Core Java

SMPP Java Example(Client)

This post provides SMPP java example by creating a simple SMPP client that sends short messages to mobile subscriber.Using this client either we can make simple submit to send message to a single mobile subscriber or can broadcast a message to multiple mobile subscribers in one shot.Also, we will verify the delivery receipt. For the client purpose we will be using existing java SMPP client library – jSMPP

What is SMPP

SMPP stands for Short Message Peer-to-Peer. It is an open industry standard protocol designed to provide a flexible data communication interface for the transfer of short message data.Most of the time SMPP is used to carry short messages in bulk.You can broadcast message to thousand subscribers in one shot.SMPP is not only limited to short messages, we can also it to carry voicemail notifications, Cell broadcast,WAP messages including WAP Push messages

SMPP Operation

SMPP uses the client-server model of operation.Before submitting any messages to SMPP, we send a bind command. In this example we will be sending bind_transmitter as we are only interested in submitting messages to the server. Apart from bind_transmitter other bind commands are bind_receiver means that the client will only receive the messages, and bind_transceiver allows message transfer in both directions.

The complete detail of SMPP operation is out of scope of this article. If you want to know the operation in detail visit – SMPP wiki

Using jSMPP

To get started with the SMPP client we will be using jSMPP. To include the jSMPP in your project add following maven dependency to your pom.xml

pom.xml

<dependency>
	<groupId>org.jsmpp</groupId>
	<artifactId>jsmpp</artifactId>
	<version>2.3.5</version>
</dependency>

SMPP Multiple Submit Example

As we discussed SMPP can be used to send messages to single or multiple subscribers.Following is an example to send messages to multiple mobile subscribers.The first step is to send a bind command to server using the host name, username and password. This operation we are doing in initSession(). Once this is done SMPP session will be created and then we can use this session to send messages.

The different parameters such as ip, host, username, password will be provided by the corresponding providers.

MultipleSubmitExample.java

public class MultipleSubmitExample {

    private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubmitExample.class);

    private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();

    private final String smppIp = "127.0.0.1";

    private int port = 8086;

    private final String username = "localhost";

    private final String password = "password";

    private final String address = "AX-DEV";

    private static final String SERVICE_TYPE = "CMT";

    public void broadcastMessage(String message, List numbers) {
        LOGGER.info("Broadcasting sms");
        SubmitMultiResult result = null;
        Address[] addresses = prepareAddress(numbers);
        SMPPSession session = initSession();
        if(session != null) {
            try {
                result = session.submitMultiple(SERVICE_TYPE, TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, address,
                        addresses, new ESMClass(), (byte) 0, (byte) 1, TIME_FORMATTER.format(new Date()), null,
                        new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), ReplaceIfPresentFlag.REPLACE,
                        new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte) 0,
                        message.getBytes());

                LOGGER.info("Messages submitted, result is {}", result);
                Thread.sleep(1000);
            } catch (PDUException e) {
                LOGGER.error("Invalid PDU parameter", e);
            } catch (ResponseTimeoutException e) {
                LOGGER.error("Response timeout", e);
            } catch (InvalidResponseException e) {
                LOGGER.error("Receive invalid response", e);
            } catch (NegativeResponseException e) {
                LOGGER.error("Receive negative response", e);
            } catch (IOException e) {
                LOGGER.error("I/O error occured", e);
            } catch (Exception e) {
                LOGGER.error("Exception occured submitting SMPP request", e);
            }
        }else {
            LOGGER.error("Session creation failed with SMPP broker.");
        }
        if(result != null && result.getUnsuccessDeliveries() != null && result.getUnsuccessDeliveries().length > 0) {
            LOGGER.error(DeliveryReceiptState.getDescription(result.getUnsuccessDeliveries()[0].getErrorStatusCode()).description() + " - " +result.getMessageId());
        }else {
            LOGGER.info("Pushed message to broker successfully");
        }
        if(session != null) {
            session.unbindAndClose();
        }
    }

    private Address[] prepareAddress(List numbers) {
        Address[] addresses = new Address[numbers.size()];
        for(int i = 0; i< numbers.size(); i++){
            addresses[i] = new Address(TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, numbers.get(i));
        }
        return addresses;
    }

    private SMPPSession initSession() {
        SMPPSession session = new SMPPSession();
        try {
            session.setMessageReceiverListener(new MessageReceiverListenerImpl());
            String systemId = session.connectAndBind(smppIp, Integer.valueOf(port), new BindParameter(BindType.BIND_TX, username, password, "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null));
            LOGGER.info("Connected with SMPP with system id {}", systemId);
        } catch (IOException e) {
            LOGGER.error("I/O error occured", e);
            session = null;
        }
        return session;
    }

    public static void main(String[] args) {
        MultipleSubmitExample multiSubmit = new MultipleSubmitExample();
        multiSubmit.broadcastMessage("Test message from devglan", Arrays.asList("9513059515", "8884377251"));
    }
}

While creating SMPP session we have registered message receiver listener which will be used to get the delivery receipt of the message. Following is the example.

MessageReceiverListenerImpl.java

public class MessageReceiverListenerImpl implements MessageReceiverListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(MessageReceiverListenerImpl.class);
    private static final String DATASM_NOT_IMPLEMENTED = "data_sm not implemented";

    public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException {
        
        if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass())) {

            try {
                DeliveryReceipt delReceipt = deliverSm.getShortMessageAsDeliveryReceipt();

                long id = Long.parseLong(delReceipt.getId()) & 0xffffffff;
                String messageId = Long.toString(id, 16).toUpperCase();

                LOGGER.info("Receiving delivery receipt for message '{}' from {} to {}: {}",
                    messageId, deliverSm.getSourceAddr(), deliverSm.getDestAddress(), delReceipt);
            } catch (InvalidDeliveryReceiptException e) {
                LOGGER.error("Failed getting delivery receipt", e);
            }
        }
    }
    
    public void onAcceptAlertNotification(AlertNotification alertNotification) {
        LOGGER.info("AlertNotification not implemented");
    }
    
    public DataSmResult onAcceptDataSm(DataSm dataSm, Session source)
            throws ProcessRequestException {
        LOGGER.info("DataSm not implemented");
        throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID);
    }
}

