26.2.4. Syntax of
the +CMGR AT Command in SMS PDU Mode
The
syntax of the +CMGR AT command in SMS PDU mode is the same as that in
SMS text mode:
+CMGR=index
In
the above line, index
is an integer specifying the location of the SMS message to be read
from the message storage area.
26.2.5. Format of
the Information Response of the +CMGR AT Command in SMS PDU Mode
If
the GSM/GPRS modem or mobile phone reads the SMS message from message
storage successfully, it will return an information response to the
computer / PC. In SMS PDU mode, the information response of the +CMGR
AT command has the following format: (Optional fields are enclosed in
square brackets.)
+CMGR:
message_status,[address_text],TPDU_length<CR><LF>SMSC_number_and_TPDU
Before
we discuss each of the fields that appear in the +CMGR information
response, let's see an example that gives you some idea of how an
actual +CMGR information response should look like:
+CMGR:
0,,62 07915892000000F0040B915892214365F700007040213252242331493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
OK
The
message_status Field
The
first field of the information response of the +CMGR AT command,
message_status, is an
integer that indicates the status of the SMS message. It can be one
of the following four values:
0.
It refers to the message status "received unread".
1.
It refers to the message status "received read".
2.
It refers to the message status "stored unsent".
3.
It refers to the message status "stored sent".
The
address_text Field
The
second field of the information response of the +CMGR AT command,
address_text, is a
string that contains the text associated to address
in the phonebook, where address
is the phone number encoded in the TPDU of the SMSC_number_and_TPDU
field. For example, if the phone number encoded in the TPDU is
"91234567" and the text "Alice" is associated to
the phone number "91234567" in the phonebook, address_text
will be "Alice". The AT command +CSCS (command name in
text: Select TE Character Set) can be used to specify the character
set for displaying address_text.
Note
that address_text is
an optional field. Some GSM/GPRS modems and mobile phones (examples:
most Nokia products, including my Nokia 6021) leave this field empty.
The
TPDU_length Field
The
third field of the information response of the +CMGR AT command,
TPDU_length, is an integer
that indicates the length (in octets. 1 octet = 8 bits) of the TPDU
contained in the SMSC_number_and_TPDU
field. In the earlier example command line, the value of the
SMSC_number_and_TPDU
field is:
07915892000000F0040B915892214365F700007040213252242331493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
It
can be divided into two parts. The following part is the TPDU:
040B915892214365F700007040213252242331493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
The
TPDU is coded in hexadecimal format. Each character represents 4
bits, i.e. 1/2 octet. The TPDU has 124 characters and so there are
totally 62 octets. That's why the value of the TPDU_length
field is 62.
The
SMSC_number_and_TPDU Field
The
fourth field of the information response of the +CMGR AT command,
SMSC_number_and_TPDU,
specifies the SMSC number and the TPDU (Transfer Protocol Data Unit)
in hexadecimal format. If the SMS message to be read is an
incoming SMS message, the TPDU will be of the type SMS-DELIVER. If
the SMS message to be read is an outgoing SMS message, the TPDU will
be of the type SMS-SUBMIT.
26.2.6. Some
Explanation about the Decoding of the SMSC_number_and_TPDU Field
Value of the +CMGR AT Command
This
section provides some explanation about the decoding of the
SMSC_number_and_TPDU
field value of the +CMGR AT command so that you can extract the
information you need from it. Let's consider the SMSC_number_and_TPDU
field value in the earlier example command line:
07915892000000F0040B915892214365F700007040213252242331493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
The
above value can be divided into two parts, as shown below. The first
part contains information about the SMSC. The second part is the
TPDU.
07915892000000F0
040B915892214365F700007040213252242331493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
26.2.6.1. Incoming
SMS Messages and Outgoing SMS Messages
The
SMS message discussed above is an incoming SMS message. The first
part indicates which SMSC the SMS message was received from,
and the second part is a TPDU of the type SMS-DELIVER. If the SMS
message retrieved by the +CMGR AT command is an outgoing SMS message,
the first part indicates which SMSC will be used to send the SMS
message, and the second part is a TPDU of the type SMS-SUBMIT, whose
format is different from that of an SMS-DELIVER TPDU.
The
format of the SMSC_number_and_TPDU
field value of an outgoing SMS message is the same as that mentioned
in the earlier section "Some
Explanation about the Coding of the SMSC_number_and_TPDU Parameter
Value of the +CMGS AT Command".
Thus, we will not discuss about it again here. In the following
sections, we assume the SMS message retrieved by the +CMGR AT command
is an incoming SMS message and the TPDU is of the type SMS-DELIVER.
26.2.6.2. The
SMSC Part
The
SMSC part can be further divided into three sub-fields, like this:
07
91 5892000000F0
The
First Sub-field: Length of the Second and Third Sub-fields
The
first sub-field specifies the length in octets of the following two
sub-fields. There are 14 hexadecimal digits in "915892000000F0"
and each hexadecimal digit represents 4 bits, i.e. 1/2 octet. So,
there are totally 7 octets. That's why the value of the first
sub-field is 0x07.
The
Second Sub-field: Type of SMSC Number
The
second sub-field specifies the type of the SMSC number assigned to
the third sub-field. Two values are
commonly used. They are 0x81 (129 in decimal) and 0x91 (145 in
decimal):
0x81.
It means the SMSC number is formatted using the typical ISDN /
telephony numbering plan (ITU E.164/E.163) but it is not sure
whether the SMSC number is an international number, a national
number or a number of other types. For example, suppose the SMSC
number from which the SMS message was received is "+85290000000".
If the value of the second sub-field is 0x81, the SMSC number
assigned to the third sub-field may be "85290000000"
(country code included) or "90000000" (country code
omitted).
0x91.
It means the SMSC number is formatted using the typical ISDN /
telephony numbering plan (ITU E.164/E.163) and it is an
international number. For example, suppose the SMSC number from
which the SMS message was received is "+85290000000". If
the value of the second sub-field is 0x91, the SMSC number assigned
to the third sub-field should be "85290000000".
The
Third Sub-field: SMSC Number
The
third sub-field specifies the SMSC number from which the SMS message
was received. 0x5892000000F0 represents the phone number
+85290000000. Here's how the value 0x5892000000F0 is obtained:
Starting
from the left, group the digits of the phone number 85290000000 into
pairs, like this: 85 29 00 00 00 0.
As
the last group has only one digit, we add an "F" to make
up a pair. The result is 85 29 00 00 00 0F.
Swap
the digits in each pair and you will get 58 92 00 00 00 F0.
26.2.6.3. The TPDU
Part (SMS-DELIVER TPDU)
The
TPDU part can be divided into nine sub-fields, as shown below. This
is a TPDU of the type SMS-DELIVER.
04
0B 91 5892214365F7 00 00 70402132522423 31
493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
The
First Sub-field: First Octet of the TPDU
The
first sub-field is the first octet of the TPDU. It tells us several
things:
the
type of the TPDU
whether
the SMSC has messages that are waiting to be sent to us
whether
a reply path exists
whether
a user data header exists in the TPDU
whether
a status report is requested by the sender of the SMS message
The
value 0x04 means:
the
type of the TPDU is SMS-DELIVER
the
SMSC has no message that is waiting to be sent to us
no
reply path exists
no
user data header exists in the TPDU
no
status report is requested by the sender of the SMS message
The
Second Sub-field: Length of the Sender Phone Number
The
second sub-field specifies the length
in digits of the sender phone number. The sender phone number
specified in the fourth sub-field is "+85291234567",
which has 11 digits. Thus, the value of the second sub-field is 0x0B
(i.e. 11 in decimal).
The
Third Sub-field: Type of the Sender Phone Number
The
third sub-field specifies the type of the sender phone number
assigned to the fourth sub-field. Two
values are commonly used. They are 0x81 (129 in decimal) and 0x91
(145 in decimal):
0x81.
It means the sender phone number is formatted using the typical ISDN
/ telephony numbering plan (ITU E.164/E.163) but it is not sure
whether the sender phone number is an international number, a
national number or a number of other types. For example, suppose
there is an incoming SMS message that was originated from the phone
number "+85291234567". If the value of the third sub-field
is 0x81, the sender phone number assigned to the fourth sub-field
may be "85291234567" (country code included)
or "91234567" (country code omitted).
0x91.
It means the sender phone number is formatted using the typical ISDN
/ telephony numbering plan (ITU E.164/E.163) and it is an
international number. For example, suppose there is an incoming SMS
message that was originated from the phone number "+85291234567".
If the value of the third sub-field is 0x91, the sender phone number
assigned to the fourth sub-field should be
"85291234567".
The
Fourth Sub-field: Sender Phone Number
The
fourth sub-field specifies the sender phone number. The value
0x5892214365F7 represents the phone number +85291234567. Here's how
the value 0x5892214365F7 is obtained:
Starting
from the left, group the digits of the phone number 85291234567 into
pairs, like this: 85 29 12 34 56 7.
As
the last group has only one digit, we add an "F" to make
up a pair. The result is 85 29 12 34 56 7F.
Swap
the digits in each pair and you will get 58 92 21 43 65 F7.
The
Fifth Sub-field: Protocol Identifier
The
fifth sub-field specifies the protocol identifier. Its value should
be 0x00 for normal cases.
The
Sixth Sub-field: Data Coding Scheme
The
sixth sub-field specifies the data coding scheme. The value 0x00
indicates that the text in the SMS message body is encoded according
to the "GSM 7-bit default alphabet" text coding scheme.
The
Seventh Sub-field: Service Center Time Stamp
The
seventh sub-field specifies the time and data at which the SMS
message arrived at the service center (i.e. SMSC). The
value 0x70402132522423 represents 12 April 2007, 23:25:42 GMT+8
hours. Here's how the value 0x70402132522423 is decoded:
Starting
from the left, group the digits of the value 0x70402132522423 into
pairs, like this: 70 40 21 32 52 24 23.
Swap
the digits in each pair and you will get 07 04 12 23 25 42 32.
Starting from the left, the values represent year, month, day, hour,
minute, second and time zone respectively. Note
that the unit of time zone is a quarter of an hour.
The
decoding of the time zone field requires a bit more explanation. The
binary representation of the hexadecimal value 0x32 is 00110010. It
can be divided into three parts, like this:
0
011 0010
The
first part represents the plus-minus sign. If the value of the first
part is 0, the sign is "+". If it is 1, the sign is "-".
The second part represents the most significant digit of the time
zone. "011" is equal to 3 in decimal. The third part
represents the least significant digit of the time zone. "0010"
is equal to 2 in decimal. Overall, "00110010" represents
GMT+32 quarters of an hour = GMT+8 hours.
The
Eighth Sub-field: Length of the SMS Message Body
The
eighth sub-field specifies the length of the SMS message body in
septets (1 septet = 7 bits). The value 0x31 means there are 49
septets (or characters, since each character is represented by 7 bits
according to the "GSM 7-bit default alphabet" text coding
scheme) in the SMS message body.
The
Ninth Sub-field: SMS Message Body
The
ninth sub-field specifies the SMS message body. The value below:
0x493A283D0795C3F33C88FE06C9CB6132885EC6D341EDF27C1E3E97E7207B3A0C0A5241E377BB1D7693E72E
represents the text message "It is easy to read text messages
via AT commands.". Below shows how to convert the
hexadecimal value to text:
Group
the digits of the hexadecimal value into pairs, as shown below. Each
pair represents one octet of data.
49
3A 28 3D 07 95 C3 F3 3C 88 FE 06 C9 CB 61 32 88 5E C6 D3 41 ED F2 7C
1E 3E 97 E7 20 7B 3A 0C 0A 52 41 E3 77 BB 1D 76 93 E7 2E
The
binary representation of the first octet is 01001001. With the
character set "GSM 7-bit default alphabet", each character
is represented by 7 bits. The seven least significant bits, 1001001,
represent the first character. The hexadecimal value of 1001001 is
0x49, which represents the character "I" according to the
character set "GSM 7-bit default alphabet". To find out
which character is represented by a certain hexadecimal code, see
"Appendix: GSM 7-bit Default
Alphabet Table (with Character Codes of ISO 8859 Latin 1)"
of this SMS tutorial.
The
binary representation of the second octet is 00111010. Now move the
most significant bit of the first octet to the rightmost position of
the second octet. The result is 001110100.
The seven least significant bits, 1110100, represent the second
character. The hexadecimal value of 1110100 is 0x74, which
represents the character "t" according to the character
set "GSM 7-bit default alphabet".
Similarly,
move the two unused bits at the leftmost position of the second
octet to the rightmost position of the third octet. The binary
representation of the third octet is 00101000 and so the
result is 0010100000. The seven least significant
bits, 0100000, represent the third character. The hexadecimal value
of 0100000 is 0x20, which represents the space character according
to the character set "GSM 7-bit default alphabet".
The
unpacking process continues. This is illustrated in the following
table.
|
Bit 6
|
Bit 5
|
Bit 4
|
Bit 3
|
Bit 2
|
Bit 1
|
Bit 0
|
|
|
Character
1
|
1
|
0
|
0
|
1
|
0
|
0
|
1
|
=
|
0x49
|
Character
2
|
1
|
1
|
1
|
0
|
1
|
0
|
0
|
=
|
0x74
|
Character
3
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
4
|
1
|
1
|
0
|
1
|
0
|
0
|
1
|
=
|
0x69
|
Character
5
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
=
|
0x73
|
Character
6
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
7
|
1
|
1
|
0
|
0
|
1
|
0
|
1
|
=
|
0x65
|
Character
8
|
1
|
1
|
0
|
0
|
0
|
0
|
1
|
=
|
0x61
|
Character
9
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
=
|
0x73
|
Character
10
|
1
|
1
|
1
|
1
|
0
|
0
|
1
|
=
|
0x79
|
Character
11
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
12
|
1
|
1
|
1
|
0
|
1
|
0
|
0
|
=
|
0x74
|
Character
13
|
1
|
1
|
0
|
1
|
1
|
1
|
1
|
=
|
0x6F
|
Character
14
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
15
|
1
|
1
|
1
|
0
|
0
|
1
|
0
|
=
|
0x72
|
Character
16
|
1
|
1
|
0
|
0
|
1
|
0
|
1
|
=
|
0x65
|
Character
17
|
1
|
1
|
0
|
0
|
0
|
0
|
1
|
=
|
0x61
|
Character
18
|
1
|
1
|
0
|
0
|
1
|
0
|
0
|
=
|
0x64
|
Character
19
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
20
|
1
|
1
|
1
|
0
|
1
|
0
|
0
|
=
|
0x74
|
Character
21
|
1
|
1
|
0
|
0
|
1
|
0
|
1
|
=
|
0x65
|
Character
22
|
1
|
1
|
1
|
1
|
0
|
0
|
0
|
=
|
0x78
|
Character
23
|
1
|
1
|
1
|
0
|
1
|
0
|
0
|
=
|
0x74
|
Character
24
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
25
|
1
|
1
|
0
|
1
|
1
|
0
|
1
|
=
|
0x6D
|
Character
26
|
1
|
1
|
0
|
0
|
1
|
0
|
1
|
=
|
0x65
|
Character
27
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
=
|
0x73
|
Character
28
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
=
|
0x73
|
Character
29
|
1
|
1
|
0
|
0
|
0
|
0
|
1
|
=
|
0x61
|
Character
30
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
=
|
0x67
|
Character
31
|
1
|
1
|
0
|
0
|
1
|
0
|
1
|
=
|
0x65
|
Character
32
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
=
|
0x73
|
Character
33
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
34
|
1
|
1
|
1
|
0
|
1
|
1
|
0
|
=
|
0x76
|
Character
35
|
1
|
1
|
0
|
1
|
0
|
0
|
1
|
=
|
0x69
|
Character
36
|
1
|
1
|
0
|
0
|
0
|
0
|
1
|
=
|
0x61
|
Character
37
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
38
|
1
|
0
|
0
|
0
|
0
|
0
|
1
|
=
|
0x41
|
Character
39
|
1
|
0
|
1
|
0
|
1
|
0
|
0
|
=
|
0x54
|
Character
40
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
=
|
0x20
|
Character
41
|
1
|
1
|
0
|
0
|
0
|
1
|
1
|
=
|
0x63
|
Character
42
|
1
|
1
|
0
|
1
|
1
|
1
|
1
|
=
|
0x6F
|
Character
43
|
1
|
1
|
0
|
1
|
1
|
0
|
1
|
=
|
0x6D
|
Character
44
|
1
|
1
|
0
|
1
|
1
|
0
|
1
|
=
|
0x6D
|
Character
45
|
1
|
1
|
0
|
0
|
0
|
0
|
1
|
=
|
0x61
|
Character
46
|
1
|
1
|
0
|
1
|
1
|
1
|
0
|
=
|
0x6E
|
Character
47
|
1
|
1
|
0
|
0
|
1
|
0
|
0
|
=
|
0x64
|
Character
48
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
=
|
0x73
|
Character
49
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
=
|
0x2E
|
|
|
|
|
|
|
|
0
|
|
|
Feedback Form (ExpandCollapse)
|
|