Menu

Sending Long SMS using UDH

the coder
2011-07-10
2019-08-23
  • the coder

    the coder - 2011-07-10

    Hi Oran, Thanks for the great work you have done regarding smppapi. I have
    used it in production env for 6 yrs now and it has never disappointed me.

    I am using smppapi-0.3.9 and have noticed that using UDH each SMS segment
    contains 140 characters. Can I extend this such that each SMS segment contains
    160 characters? How can I extend it to contain more characters?

    Thanks.

    the coder

     
  • Oran Kelly

    Oran Kelly - 2011-07-10

    The direct answer is: you can't.

    A short message contains 140 bytes, that's non-negotiable. The reason you can
    send 160 characters is because of the character encoding being used, which is
    7-bit. The 7-bit characters are bit-packed into the bytes. So there's 140
    extra "bits" that can be used in each SMS, which equates to another 20 7-bit
    characters.

    You could, therefore, use the same bit-packing approach to pack characters in
    to your own SMSs (the DefaultAlphabetEncoding class in smppapi has an
    implementation of this). Of course, the receivers of the messages will have to
    support it.

    However, once you're using the UDH, you're using up some of those bytes so
    you're never going to get the full 160 characters in anyway.

     
  • the coder

    the coder - 2011-07-11

    Hi Oran,

    Thanks for the quick response.

    I am using DefaultAlphabetEncoding but the best I can get is 134 characters.
    UDH Header takes 6 characters so the best I can get is 134 characters. Since a
    normal SMS gives me 160 characters, how can I structure my long SMS to give me
    154 characters (6 to be taken by UDH header) per segment?

    Below is my code:

    String msg = .....//Long msg content

    byte messageData = new longstuff.DefaultAlphabetEncoding().encode(msg);

    UserData userData = new UserDataImpl();

    userData.setData(messageData);

    ie.omk.smpp.message.SubmitSM submits =
    UserDataUtil.createSubmits(userData.toSegments(), source_addr, destination);

    Thanks.

    the coder.

     
  • Oran Kelly

    Oran Kelly - 2011-07-11

    You'd need to do something like

    String message = "A text message";
    DefaultAlphabetEncoding enc = new DefaultAlphabetEncoding();
    byte[] messageData = enc.pack(enc.encode(message));
    UserData userData = new UserDataImpl();
    userData.setData(messageData);
    submits = UserDataUtil.createSubmits(userData.toSegments(), source_addr, destination);
    

    The key to the above code is the call to enc.pack. I will say though that
    your mileage may vary widely trying to send packed GSM alphabet characters.

     
    • Myint TZ

      Myint TZ - 2019-08-22

      Hello Oran,

      Firstly, thank you so much for your reply.

      I use the above code to send long sms.
      But there is empty result in "submits" and I cannot received any sms.
      Please help me .

      My code is like that...
      String msg= ".....Long one";
      DefaultAlphabetEncoding enc = new DefaultAlphabetEncoding();
      byte[] messageData = enc.pack(enc.encodeString(msg));
      UserData userData = new UserDataImpl();
      userData.setData(messageData);
      SubmitSM[] submits = UserDataUtil.createSubmits(userData.toSegments(), source, destination);

       
      • Myint TZ

        Myint TZ - 2019-08-22

        Hello Oran,

        Now I can send long SMS.
        Thank you so much for your api and discussion sessions.

         
  • the coder

    the coder - 2011-07-14

    I have done that but I get an SMS with funny characters. The 1st message part
    is:

    é@¥?$£F??ù???2?øFk??n2;år??e??MG??ovz?.?A???ør?A??ÖÜv??r?=???A??äÖù???<?æ???dP
    ?Mù???<?Ü??A???Å??¡????v?Ao?ΘΛv?A??öÅ???n?,§Å??.?<=É???0òΞv??f

    2nd pard message is: é@¥?$$yzÆù1??2

    without the enc.pack() method call I get the right message content but each
    segment takes 134 characters(140 inc of UDH).

    All in all what am trying to achieve is to structure my long SMS to give me
    154 characters (6 to be taken by UDH header) per segment instead of 140
    characters?

    Please help.

    the coder.

     
  • Oran Kelly

    Oran Kelly - 2011-07-14

    Yep, as I said, your mileage may vary! I'm not sure how else to help you. If
    the receiver doesn't support messages bit-packed according to the GSM alphabet
    then there's not much you can do.

    The only place you can go now is the GSM specifications themselves now, see if
    there's any information in there that will help.

     
  • Anonymous

    Anonymous - 2011-07-14

    Two ideas:

    1. You need to let the receiver know that you are sending with the 7 bit encoding. This can be done by calling SubmitSM.setMessageEncoding(MessageEncoding).
    2. I have the impression you are sending concatinated SMS. If that is the case, you are probably building the UDH header yourself, and the problem can be in the header. If the receiver does not know that these packets form one big message, it can't possibly unpack the data (since with the 7 bit encoding some characters are split between the two packets). Are you correctly setting the SAR optional parameters?
     
  • the coder

    the coder - 2011-07-15

    Hi,

    I have set the encoding as specified above and still not working. Failure of
    this working will mean that sending long SMS is limited to 140 characters(6
    for udh header and 134 for my text) per segment(part) when using UDHI. Is this
    the smpp standard or am I missing something?

    Please look at my code and tell me if av left something out.

     public static ie.omk.smpp.message.SubmitSM[] createSubmits(
                byte[][] segments,
                ie.omk.smpp.Address from,
                ie.omk.smpp.Address to) {
            List<ie.omk.smpp.message.SubmitSM> packets = new ArrayList<ie.omk.smpp.message.SubmitSM>();
            for (byte[] segment : segments) {
                ie.omk.smpp.message.SubmitSM p = new ie.omk.smpp.message.SubmitSM();
                p.setSource(from);
                p.setDestination(to);
                p.setEsmClass(0x43);
                ie.omk.smpp.util.DefaultAlphabetEncoding enc = new ie.omk.smpp.util.DefaultAlphabetEncoding();
                p.setMessageEncoding(enc);
                p.setMessage(segment);
                p.setDataCoding(0);
                packets.add(p);
            }
            return packets.toArray(new ie.omk.smpp.message.SubmitSM[packets.size()]);
        }
    [code]
    
    Thanks all.
    
     
  • Anonymous

    Anonymous - 2011-07-15

    I can tell you from experience that you can send long SMS messages with more
    than 134 characters using the 7 bit encoding, and every device we've tested
    with works (though there can be some quirks).

    However, I did it not by sending UDH headers, but by adding the SAR optional
    parameters, which the SMSC needs to support.

    I don't know what the UDH header need to look like for long messages, but I am
    guessing you are not creating it correctly. The receiver needs to know for
    each packet that this is packet I of N, and I don't see that data anywhere in
    your code.

    From reading http://en.wikipedia.org/wiki/Concatenated_SMS it seems that indeed this data needs to be
    present in the UDH, and the UDH length needs to be a multiple of 7 bits. Are
    you doing these things?

     
  • the coder

    the coder - 2011-07-15

    Hi,

    Thanks for the quick reply. Please provide me the code for sending using SAR.
    Hope that its able to send long SMS and have it get concatenated on the phone
    and appear as 1 long SMS. Below is my code for sending with UDH. Correct me if
    my code is wrong.

    ie.omk.smpp.util.DefaultAlphabetEncoding enc = new ie.omk.smpp.util.DefaultAlphabetEncoding();
    byte[] messageData = enc.pack(enc.encodeString(msg));
    UserData userData = new UserDataImpl();
    userData.setData(messageData);
    ie.omk.smpp.message.SubmitSM[] submits = UserDataUtil.createSubmits(userData.toSegments(), source_addr, destination);
    

    From this code, UserData class sets the packet 1 of N within the UDH. I
    actually receive the SMS concatenated on my phone. The question therefore is
    not specifying the packet 1 of N but why I am able to send 134 char text
    instead of at least 154 characters using UDH. If anyone is able to send long
    SMS with each segment allowing 154 characters text using UDH, please share
    code. Otherwise am inclined to conclude that its not possible to send more
    than 134 char text per segment using UDH.

    Thanks.

    the coder.

     
  • the coder

    the coder - 2011-07-15

    Hi,

    Thanks for the quick reply. Please provide me the code for sending using SAR.

    Hope that its able to send long SMS and have it get concatenated on the phone

    and appear as 1 long SMS. Below is my code for sending with UDH. Correct me

    if my code is wrong.

    public static ie.omk.smpp.message.SubmitSM[] createSubmits(
                byte[][] segments,
                ie.omk.smpp.Address from,
                ie.omk.smpp.Address to) {
            List<ie.omk.smpp.message.SubmitSM> packets = new ArrayList<ie.omk.smpp.message.SubmitSM>();
            for (byte[] segment : segments) {
                ie.omk.smpp.message.SubmitSM p = new ie.omk.smpp.message.SubmitSM();
                p.setSource(from);
                p.setDestination(to);
                p.setEsmClass(0x43);
                ie.omk.smpp.util.DefaultAlphabetEncoding enc = new ie.omk.smpp.util.DefaultAlphabetEncoding();
                p.setMessageEncoding(enc);
                p.setMessage(segment);
                p.setDataCoding(0);
                packets.add(p);
            }
            return packets.toArray(new ie.omk.smpp.message.SubmitSM[packets.size()]);
        }
    
    ie.omk.smpp.util.DefaultAlphabetEncoding enc = new
    ie.omk.smpp.util.DefaultAlphabetEncoding();
    byte[] messageData = enc.pack(enc.encodeString(msg));
    UserData userData = new UserDataImpl();
    userData.setData(messageData);
    ie.omk.smpp.message.SubmitSM[] submits =
    UserDataUtil.createSubmits(userData.toSegments(), source_addr, destination);
    

    From this code, UserData class sets the packet 1 of N within the UDH. I
    actually

    receive the SMS concatenated on my phone. The question therefore is not
    specifying

    the packet 1 of N but why I am able to send 134 char text instead of at least

    154 characters using UDH. If anyone is able to send long SMS with each segment

    allowing 154 characters text using UDH, please share code. Otherwise am
    inclined

    to conclude that its not possible to send more than 134 char text per segment

    using UDH.

    Thanks.

    the coder.

     
  • Anonymous

    Anonymous - 2011-07-15

    What is this userData class? I don't know it, and I don't see it in the
    JavaDoc for the library. Since it has no way of knowing that the message is 7
    bit encoded, there is no way that it will create the correct UDH. I suspect
    this is the source of your problem.

    .

    In order to use the SAR optional parameters, your SMSC must support SMPP 3.4,
    and specifically these parameters (that's why they are called optional). If
    that is the case, immidiatly after creating the transciver, call:

    transceiver.setVersion(SMPPVersion.V34);
    

    Create a member variable nextRefNum that will be used to generate unique IDs
    for messages:

    private int nextRefNum = 0;
    
    private synchronized int getNextRefNum () {
        if (nextRefNum>=65535) { //2 byte positive integer
            nextRefNum = 0;
        }
        return ++nextRefNum;
    }
    

    Then use the following code to send a messae:

    byte[] binaryContent = alphabet.encodeString(content);
    int parts = (binaryContent.length<maxShortMessageLength ? 1 : (int)Math.ceil(((double)binaryContent.length) / maxSegmentLength));
    Integer msgRefNum = new Integer(getNextRefNum()); 
    SMPPRequest sm;
    if (parts == 1)  {
        sm = createPacket(smsNumber);
        if (sm==null) {
            return false;
        }
        sm.setMessage(binaryContent, alphabet);
        sendRequest(sm);
    } else {
        byte[] packet = new byte[maxSegmentLength];
        for (int i=0 ; i<parts ; i++) {
            sm = (SubmitSM)transceiver.newInstance(SMPPPacket.SUBMIT_SM);
            sm.setDestination(new Address(0, 0, number));
            sm.setSource(sourceAddress);
            sm.setOptionalParameter(Tag.SAR_TOTAL_SEGMENTS, new Integer(parts)); 
            sm.setOptionalParameter(Tag.SAR_MSG_REF_NUM, msgRefNum);            
            sm.setOptionalParameter(Tag.SAR_SEGMENT_SEQNUM, new Integer(i+1)); 
            if (i==parts-1) {
                int pos = i*maxSegmentLength;
                int len = binaryContent.length - pos;
                byte[] finalPacket = new byte[len];
                System.arraycopy(binaryContent, pos, finalPacket, 0, len);
                sm.setMessage(finalPacket, alphabet);
            } else {
                System.arraycopy(binaryContent, i*maxSegmentLength, packet, 0, maxSegmentLength);
                sm.setMessage(packet, alphabet);
            }
            transceiver.sendRequest(sm);
        }
    }
    

    maxSegmentLength and max_short_message_length depend on your SMSC, but you
    should probably set both to 134.

    BTW, the maximum length when using UDH is 153, not 154, since the UDH header
    takes 6 bytes which is more than 6 characters.

     
  • Oran Kelly

    Oran Kelly - 2011-07-15

    The UserDataImpl class is an experimental API that is on the trunk of smppapi

    • some people have back-ported it to the 0.3 stream to use it.

    The UserDataImpl contains an implementation of concatenated short messages
    using UDH.

    A bit of background: although SMPP grew out of GSM, it's important to note
    that SMPP is not GSM SMS. SMPP grew beyond those bounds in order to be an
    API independent of the kind of network messages were being delivered on (for
    example, a CDMA based one). This is often a source of confusion.

    The SAR TLVs were introduced as an abstraction for long SMS. They removed the
    burden of specific network encoding from client SMPP apps, allowing the SMSC
    that was routing the SMS segments to re-encode them depending on the transport
    network of the SME.

    The problem that this all then leads to is that many people don't realise that
    SMSCs read, interpret and re-encode messages you submit via SMPP. And how it
    does that is not particularly standard across SMSCs.

    So yes, if you have the option of using TLV (optional parameter) support in
    your application (your SMSC must support at least SMPP v3.4) then this is by
    far the best option. Only use UDH (via UserData or otherwise) if you're stuck
    with no TLV support.

     
  • Anonymous

    Anonymous - 2011-07-15

    Looking at the trunk, if you MUST use UDH, and you want use UserDataImpl, then
    before calling userData.setData(messageData), you need to right-shift the
    whole byte array by one bit, and the new leftmost bit must be 0. Note that you
    may need to increase the size of the array by one byte if there is overflow,
    and that in this case the new byte must be either 0 or 128. This is obviously
    a hack, but it seems like it should work.

    (This assumes you are using the default constructor and therefore
    useConcat16=false. If it is true, the number of bits changes...)

     
  • Ravi Kumar

    Ravi Kumar - 2019-08-23

    Hi Oran Kelly,
    Thanks for developed this smpp server api,
    I need you help,
    should i use this smpp server in openSmpp libarary?
    or if i will use , How i have to implement this code to smpp liberary.

    Thanks & Regards,'
    Ravi Kumar

     

Log in to post a comment.

MongoDB Logo MongoDB