nguyenbahuong / smslib

Automatically exported from code.google.com/p/smslib
0 stars 0 forks source link

messages longer than 254 characters are not delivered using SMPP #448

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
SUBMIT_SM PDU has a limit of 254 characters for it's body. However, it's 
possible to send a message longer than 254 characters by splitting up the 
message and using the message_payload optional parameter. It is the 
responsibility of the client to do that. SMSlib does not seem to be doing that, 
instead it is trying to create a PDU with body longer than 254 characters which 
causes JSMPP to raise the following exception.

org.jsmpp.PDUStringException: Octet String value 'a really long message longer 
than 254 characters yadda yadda yaddya filler stuff blah blah foo bar goo fuu.. 
SMPP is stand for Short Message Peer to Peer. It is a standard protocol for 
exchanging SMS messages between SMS entities over TCP/IP or X.25 connections.' 
cannot more than 254. Actual length of string is 262
    at org.jsmpp.util.StringValidator.validateString(StringValidator.java:73)
    at org.jsmpp.util.DefaultComposer.submitSm(DefaultComposer.java:215)
    at org.jsmpp.DefaultPDUSender.sendSubmitSm(DefaultPDUSender.java:196)
    at org.jsmpp.SynchronizedPDUSender.sendSubmitSm(SynchronizedPDUSender.java:192)
    at org.jsmpp.session.SubmitSmCommandTask.executeTask(SubmitSmCommandTask.java:86)
    at org.jsmpp.session.AbstractSession.executeSendCommand(AbstractSession.java:248)
    at org.jsmpp.session.SMPPSession.submitShortMessage(SMPPSession.java:320)
    at org.smslib.smpp.jsmpp.JSMPPGateway.sendMessage(JSMPPGateway.java:298)
    at org.smslib.AGateway$QueueManager.process(AGateway.java:503)
    at org.smslib.threading.AServiceThread.run(AServiceThread.java:105)

Original issue reported on code.google.com by manohar....@gmail.com on 2 Jan 2012 at 10:38

GoogleCodeExporter commented 9 years ago
This is not a defect since 254 octets limit is specified in SMPP specification.

There are three possible methods for handling long messages (longer than 254 
octets) in SMPP, using message_payload optional parameter, using sar_xxx 
optional parameters, and using UDH. It really depends on what the SMSC 
supports. As long as I know, the most supported and widely used method is using 
UDH.

Check what method is supported by your SMSC provider.

-Bassam

Original comment by balsar...@gmail.com on 2 Jan 2012 at 10:06

GoogleCodeExporter commented 9 years ago
Can I currently use any of the above methods through smslib? 

And I presume smslib is a high level library. In which case this should be 
transparent to the client. The client simply calls sendMessage() and perhaps 
optionally specifies the mechanism and smslib does all the work of ensuring the 
message is delivered. The client shouldn't have to deal with the protocol 
details.

Original comment by manohar....@gmail.com on 3 Jan 2012 at 6:59

GoogleCodeExporter commented 9 years ago

As I said, it depends on what the SMSC you are connected to supports. Almost 
all SMSCes support UDH method. None of the methods can currently be used 
directly from SMSLib without modifying the code.

SMSLib supports different Gateways such as Modems, HTTP Gateways, and SMPP 
(added recently). Each Gateway handles sendMessage() method differently. SMPP 
support was added by integrating with JSMPP library. JSMPP does not provide a 
way to automatically detect long messages and do appropriate handling. Maybe 
you should address this issue to JSMPP team.

If you would like to add such feature to SMSLib, you can start by editing 
JSMPPGateway class. Maybe you can add an Enum or a property which a user can 
set and specifies how to handle long messages. Here is how each method works 
and how can it be used with JSMPP  

SMPP Specification
http://www.smsforum.net/SMPP_v3_4_Issue1_2.zip

1- Using UDH

Usually long messages are split into parts each part 153 bytes long for 7-bit 
character based encodings (such as GSM) and 134 bytes for encodings such as 
UTF-16BE. UDH information is added at the beginning of each part, described here
http://en.wikipedia.org/wiki/Concatenated_SMS

Each part is sent separately and UDHI of esm_class parameter should be set on 
each part.

Example of using UDH with JSMPP

// Assuming message is 300 chars long
String myLongMessage = "a very long message...";

byte[] msgBytes = myLongMessage.getBytes();
byte[] udh = new byte[6];
udh[0]=5; //same for any msg
udh[1]=0; //same for any msg
udh[2]=3; //same for any msg
udh[3]=0; //CSMS reference number, must be same for all the SMS parts in the 
CSMS
udh[4]=2; //total number of parts
udh[5]=1; //this part's number in the sequence

//Need to set UDHI
ESMClass esm = new ESMClass(64);

//first part
byte[] msgPart = new byte[159];
System.arraycopy(udh, 0, msgPart , 0, 6);
System.arraycopy(msgBytes, 0, msgPart , 6, 153);

//Call session.submitShortMessage() method
//passing msgPart array for shortMessage 
//argument and esm for ESMClass argument

//second part
//set sequence number in udh
udh[5]=2;

msgPart = new byte[147];
System.arraycopy(udh, 0, msgPart , 0, 6);
System.arraycopy(msgBytes, 153, msgPart , 6, 147);

//Call session.submitShortMessage() method
//passing msgPart array for shortMessage 
//argument and esm for ESMClass argument

2- Using message_payload
The whole message is set in the message_payload optional parameter. 
short_message should not be used and sm_length should be set to 0. 

Example of using message_payload with JSMPP

String myLongMessage = "a very long message...";
OptionalParameter messagePayloadParameter = new 
OptionalParameter.OctetString(Tag.MESSAGE_PAYLOAD, myLongMessage);

//Call session.submitShortMessage() method
//passing an empty array for shortMessage 
//argument and messagePayloadParameter 
//as the last argument

3- Using SARXXX Optional Parameters

Example of using sarxxx with JSMPP

OptionalParameter sarMsgRefNumParameter = new 
OptionalParameter.Int(Tag.SAR_MSG_REF_NUM, 0);
OptionalParameter sarTotalSegmentsParameter = new 
OptionalParameter.Int(Tag.SAR_TOTAL_SEGMENTS, 2);
OptionalParameter sarSegmentSeqnumParameter = new 
OptionalParameter.Int(Tag.SAR_SEGMENT_SEQNUM, 1);

// Assuming message is 300 chars long
String myLongMessage = "a very long message...";
byte[] msgBytes = myLongMessage.getBytes();

byte[] msgPart = new byte[254];
System.arraycopy(msgBytes, 0, msgPart , 0, 254);

//Call session.submitShortMessage() method
//passing msgPart array for shortMessage 
//argument and sarxxx as last arguments

msgPart = new byte[46];
System.arraycopy(msgBytes, 254, msgPart , 0, 46);

//change the sequence number
sarSegmentSeqnumParameter = new OptionalParameter.Int(Tag.SAR_SEGMENT_SEQNUM, 
2);

//Call session.submitShortMessage() method
//passing msgPart array for shortMessage 
//argument and sarxxx as last arguments

Finally, let me know if that works for you or if you need extra information

Original comment by balsar...@gmail.com on 4 Jan 2012 at 12:36

GoogleCodeExporter commented 9 years ago

Original comment by T.Delenikas on 20 Jan 2012 at 1:54

GoogleCodeExporter commented 9 years ago

Original comment by admin@smslib.org on 1 Jan 2014 at 9:25

GoogleCodeExporter commented 9 years ago

Original comment by admin@smslib.org on 5 Jan 2014 at 4:05