User’s Guide

Java SMPP API User’s Guide

Document status

This document is brief and extremely rough-and-ready. Feedback and criticism should be posted to the relevant discussion forums on Sourceforge.

The latest version of this document is always available at


This guide describes the use of the Java SMPP API (smppapi) in an application. The project resides on the web at

This guide is meant only as an introduction to the functionality provided by the API. Developer’s should refer to the API documentation for a comprehensive description of the interfaces available.


The smppapi is released under the GNU Lesser GPL (LGPL). The text of the LGPL should be in the LICENSE file in the top-level of the smppapi distribution and can also be the Open Source Initiative.

Interface version

The API supports versions 3.3 and 3.4 of the SMPP specification.


The smppapi classes are packaged in (and under) the ie.omk.smpp namespace. Top-level classes (such as Connection) are in the ie.omk.smpp package. SMPP message primitives (requests and responses) are in the ie.omk.smpp.message package. Classes which handle network connectivity (eg TcpLink) reside in the package. There are also some utility classes in ie.omk.smpp.util package.

Establishing the network link

The physical connection between an SMPP application (ESME) and the SMSC is defined by the SmscLink abstract class. Specific network implementations extend this class to allow the API to communicate with the SMSC over any Java-supported network protocol. The smppapi currently provides two concrete SmscLink implementations:

  • TcpLink. This allows an ESME to communicate with the SMSC
    over the Internet-standard TCP/IP protocol.
  • StreamLink. This class is mainly provided for debugging purposes.
    It allows the ESME to provide any Java input stream and output stream for the
    smppapi to use for i/o.

Using TcpLink

A TCP/IP link can be established to the SMSC in two ways. In the first case, the developer relies on the API to open the underlying socket to the remote system. In the second, the socket connection is already established.

Case 1:

