Mobile messaging
Johan Montelius
In this session you will experiment with different messaging alternatives.
You will first send plan SMS messages using a laptop and a mobile phone
an then learn how to code a WAP Push message to send a MMS notification
and a Service Indication.
Through out this tutorial it’s good to have the SMS specification 23.040
at hand. You can find it at the 3GPP web site.
Getting started
You need a computer and a mobile phone and some means to connect the
phone to the computer. A cable is of course to prefer but IrDa or Bluetooth
also works. We will communicate with the modem of the phone using AT
commands so you also need a terminal program. On a Windows platform
you could use HyperTerm and and on a Linux platform you can use minicom.
The firs thing you need to do is to connect the mobile and the computer
and find out which com port the modem is assigned. Next open up the
terminal program and attach the terminal to the com port. If you succeed
you should be able to issue the following AT command (¡cr¿ is you typing
AT+ CIMI<cr>
The result should be a fifteen digit number starting with 240.... (240 is
the number for Sweden). This is the IMSI number of the SIM card.
AT+ CSCA?<cr>
This is the number to the SMSC. You could change it to anything
you want but if you’re on the Telenor network it should probably read
When sending SMS messages over AT you either work in text mode or
binary (PDU) mode. You can check which mode you’re in with the command
CMGF. A 0 is PDU mode and a 1 is text mode.
AT+ CMGF?<cr>
To change it to text mode CMGF=1 but if you’re using a SonyEricsson
phone it is very likely that it will only give you a error message. Since
submit header (1 byte)
message ref (1 byte)
destination address (2-12 byte)
protocol identifier (1 byte)
coding scheme (1 byte)
validity period (0, 1 or 7 byte)
user data length (1 byte)
user data (0-140 byte)
we will experiment with different SMS parameters that is ok, we will do
everything in PDU mode. If your phone supports text mode you could try
to send a message directly.
AT+ CMGS="+46703123456"<cr>
>This is the message<ctrl-Z>
Sending a SMS using PDU mode is a bit more complicated. Remember
the structure of a Submit PDU.
Let’s first send a regular SMS and then we will explore the different
parameters. A simple submit header is 01, this indicates a SMS submit
without a validity period set. The message reference can be left out so we
will use 00 for now.
If your phone number is 0732-041640 we have to code it as 6437021446F0,
remember why? The number is then written in international format using
E.164 numbering plan. This will be coded using one byte as 91. The highest
bit is always set and the lower four bits indicate the E.164 numbering plan.
Bits 7,6 and 5 (in our case 001) describe how the number is written down.
We will use international format but you can try 010 (that is A) to use a
number without the country code. The length of the number is 11 digits so
the complete coding of the destination will thus be as follows.
Protocol identifier is set to 00 indicating a regular mobile to mobile
message. One can also play with protocol identifiers from 60 to 9F that are
used to replace previously delivered messages.
The coding scheme will in our first SMS be regular GSM 7-bit characters. So coding scheme is 00. We will use 8-bit data when we send more
complicated messages and then the coding scheme is 04.
Since we specified that there was no validity period we can omit this
byte. The length of the my secret message is thirty characters.
The message it self is hard to decode since it is coded in GSM 7-bit
characters but written down using hex numbers. The message is coded as
follows. Note that the coding of our 30 characters only requires 26 8-bit
A smaller messag that you can work with is “hello”. If we want to code
this we first write it down in 7-bit code with the least significat bit first.
The 7-bit code is ASCII for regular characters.
Now read the bits eight by eight.
0001011 1
010011 00
11011 001
1011 1111
011 .....
Patch the last octet with zeros and write down the corresponding hex
code. Remember that the least significat bit is the first bit.
0001011 1
010011 00
11011 001
1011 1111
011 00000
Since “hello” has five characters the we would code the length field as
05 and the message as E8329BFD06. Simple, right?
Now send you first PDU SMS using the CMGS command. The command
takes one argument that is the number of bytes in the PDU. When we issue
the command we will have an input prompt in the terminal. We can now
write down the PDU as listed above but we have to start with 00 to indicate
that the terminal should use its default SMSC (this byte is not part of the
PDU and is thus not counted in the length of the PDU). End the sequence
with ctr-z.
AT+ CMGS=40<cr>
>0001000B9164..... <ctr-z>
If all works ok you should have a OK message with a message reference.
Now let’s tweak the parameters a bit.
message waiting
One thing we can play with is the coding scheme. This byte holds more
than just the character coding. If the high nible is 1100 we tell the terminal
to handle the message as a “Message waiting indication”. If the low nible is
coded as follows s0ii where the s bit is set or re-set and ii is either voice
00, fax 01, mail 10 or other 11 .
Try to set and re-set an icon (different on each terminal) that indicates
that we have a fax waiting. The body of the PDU can be empty (length
ohh, no!
How often have you not sent a SMS and though “Ohh no, I should never
had sent that”. Well the designers of GSM knew this would happen so
they included a “Replace message” protocol type. The protocol identifier is
otherwise quite useless if you’re not in the business of sending telex messages.
If the high nible is set to 4 the low nible can specify a replace identifier from
one to seven. If we send one message with code 41 you can then send another
message with the same code and the new SMS will replace the old one.
Try to send a message and then change its meaning. Does it matter if
you have read the first message.
gone in 30 sec
Another parameter one can play with is the validity period. Turn a phone
off and then send it a message with very limited validity period (how do you
code 30 sec?). Then turn the phone back on and see if the SMSC is still
trying to deliver your message. You will probably have to use two phones
for this so collaborate in a small group.
Receiving a SMS
Receiving SMS can actually be quite tricky. One has to set it up properly
before we can even read stored messages on the terminal. There are different
memory areas and one can choose to work with, the SIM card denoted
"SM" and the mobile denoted "ME". There are also three different storage:
for reading and deleting, for writing and sending and for storing incoming
messages. Each storage can be allocated on either the SIM card or the
mobile. You can list the current setting with the CPMS command. You will
then also see how many messages you have in each storage.
The writing storage can be used to store SMS messages and and then
send them at a later point. This could be more convenient then issuing a
full CMSG command. We will now read messages so we must make sure that
the memory area for reading is the same as for storing incoming messages.
If incoming messages are stored in "ME" then we should also us this area for
We can now list the content of this memory area with the CMGL command.
However, this command also takes a parameter: the status of the message.
Check in the AT command reference how to use the CMGL command.
As you see we now have a message number attached to each message.
One can then read and handle a specific message.
The result is of course a SMS in its binary PDU format but this is of
course easy for you to decode. Look at a small message and try to identify the
elements. Remember that you’re now looking at a delivered SMS message,
not a submit message. All though similar in structure the decoding is not
the same. Can you see who it is from?
The next thing you could explore is how to automatically be notified of
incoming messages. If you build an application you do not want to poll the
terminal every 10’th second you would rather have a message being delivered
to you. First issue the CNMI command to find out how messages are handled
by default. Then change the setting so that arriving messages will give you
a message in the terminal window.
AT+ CNMI=2,1,0,0,0
More advanced stuff
You now have all the tools that you need to send SMS messages. You can
then proceed with one of three tasks: sending EMS messages, sending a
MMS notification or sending a Service Indication (SI). They all require you
to understand how User Data Headers are coded, the MMS and SI also
requires a lot of knowledge on how a WSP/WDP packet is coded.
Service Indication
This is the message we want to deliver. It’s a service indication message,
the message will be presented to the user and if the user choose to accept
the message the link to the server will be used. More information can be
found in WAP-167 Service Indication.
<?xml version="1.0"?>
<indication href="" >
This is a test.
In order to send this we need to code it in WBXML format. Note that
the specifics of how to code a service indication element is found in the end
of WAP-167.
Strings are coded in 8-bit octets, nothing funny here.
A WSP push
We now have to construct a WSP Push message.
Note that when you look for the token values in WAP-230 you will not
find ”0xAE” but rather ”0x2E”. When coding small integers the high bit is
The WSP message is then put in a WDP packet that is directed to the
push destination port.
WBXML version 1.1
public identifier for SI 1.0
charset iso-8859-1
length of string
si with content
indication with content and attributes
token for ”href=http://www.”
inline string follows
the string ”
end of string
end of indication attributes
inline string follows
the string ”2G1722”
end of indication
end of si
push transaction id, could be anything
WSP type is Push
header length
content type length
content type: application/vn
header: x-wap-application-id
2 - the WML User Agent
101 - last-push, URI authenticated
User Data Header length (not including this byte)
identifer elements, port addressing
length of element
push dest port (2948)
push originator port (9200)
concatenated short message
length of element
ref number
max number of segments
current segmenet number
A SMS-SUBMIT message with a User Header
This is the message reference but here we let the phone set it.
Length of the address, change this if you change the receiver number
The address type used, in this case international starting with country code
this is the phone number, check the SMS tutorial.
Data coding scheme, in this case 8-bit bytes.
This is the length of the User Data
The WDP packet have different structure depending on which link layer we
are using. Since we are sending it over a SMS we will code it as a User Data
Header. Note that we have two elements one specifying the destination port
(2948) and a second indicating that the rest a concatented message.
So we now have a WDP that includes a WSP consisting of a Service indication. This should now all be put in a SMS.
The whole WDP is now interpreted as a User Header Information. If
the terminal can not understand the header it will be ignored.
Download PDF