SMPP Delivery Receipt

There are many standard delivery receipt error codes provided by SMPP to identify the delivery receipt. We have implemented few to identify the actual receipt information.For complete exhaustive list follow – smpperrorcodes

DeliveryReceiptState.java

package com.devglan.smpp;

public enum DeliveryReceiptState {

    ESME_ROK(0, "Ok - Message Acceptable"),

    ESME_RINVMSGLEN(1, "Invalid Message Length"),

    ESME_RINVCMDLEN(2, "Invalid Command Length"),

    ESME_RINVCMDID(3, "Invalid Command ID"),

    ESME_RINVBNDSTS(4, "Invalid bind status"),

    ESME_RALYBND(5,	"Bind attempted when already bound"),

    ESME_RINVPRTFLG(6, "Invalid priority flag"),

    ESME_RINVREGDLVFLG(7, "Invalid registered-delivery flag"),

    ESME_RSYSERR(8,	"SMSC system error"),

    ESME_RINVSRCADR(9, "Invalid source address"),

    ESME_RINVDSTADR(11, "Invalid destination address"),

    ESME_RINVMSGID(12, "Invalid message-id"),

    NOT_FOUND(000, "Couldn't resolve.Ask admin to add.");

  private int value;
  private String description;

  DeliveryReceiptState(int value, String description) {
    this.value = value;
    this.description = description;
  }

  public static DeliveryReceiptState getDescription(int value) {
    for (DeliveryReceiptState item : values()) {
      if (item.value() == value) {
        return item;
      }
    }
    return NOT_FOUND;
  }

    public int value() {
        return value;
    }

    public String description() {
        return description;
    }

}

SMPP Single Submit Example

jSMPP provides submitShortMessage() for single submit.Following is the implemnetation. The complete implementation is provided in the source.

String messageId = session.submitShortMessage(SERVICE_TYPE,
                        TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, address,
                        TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, number,
                        new ESMClass(), (byte)0, (byte)1,  TIME_FORMATTER.format(new Date()), null,
                        new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), (byte)0, new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0,
                        message.getBytes());

Conclusion

This is a simple example of SMPP client implementation in java. In next post we will be discussing about its simulator.

Published on Java Code Geeks with permission by Dhiraj Ray, partner at our JCG program. See the original article here: SMPP Java Example(Client)

Opinions expressed by Java Code Geeks contributors are their own.

Dhiraj Ray

He is a technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. He is an avid reader and a technology enthusiast who likes to be up to date with all the latest advancements happening in the techno world. He also runs his own blog @ devglan.com
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
5 years ago

Hi! Tx, but i have an error:

SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread “pool-1-thread-2” java.lang.IllegalArgumentException: No enum const NumberingPlanIndicator with value 2
at org.jsmpp.bean.NumberingPlanIndicator.valueOf(NumberingPlanIndicator.java:69)
at org.jsmpp.bean.Address.(Address.java:36)
at org.jsmpp.bean.UnsuccessDelivery.(UnsuccessDelivery.java:28)
at org.jsmpp.util.DefaultDecomposer.submitMultiResp(DefaultDecomposer.java:558)
at org.jsmpp.session.state.SMPPSessionBoundTX.processSubmitMultiResp(SMPPSessionBoundTX.java:77)
at org.jsmpp.session.PDUProcessTask.run(PDUProcessTask.java:83)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

Process finished with exit code 0

Back to top button