SMPP SMS Send Long SMS

1.8k views Asked by At

I have a java code to submit long SMS to SMPP but while excecution I'm getting "length must be less than or equal to 254. Actual length is 270" error. When using a lengthy string or any arabic characters.

Can anyone help me to identify the cause and suggest me how to fix the problem.

Below is the code that I'm trying.

import java.io.IOException;
import java.util.Date;
import java.util.Random;

import org.jsmpp.InvalidResponseException;
import org.jsmpp.PDUException;
import org.jsmpp.bean.Alphabet;
import org.jsmpp.bean.BindType;
import org.jsmpp.bean.ESMClass;
import org.jsmpp.bean.GeneralDataCoding;
import org.jsmpp.bean.MessageClass;
import org.jsmpp.bean.NumberingPlanIndicator;
import org.jsmpp.bean.OptionalParameter;
import org.jsmpp.bean.OptionalParameters;
import org.jsmpp.bean.RegisteredDelivery;
import org.jsmpp.bean.SMSCDeliveryReceipt;
import org.jsmpp.bean.TypeOfNumber;
import org.jsmpp.extra.NegativeResponseException;
import org.jsmpp.extra.ResponseTimeoutException;
import org.jsmpp.session.BindParameter;
import org.jsmpp.session.SMPPSession;
import org.jsmpp.util.AbsoluteTimeFormatter;
import org.jsmpp.util.TimeFormatter;

public class SendLongSMSMessage
{
        private static TimeFormatter    timeFormatter   = new AbsoluteTimeFormatter();

    public String[] submitLongSMS(String MSISDN, String senderAddr, String message) throws Exception
    {
            SMPPSession session = getSession();

            String[] msgId = null;
            int splitSize = 135;
            int totalSize = 140;
            int totalSegments = 0;

            RegisteredDelivery registeredDelivery = new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT);

            GeneralDataCoding dataCoding = new GeneralDataCoding(false, false, MessageClass.CLASS1,
            Alphabet.ALPHA_8_BIT);
            ESMClass esmClass = new ESMClass();

            if (message != null && message.length() > totalSize)
            {
                    totalSegments = getTotalSegmentsForTextMessage(message);
            }

            Random random = new Random();
            OptionalParameter sarMsgRefNum = OptionalParameters.newSarMsgRefNum((short) random.nextInt());
            OptionalParameter sarTotalSegments = OptionalParameters.newSarTotalSegments(totalSegments);

            String[] segmentData = splitIntoStringArray(message, splitSize, totalSegments);

            msgId = new String[totalSegments];
            for (int i = 0, seqNum = 0; i < totalSegments; i++)
            {
                    seqNum = i + 1;
                    OptionalParameter sarSegmentSeqnum = OptionalParameters.newSarSegmentSeqnum(seqNum);
                    try
                    {       byte[] byteText = segmentData[i].getBytes("UTF-16BE");
                            msgId[i] = session.submitShortMessage("", TypeOfNumber.NATIONAL,
                            NumberingPlanIndicator.ISDN, "9999999999", TypeOfNumber.NATIONAL,
                            NumberingPlanIndicator.ISDN, MSISDN, esmClass, (byte) 0, (byte) 0, timeFormatter
                            .format(new Date()), null, registeredDelivery, (byte) 0, dataCoding, (byte) 0, byteText, sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments);

                            System.out.println("Message id  for segment " + seqNum + " out of totalsegment "
                            + totalSegments + "is" + msgId[i]);

                    }
                    catch (PDUException e)
                    {
                            System.out.println("PDUException has occured" + e.getMessage());
                    }
                    catch (ResponseTimeoutException e)
                    {
                            System.out.println("ResponseTimeoutException has occured" + e.getMessage());
                    }
                    catch (InvalidResponseException e)
                    {
                            System.out.println("InvalidResponseException has occured" + e.getMessage());
                    }
                    catch (NegativeResponseException e)
                    {
                            System.out.println("NegativeResponseException has occured" + e.getMessage());
                    }
                    catch (IOException e)
                    {
                            System.out.println("IOException has occured" + e.getMessage());
                    }
            }
             session.unbindAndClose();
            return msgId;
    }

    private SMPPSession getSession() throws Exception
    {
            return newSession();
    }

    private SMPPSession newSession() throws Exception
    {
            BindParameter bindParam = new BindParameter(BindType.BIND_TX, "<user_name>", "<pass_word>", "tdd",
            TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null);

            return new SMPPSession("17.1.1.1", 6666, bindParam);
    }

    public int getTotalSegmentsForTextMessage(String message)
    {
            int splitPos = 135;
            int totalsegments = 1;
            if (message.length() > splitPos)
            {
                    totalsegments = (message.length() / splitPos) + ((message.length() % splitPos > 0) ? 1 : 0);
            }
            return totalsegments;
    }

    public String[] splitIntoStringArray(String msg, int pos, int totalSegments)
    {
            String[] segmentData = new String[totalSegments];
            if (totalSegments > 1)
            {
                    int splitPos = pos;

                    int startIndex = 0;

                    segmentData[startIndex] = new String();
                    segmentData[startIndex] = msg.substring(startIndex, splitPos);

                    for (int i = 1; i < totalSegments; i++)
                    {
                            segmentData[i] = new String();
                            startIndex = splitPos;
                            if (msg.length() - startIndex <= pos)
                            {
                                    segmentData[i] = msg.substring(startIndex, msg.length());
                            }
                            else
                            {
                                    splitPos = startIndex + pos;
                                    segmentData[i] = msg.substring(startIndex, splitPos);
                            }
                    }
            }
            return segmentData;
    }

    public static void main(String[] args) throws Exception
    {
            SendLongSMSMessage slSMS = new SendLongSMSMessage();

            String message = "Tech Dive heralds the arrival of a community of Developers "
            + "who share, collaborate and exchange ideas, concepts, technical know-how. "
            + "This forum lets you take a deep dive in technical topics that are hot and happening as well as on legacy systems."
            + "The idea of the forum is to ensure collaboration amongst developers through exchange of ideas/concepts "
            + "so their technical skills are enhanced."
            + "We plan to bring in experienced professionals on board so content/blog written is authentic and precise."
            + "Come, join us and be a part of new way of collaboration!";

            String MSISDN = "9500000000";

            String senderAddr = "8500000000";

            slSMS.submitLongSMS(MSISDN, senderAddr, message);
    }
}
1

There are 1 answers

0
NigarMovsumova On

The best source to solve these kinds of problems is to use SMPP official documentation: https://smpp.org/SMPP_v3_4_Issue1_2.pdf

To send SubmitSm with long messages, you need to use optional_parameter called message_payload instead of common short_message parameter.

You can read this information in documentation too:

The maximum message length which can be specified in sm_length field is 254 octets. If an ESME wishes to submit a message of length greater than 254 octets, the sm_length field must be set to NULL and the message_payload optional parameter must be populated with the message length value and user data.

To solve your problem, you need to check each time you are sending a message, how many bytes are in it, and if it is more than 254, add message_payload as your optional_parameter instead of short_message.

With cloudhopper library you can do it like this :

    if (length > 254) {
        submitSm.setOptionalParameter(new Tlv(
                SmppConstants.TAG_MESSAGE_PAYLOAD,
                CharsetUtil.encode(messageBody, CharsetUtil.CHARSET_UCS_2),
                "message_payload"));
    } else {
        submitSm.setShortMessage(CharsetUtil.encode(messageBody, CharsetUtil.CHARSET_UCS_2));
    }