0845 356 5758
or

Sending SMS to a Specific Port

Recently we seem to be getting more and more support cases raised asking if we support sending an SMS text message to a specific port on a handset.  The short answer to this is yes, but it is considered to be an advanced subject that most users won't need to do and is very much a manual process.  So if you're willing to roll up your sleeves and dive into this, then please read on, but expect a little preamble before we get to the bones of it.  Also, I'm assuming you know how to consume a Web Service, or make HTTP post calls to a web page.

A Brief Introduction to SMPP and PDUs

Most of our connections to network operators are through the SMPP protocol (see smsforum.net for downloads of the specification).  To send an SMS to a specific port requires at least a rudimentary grasp of the concepts involved in this protocol, particularly the SubmitSM protocol data unit (or PDU).  In the loosest possible terms SMPP works using request and response PDUs.  In order to send a message, we send a SubmitSM PDU to the operator, who then sends back a response PDU to say they have accepted it.

A SubmitSM PDU contains everything the operator requires to send one text message: the originator and destination mobile numbers (in the source and destination address parameters), the message text to send (in the user data section), and a number of other parameters that we need to set in order to describe the content of the message.

The two most important of these other parameters are the data coding scheme, and the ESM class.  The data coding scheme (or DCS) is used to describe how the bytes in the user data section of the PDU are encoded.  The ESM class describes special attributes that are applied to the message (more on this later).

Importantly, there are no parameters in a SubmitSM PDU that directly take the source and destination ports of the application on the handset to send the message to.

So how do we specify port values in the PDU if there are no parameters for them?  We place a header on the user data section.

Introduction to User Data Headers (UDH)

A UDH is a series of bytes within the user data section of a SubmitSM PDU.  A standard text message does not have a UDH, so is treated like a normal text message on the phone and is delivered to the standard message inbox.  A UDH can contain port and concatenation information, which tells the handset where to send the message, and if there are any further parts of the message it needs to wait for.

We only need to know about the port information in the UDH for the purposes of this example.

Here is a stream of bytes (hex encoded) that would be in the user data section of the PDU for a WAP Push message (as a WAP Push message needs to contain port information):

0605040B8423F025060A03AE81EAAF828DADB48401056A0045C60C0364657670726F6A32302E626C6F6773706F742 E636F6D2F000801034D7920426C6F67000101

The header of this message is this:

0605040B8423F0

The first three bytes here (060504) describe various lengths within the header.  The port information is contained within the next four bytes (0B8423F0).  So in summary the entire message can be broken down as:

060504: Length indicators
0B84: Destination port (2948) 
23F0: Originator port (9200)
25060.... : the actual message bytes describing the URL and a piece of text.

Therefore, a WAP Push message is a series of bytes with a UDH that specifies destination port 2948, and source port 9200.  But as headers are optional on a user data section, how does the phone know if one is present?  We indicate this in the ESM class parameter of the PDU.

UDH Indicator and Data Coding

The ESM class parameter plays a very powerful role in how the message is interpreted and displayed on the phone, and it's just one byte.  Combinations of individual bits within this byte indicate different requirements, but the one we're interested in is the UDH Indicator.  If you set these bits (and don't need any others set) the value of the ESM class byte is 64 (0x40), and this indicates that a UDH is present in the user data section.

The DCS parameter comes into play here by indicating how the bytes after the header (if one is present) are to be decoded.  In a normal message with no header this parameter is set to 0, which indicates the default alphabet used by the operator.  In a Wap Push message this is set to 4 to indicate 8-bit binary.

So how do I send a message to a port?

Now you're familiar with the concepts, I'll finally get around to telling you what you're reading this post for.  We expose an Advanced Send Service as a Web Service, and an HTTP post interface.  If you take a look at one of these you will see ESMClass and DataCodingScheme parameters (see: I told you they were important, so if you've just skipped to here and don't know what I'm talking about, go back and read everything).

Let's have an example.  Say you need to send a text message "ab"(without the quotes) to port 5000 (for actual port values you'll have to consult the documentation for the application you are sending to). 

1. Construct the header

You'll need to construct the header and encode the text onto the end of it.

For this example the header will be:

06050413880000

Because:

060504: Length indicators
1388: Destination port (5000)
0000: Originator port (zero it if you don't need a specific one)

2. Encode your text

Encode your text to ASCII and append to the header.  The text "ab" is 0x6162, so your full message with header is:

060504138800006162

3. Submit the message

In this case the value for the ESMClass parameter will be 64, and the DataCodingScheme should be set to 0.  Put the string 060504138800006162 as the body parameter, enter values for the rest of the parameters (originator, destination, etc.) and submit.

And that's it.  As long as your header is correct and you've encoded the text correctly you should have the message delivered to the application on the phone that needs it.

Important Notes

Some things to be aware of when submitting messages like this

  • Commonly, if the handset you are sending to cannot interpret the message you're sending it will just do nothing.  You will get a delivery receipt for the message saying it has been delivered to the handset, but you will see nothing on the screen.  This makes debugging very difficult.
  • The body parameter (in this case) needs to be a hex encoded string of the bytes you wish to send.  This means 2 hex characters per byte.  i.e. 0xA should be sent as 0A not just A.
  • The values for the ESMClass and DCS should be decimal numbers
  • With regards to character encoding, we have received scattered reports of some non-alphanumeric characters not being displayed correctly, but we haven't had been able to narrow down the cause of this.  If you experience encoding problems please email support@esendex.com.