The SMPP (Short Message Peer to Peer) protocol has been around for a very long time. It is the core protocol used to build a ESME (External Short Messaging Entity) that can connect to a SMSC (Short Message Service Center). Now that we have all of our acronyms out of the way.
This client has been tested thoroughly and we used it in several production products we have. Over the years we have run into different SMSC's, each implementing the SMPP 3.4 protocol a bit differently. We have been able to use this client to handle all those scenarios.
On top of the core SMPP protocol we have built a class called ESMEManager. This class provides management support for multiple connections. It exposes events that you can bind your application code into.
Here is a piece of the sample console application to show you how easy it is to use:
// IP Address or Name of the server
string server = "gateway.domain.com";
// Port
short port = 9900;
// The short or long code for this bind
string shortLongCode = "55555";
// The system id for authentication
string systemId = "systemid";
// The password of authentication
string password = "password";
// The encoding to use if Default is returned in any PDU or encoding request
DataCodings dataCoding = DataCodings.ASCII;
// Create a esme manager to communicate with an ESME
connectionManager = new ESMEManager("Test",
shortLongCode,
new ESMEManager.CONNECTION_EVENT_HANDLER(ConnectionEventHandler),
new ESMEManager.RECEIVED_MESSAGE_HANDLER(ReceivedMessageHandler),
new ESMEManager.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackHandler),
new ESMEManager.SUBMIT_MESSAGE_HANDLER(SubmitMessageHandler),
new ESMEManager.QUERY_MESSAGE_HANDLER(QueryMessageHandler),
new ESMEManager.LOG_EVENT_HANDLER(LogEventHandler),
new ESMEManager.PDU_DETAILS_EVENT_HANDLER(PduDetailsHandler));
// Bind one single Receiver connection
connectionManager.AddConnections(1, ConnectionModes.Receiver, server, port, systemId, password, "Receiver", dataCoding);
// Bind one Transmitter connection
connectionManager.AddConnections(1, ConnectionModes.Transmitter, server, port, systemId, password, "Transceiver", dataCoding);
string server = "gateway.domain.com";
// Port
short port = 9900;
// The short or long code for this bind
string shortLongCode = "55555";
// The system id for authentication
string systemId = "systemid";
// The password of authentication
string password = "password";
// The encoding to use if Default is returned in any PDU or encoding request
DataCodings dataCoding = DataCodings.ASCII;
// Create a esme manager to communicate with an ESME
connectionManager = new ESMEManager("Test",
shortLongCode,
new ESMEManager.CONNECTION_EVENT_HANDLER(ConnectionEventHandler),
new ESMEManager.RECEIVED_MESSAGE_HANDLER(ReceivedMessageHandler),
new ESMEManager.RECEIVED_GENERICNACK_HANDLER(ReceivedGenericNackHandler),
new ESMEManager.SUBMIT_MESSAGE_HANDLER(SubmitMessageHandler),
new ESMEManager.QUERY_MESSAGE_HANDLER(QueryMessageHandler),
new ESMEManager.LOG_EVENT_HANDLER(LogEventHandler),
new ESMEManager.PDU_DETAILS_EVENT_HANDLER(PduDetailsHandler));
// Bind one single Receiver connection
connectionManager.AddConnections(1, ConnectionModes.Receiver, server, port, systemId, password, "Receiver", dataCoding);
// Bind one Transmitter connection
connectionManager.AddConnections(1, ConnectionModes.Transmitter, server, port, systemId, password, "Transceiver", dataCoding);
Once the AddConnection call is made the client starts the bind process and messages can be sent and received.
The most complicated piece of the protocol is handling the encoding of the strings. The protocol has this concept of a "Default" encoding. This is usually ASCII or Latin1. You can tell the owner of the SMSC which protocol you want to use for Default. If the protocol used matches the Default that is what you will be told. It is really important when responding to a Receive PDU to use the same encoding on the Submit PDU.
At the connect level you can specify what the "Default" encoding is but this can be overridden in the SendMessage call.
// This is set in the Submit PDU to the SMSC
// If you are responding to a received message, make this the same as the received message
DataCodings submitDataCoding = DataCodings.Default;
// Use this to encode the message
// We need to know the actual encoding.
DataCodings encodeDataCoding = DataCodings.ASCII;
// There is a default encoding set for each connection. This is used if the encodeDataCoding is Default
SubmitSm submitSm = null;
SubmitSmResp submitSmResp = null;
connectionManager.SendMessage(phoneNumber, null, Ton.National, Npi.ISDN, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp);
// If you are responding to a received message, make this the same as the received message
DataCodings submitDataCoding = DataCodings.Default;
// Use this to encode the message
// We need to know the actual encoding.
DataCodings encodeDataCoding = DataCodings.ASCII;
// There is a default encoding set for each connection. This is used if the encodeDataCoding is Default
SubmitSm submitSm = null;
SubmitSmResp submitSmResp = null;
connectionManager.SendMessage(phoneNumber, null, Ton.National, Npi.ISDN, submitDataCoding, encodeDataCoding, message, out submitSm, out submitSmResp);
In the SendMessage call there are two encoding parameters. The submitDataCoding parameter specifies the data coding value to be used in the actual PDU. The encodeDataCoding parameter specifies which protocol to use to encode the message string.
As an example, you most likely will want to set "Default" in the PDU and use "ASCII" to perform the actual encoding.
Evey SMSC handles encoding differently so this gives you the flexibility you need to get out of any situation.
The projects are in Visual Studio 2012 using the 4.5 framework. The code will compile in VS 2010 and earlier version of the framework. Download the code, build the SMPP client and try running the console application.
Here are some of the Key Features:
1. Fully tested production code. Can handle millions of transactions a day.
2. ESMEManager support mutiple binds of different types. Will round-robin on Transmitter and Transceiver bind.
3. Will log the Full PDU to stdout.
4. Support for SQL Server to store PDU's.
5. Reconnection support when connection drop. Implements the Enquire link rules.
6. Supports Encoding for ASCII, Latin1 and UTF-16. Handles Default data coding rules.
7. Event driven API so all the details are taken care of.
8. Working console based test application.
Extended Support
We have frameworks for using the SMPP client in a windows service. We also have bare bones services for an ESME and SMSC implementation.
Contact Ardan Studios at bill@ardanstudios.com for more information.