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