try {
    // First get the for the SMSC:
    InetAddress smscAddr = InetAddress.getByName("");    // Use port 5432
    TcpLink smscLink = new TcpLink(smscAddr, 5432);// Open the connection (not required)..;
} catch( ux) {
    System.err.println("SMPPAPI: " + ux.getMessage());

Case 2:

try {
    // Open the socket..
    Socket s = new Socket("", 5432);    // Create the TCP link..
    TcpLink smscLink = new TcpLink(s);
} catch ( x) {
} catch ( x) {

Using StreamLink

The StreamLink class is provided mainly for debugging purposes. It’s primary purpose is to read SMPP packets from a binary file. However, it is possible to pass any Java InputStream and OutputStream to the StreamLink constructor. For instance, if a file ‘responses.bin’ exists that contains a set of response messages that a developer wishes to test against, she may do so like this:

FileInputStream fin = new FileInputStream("responses.bin");
FileOutputStream fout = new FileOutputStream("/dev/null");
StreamLink link = new StreamLink(fin, fout);
Connection tran = new Connection(link);
link.bind(Connection.TRANSMITTER, ...);
// run tests...

Obviously, the responses should match whatever requests are sent.

Connections, Transmitters, Receivers and Transceivers.

SMPP defines three modes of operation for an ESME; transmitter, receiver and transceiver. An ESME must select one of these modes of operation when it binds to the SMSC. In transmitter mode, an ESME is capable of submitting messages to the SMSC, querying the status of messages and system parameters but it is not able to receive short messages from the SMSC. To be capable of receiving delivery of short messages, an ESME must also bind as a receiver. In receiver mode, the SMSC will send deliver_sm packets to the ESME. In receiver mode, however, all the operations available in transmitter mode are disabled. A receiver and transmitter type connection require two separate network links. That is, a receiver and transmitter connection cannot share the same TCP network link.

SMPP version 3.4 introduced the transceiver type of connection. When an ESME binds to the SMSC in transceiver mode, it is similar to having a transmitter and receiver connection over the same network link. However, SMPP 3.4 also altered other aspects of the protocol, so the transceiver connection cannot be considered identical to a transmitter and receiver rolled into one.

To bind to the SMSC as a particular type, the calling application should pass the appropriate enumeration value into the
Connection.bind method. Valid enumeration values are:

  • Connection.TRANSMITTER
  • Connection.RECEIVER
  • Connection.TRANSCEIVER

Note that the Connection object must have it’s internal version set appropriately to support a transceiver connection. See the Connection.setVersion method.

Synchronous versus Asynchronous communication.

The smppapi supports both synchronous and asynchronous communication. Synchronous communication is the default. This means that when a request is sent to the SMSC, the API blocks until the response is received from the SMSC. In asynchronous communication, the API returns immediately after sending a request and notifies your application once the response is received from the SMSC. More than one observer can be notified of an incoming SMPP packet from the SMSC.

As synchronous communication is the default, no special action needs to be taken when using the Connection class. Its use is simply:

try {
    Connection trans = new Connection(smscLink);
    SMPPResponse resp = trans.sendRequest(req);
    if (resp.getCommandStatus() != 0) {
} catch (SMPPException x) {

To create a Connection that uses asynchronous communication, an implementation of the ie.omk.smpp.event.ConnectionObserver interface is needed. The connection observer will receive updates from the API for various internal API events, including packet reception.

public class MyListener implements ie.omk.smpp.event.ConnectionObserver {
    public void packetReceived(Connection source, SMPPPacket packet) {
        // Process received packet
// Method called for API events other than packet reception.
public void update(Connection source, SMPPEvent event) {
        // process event..

This observer object must now be registered with the Connection object so that it can receive updates.

// Create a listener object
MyListener myListener = new MyListener();
// Create an asynchronous transmitter..
Connection trans = new Connection(smscLink, true);
// Register the listener..

Synchronous communication as a receiver

While it is possible to use synchronous communication with a receiver connection, it is generally more useful to use asynchronous communication when binding as a receiver. This is because the only thing a receiver application does once it binds is wait for the SMSC to deliver messages to it. Therefore, it makes sense for a receiver application to bind and then let the smppapi wait for incoming messages. Once received, the application will be passed an SMPPEvent as described above.

To use synchronous communication while bound as a receiver, have a look at the Connection.readNextPacket method.

Binding to the SMSC

To bind to the SMSC, call the Connection.bind method with appropriate arguments. For example:

Binding to the SMSC as a transmitter:

Connection c = new Connection(smscLink);
 * Bind to the SMSC...use the default routing information
 * configured at the SMSC..
BindResp r = c.bind(Connection.TRANSMITTER, "sysID", "secret", "sysType", null);
if (r.getCommandStatus() != 0) {

Handling an SMPPEvent

As already discussed, when using asynchronous communication, the smppapi will notify an observer of an incoming SMPP packet from the SMSC with a call to it’s packetReceived method. It is very important to keep thread-safety in mind when writing your event handler methods as the smppapi makes no guarantees that it will dispatch only one event at a time. An example SMPP event handler follows:

public class MyListener implements ie.omk.smpp.event.ConnectionObserver {
    public void packetReceived(Connection source, SMPPPacket pak) {
        try {
            switch (pak.getCommandID()) {
            case SMPPPacket.ESME_BNDTRN_RESP:
                if (pak.getCommandStatus() == 0) {
                    // successfully bound...
                } else {
                    // handle error...
                case SMPPPacket.ESME_SUB_SM_RESP:
                case SMPPPacket.GENERIC_NAK:
        } catch (SMPPException x) {
            // handle exception...
    public void update(Connection source, SMPPEvent event) {
        // called for control events..
        switch (event.getType()) {
            // an exception occurred in the receiver thread..
        case SMPPEvent.RECEIVER_EXIT:
            // the receiver thread has just died.
        // see the event framework for further events.

Automatic responses.

In certain cases the SMSC may send request packets to an ESME. The only two cases in SMPP version 3.3 are when the SMSC is delivering short messages to an ESME (only relevant to a receiver) and when the SMSC sends an EnquireLink request (both receiver and transmitter). The Connection can be set up to automatically respond to these messages. Thus, so long as the ESME is ‘alive’, if the SMSC sends an EnquireLink request, the smppapi will respond immediately with EnquireLinkResp. The request packet will still be passed to the application by the smppapi in the normal manner.

By default, automatically acknowledging links is enabled while automatically acknowledging messages is disabled. To change these settings, use the Connection.autoAckLink and Connection.autoAckMessages methods.

Appendix A: Glossary.

SMPP Short Message Peer to Peer
SMSC or SC Short Message Service Centre
ESME or SME (External) Short Message Entity

Comments are closed.