EM310,AT指令之_文本和PDU短信解析

简介

本文主要将了接收中英文短信的各个字段的解释.

  • 短信编码的相关知识
  • 0.参数设置
  • 发送中文短信
  • 发送英文短信
  • 1、接收中文短信
  • 2、接收纯英文或数字

短信编码的相关知识

操作SIM卡中的数据操作主要有两个地方,一个是短信操作,还有一个通讯录操作,两种编码略有差别:

1、短信息操作:

在短信息中,默认一条短信的最大长度为140个字节。

纯ASCII字符主要采用7-bit编码格式,即只是利用了字符的后7位数据,这样160个ASCII字符只占用140个字节。这样我们手机的一条短信就可以发送160个ASCII字符了

(160*7=1120=140*8)

160*7 140*8
7-bit 8-bit
ASCII ucs2的一半

包含汉字的字符采用UCS2编码格式,即UNICODE的2字节编码格式。这样每个汉字占用两个字节,只要短信中包含中文,整条短信的字符都要采用UCS2编码,这样一条短信最多就只能发送70个字符(汉字,英文字符,标点等)了。

2、通讯录操作:

通讯录中的姓名长度限制不一样,本人使用的TD模块限制长度为14个字节。

单独的ASCII字符正常都使用8-bit编码格式,即每个字节都占用8位,这也是最为正常的存储格式了。

如果包含中文等字符,则正常采用80编码格式,即整个姓名字符以80开头,后面跟上UCS2数据,但有些情况下又会采用81或者82开头。

a) 80 开头:

80开头的为ucs2格式(注意:后面的字符必须有中文才行,否则可能是以80开头的纯ASCII字符串),大头在前,小头在后。

例1:中国(\u4e2d\u56fd)

UNICODE编码为:4E2D56FD

用ucs2的80方案表示是:80 4E2D 56FD

例2:杜10娘  (\u675c \0031 \0030 \u5a18)1和0的unicode见下面的表.

UNICODE编码为:675C 0031 0030 5A18

用ucs2的80方案表示是:80675C003100305A18

显然只要有中文,数字也得占用两个字节。

 

b) 81 开头:

81开头的格式中,包含一个基址(一个字节)。有这个基址,就可以用一个字节表示一个ucs2字符了。

在格式上,81是标识,后一个字节表示整个字符串长度,再后面一个字节是基址,再往后的就都是数据了。先举一例:

例3:杜杜杜

UNICODE编码为:675C 675C 675C

0x675C

67      0x6700

  5C    0x005C

用ucs2的80方案表示是:80 675C 675 C675C

用ucs2的81方案表示是:81 03 CE DC D CDC

分析一下UCS2的81方案:8103CEDCDCDC

81:为标记

03:表示整个字符串为3个字符

CE:一个字节为基址。解析的方法为:将基址(CE)左移七位,并在最高位添加一个0(这样就16位啦)。此时基址变为0x6700,然后再判断后面的数据字节。

DCDCDC:3个数据字节 DC, DC, DC 。如果数据字节的最高位为0,则认为此字节是一个ASCII字符。如果数据字节的最高位为1,则低7位为基址的一个偏移,实际的UCS2字符为基址加上这个偏移值。由于此处三个数据字节最高位都为1,5C=1 101 1100

则实际的3个字符的 偏移值为:5C, 5C, 5C。实际的UCS2编码为: 0x675C 0x675C 0x675C, 此处我们就看的明白了。

 

例4:一丁丂七丄丅 (注:这些字符属于GBK字符集)

UNICODE编码为:4E00 4E01 4E02 4E03 4E04 4E05

用ucs2的80方案表示是:80 4E004E014E024E034E044E05

用ucs2的81方案表示是:81069C808182838485

分析一下UCS2的81方案:81069C808182838485

81:为标记

06:表示整个字符串为6个字符

9C:一个字节为基址。解析的方法为:将基址(9C)左移七位,并将最高位置为0,最低位再补一个0(这样就16位啦)。此时基址

变为0x4E00,然后再判断后面的数据字节。

808182838485:6个数据字节 80,81,82,83,84,85 。由于此处六个数据字节最高位都为1,则实际的6个字符的偏移值为:00, 

01,02,03,04,05。实际的UCS2编码为:0x4E00,0x4E01,0x4E02,0x4E03,0x4E04,0x4E05。 OK。

c) 82 开头:

82开头的格式中,包含一个基址(两个字节)。有这个基址,就可以用一个字节表示一个ucs2字符了。

在格式上,81是标识,后一个字节表示整个字符串长度,再后面两个字节是基址,再往后的就都是数据了。先举一例:

例5:8025EF芳

UNICODE编码为:00380030003200350045004682B3

用ucs2的80方案表示是:8000380030003200350045004682B3

用ucs2的81方案表示是:因为格式的限制,最多容纳128个中文和127个英文,所以此处无法用81格式表示

用ucs2的82方案表示是:82078280383032354546B3

分析一下UCS2的82方案:82078280383032354546B3

82:为标记

07:表示整个字符串为7个字符

8280:两个字节为基址。

383032354546B3:7个数据字节 38,30,32,35,45,46,B3。如果数据字节的最高位为0,则认为此字节是一个ASCII字符。如果

数据字节的最高位为1,低7位为基址的一个偏移,实际的UCS2字符为基址加上这个偏移值。由于此处七个数据字节的前六个字节最高

位为0,所以表示6个ASCII字符0x38,0x30,0x32,0x35,0x45,即8025EF。第七个字节的最高位为1,则此数据的

偏移值为0x33,需要加上基址 0x8280,UCS2编码为0x82B3(

例6:杜杜1

UNICODE编码为:675C675C0031

用ucs2的80方案表示是:80675C675C0031

用ucs2的81方案表示是:8103CEDCDC31

用ucs2的82方案表示是:82036700DCDC31

分析一下UCS2的82方案:82036700DCDC31

82:为标记

03:表示整个字符串为6个字符

6700两个字节为基址。

DCDC31:36个数据字节 DC,DC,31。由于此处三个字节的前两个字节最高位为1,则此数据的偏移值为0x5C,需要加上基址

0x6700,UCS2编码为:0x675C()。第三个字节的最高位为0,所以表示一个ASCII字符:0x31,即 1

此处只是稍微分析了一下UCS2三种格式(80,81,82)的解码,想必知道了各个字段的含义,编码也就轻松多了。

代码 显示 描述
U+0030 0 数字 0
U+0031 1 数字 1
U+0032 2 数字 2
U+0033 3 数字 3
U+0034 4 数字 4
U+0035 5 数字 5
U+0036 6 数字 6
U+0037 7 数字 7
U+0038 8 数字 8
U+0039 9 数字 9

 

 

0.参数设置

    1、短信收发模式设置

   短消息的发送和接收控制模式有三种:

模式 说明
Block模式 使用Block模式需要手机生产厂家提供驱动支持。
PDU模式 支持中文,英文,PDU模式已取代Block模式,
Text模式 不支持中文

因此,为了系统的通用性,兼容中英文短消息的发送接收,建议使用PDU模式来处理短消息,这样应设置:AT+CMGF=0 //PDU方式

然后在此应用中为了解码方便,而且也不需要中文,可以使用Text模式.AT+CMGF=1 //text方式

    2、新信息处理方式设置

格式:AT+CNMI=[<mode>[,<mt >[,<bm>[,<ds>[,<bfr>]]]]]

示例:

AT+CNMI=2,1 NOTE:将短信存储到ME 或SIM 卡后,再给出新短信指示
OK
+CMTI: "SM",1 NOTE:显示新短信指示

AT+CNMI=2,2 NOTE:收到短信,直接给出短信内容
OK
+CMT: "8613902288001",,"07/04/19,22:36:19+32",145,4,0,0,"8613912345500",145,4
TEST

这里我们使用的是:AT+CNMI=2,1,0,0,0  //将短信存储到ME 或SIM 卡后,再给出新短信指示

    3、回显设置

ATE1 //有回显,方便测试

ATE10//无回显,便于数据处理.

    4、消息服务设置

 

 

短信发送

以要将“你好”发送到13752141860,信息中心号码为:+8613800220500为例:

    1、PDU数据格式分析

      应发送的PDU字符串为:

0891683108200205F031000D91683157121468F00008AA044F60597D

下面对这段PDU数据进行详细分析:

(1)08

信息中心号码的长度,将91683108200205F0的长度除2,格式化成2位的16进制字符串所得

也就是 16/2=8(10)=0x08(16).

    (2)91 //主叫短信中心号码类型'91是TON/NPI遵守International/E.164标准,指在号码前需加‘+’号

         9110010001 //每一位数字转换为4位二进制数,各位分别表示:

            1 固定值
           001 //数值类型(Type of Number):000—未知,001—国际,010—国内,111—留作扩展;
          0001//号码鉴别(Numbering plan identification):0000—未知,0001—ISDN/电话号码(E.164/E.163),1111—留作扩展;

    (3) 683108200205F0 //短信息中心号码

       转换方法:如果号码前面有+号,去掉“+”号→如果没有“86”,在号码前加上“86”:8613800220500→看看现在号码的长度是否为偶数,如果不是,在号码后面加上“F”:8613800220500F→将奇数位和偶数位交换,得到结果:683108200205F0

    (4)31 //TPDU头字节 (以十六进制表示)

       31(16)=00110001(2) //每一位数字转换为4位二进制数

             0 //应答路径—TP-RP(TP-Reply-Path):0—不设置; 1—设置

            0 //用户数据头标识—TP-UDHL(TP-User-Data-Header-Indicator):0—不含任何头信息; 1—含头信息       

            1 //状态报告要求—TP-SPR(TP-Status-Report-Request):0—不需要报告; 1—需要报告(有些地方写0为需要报告,经偶测试是错误的)

            10 //有效期格式—TP-VPF(TP-Validity-Period-Format):00—不提供(Not present); 10—整型(标准);01—预留; 11—提供8位字节的一半(Semi-Octet Represented)

             0 //拒绝复制—TP-RD(TP-Reject-Duplicates):0—接受复制; 1—拒绝复制

           01 //信息类型提示—TP-MTI(TP-Message-Type-Indicator):00—读出(Deliver); 01—提交(Submit)

    (5)00 //信息类型

0D91683157121468F00008AA044F60597D

     (6)0D //被叫号码长度,8613752141860的长度格式化为2位16进制所得13(10)=0x0D(16)

     (7)91 //被叫短信中心号码类型'91是TON/NPI遵守International/E.164标准,指在号码前需加‘+’号,小灵通为81

     (8)683157121468F0 //被叫号码,转换方法同(3) 

13752141860-->8613752141860-->8613752141860F-->683157121468F0

     (9)00 //协议标识 TP—PID

       00--00000000 //每一位转换为4位二进制数

           00   //Bit No.7与Bit No.6: 00—如下面定义的分配Bit No.0—Bit No.5;01—参见GSM03.40协议标识完全定义;10—预留;11—为服务中心(SC)特殊用途分配Bit No.0—Bit No.5。 一般将这两位置为00。
          0     //Bit No.5:0—不使用远程网络,只是短消息设备之间的协议;1—使用远程网络。
          00000 //Bit No.0—Bits No.4:00000—隐含;00001—电传;00010—group 3 telefax;00100—语音;00101—欧洲无线信息系统(ERMES);00110—国内系统;10001—任何基于X.400的公用信息处理系统;10010—Email。

     (10)08 //数据编码方案,08:中文编码,00为英文或数字,Bit No.7与Bit No.6.Bit No.7的编码解码比较复杂,建议在发送纯英文或数字的短信时仍使用中文编码,测试通过.

       08--00001000

          00 //Bit No.7与Bit No.6 :一般设置为00;

           0 //Bit No.5:0—文本未压缩,1—文本用GSM标准压缩算法压缩;

           0 //Bit No.4:0—表示Bit No.1、Bit No.0为保留位,不含信息类型信息,1—表示Bit No.1、Bit No.0含有信息类型信息;

           00 //Bit No.3与Bit No.2:00—默认的字母表,01—8bit,10—USC2(16bit),11—预留;

           00 //Bit No.1与Bit No.0:00—Class 0,01—Class 1,10—Class 2(SIM卡特定信息),11—Class 3。

0D91683157121468F00008AA044F60597D

    (11)AA //有效期TP-VP(TP-Valid-Period),16进制数

   AA表示短信息被保留的时间为4天,其计算方法依照下表。

VP值(10进制数)

短消息有效长度

0~143

(VP+1)×5分钟

144~167

12时+(VP-143)×30分

168~196

1天×(VP-166)

197~255

1周×(VP-192)

 

    (12)04 //用户数据长度TP-UDL(TP-User-Data-Length),4F60597D的长度除2格式化为2位16进制数所得

    (13)4F60597D //用户数据TP-UD(TP-User-Data),这个就是我们发送的内容"你好"的UniCode码了

"你好"\u4f60 \u597d  工具: http://app.baidu.com/2unicode?keyword=unicode%E8%BD%AC

 

在PDU模式中,发送普通的ASCII字符用7-bit编码方式,将一串7-bit字符编码为8-bit数据,每8个字符可压缩成7个。如果发送中文字符,则采用UCS2编码方式,每个中文字符用16位的Unicode字符表示.将字符串转换为UniCode码的过程网上有很多,这里提供DELPHI下的编码函数:

***********************************************************

function Thread_Smsg.str_Gb2UniCode(text:string):String;
var
i,j,len:Integer;
cur:Integer;
t:String;
ws:WideString;
begin
Result:='';
ws:=text;
len:=Length(ws);
i:=1;
j:=0;
while i<=len do
begin
     cur:=ord(ws[i]);
     FmtStr(t,'%4.4X',[cur]); //BCD转换
   Result:=Result+t;
   inc(i);
   //移位计数达到7位的特别处理
   j:=(j+1)mod 7;
end;
end;

***********************************************************

    2、发送短信

做好了要发送的PDU数据包以后终于可以开始发送短信了。

首先发送AT,GSM回答OK,表明建立连接成功,可以测试各类AT指令;

接着发送AT+CMGS=17,17是指将PDU数据中短信中心号码后面的字符串(本例中即为31000D91683157121468F00008AA044F60597D)的长度除以2,格式化为2位的十进制数;最大长度为164,测试过165以上就会返回ERROR。

 

但是这里有个问题,70个汉字编辑成PDU后长度是155,但是这140个字符是汉字和字母数字的组合,长度就有可能超过164,因为每一位的数字或字母也被转为4位的UNICODE码。

发送长度后,GSM会返回>,然后我们发送刚才编辑的PDU字符串:0891683108200205F031000D91683157121468F00008AA044F60597D以CTRL+Z结束;

08 91 683108203005F0 31 00 0D 91 685112059236F9 00 08 AA 04 4F60597D

0891683108200205F031000D91685112059236F90008AA044F60597D

0891683108200305F031000D91685112059236F90008AA044F60597D

0891683108200305F031000D91685112059236F90008AA044F60597D

--------------------------------------------------------------------------------

短信中心:

+8613800230500

8613800230500

8613800230500F

683108200305F0

被叫号码
15215029639

8615215029639

8615215029639F

685112059236F9

 

如果GSM返回:就表示发送成功了。

        +CMGS: 183 //183是发送短信时产生的顺序号,在对方接收到短信发回状态报告时候,状态报告中会包含此顺序号

        OK

这里需要注意的是手机返回OK只能确认是成功发送到GSM网络上,接收方是否真正收到短信需要通过发送报告得知。有关如何获得发送报告在“发送报告的PDU数据分析”中有说明。

 

1、接收中文短信

以接收13752141860 号码发送来的“你好”,信息中心号码为:+8613800220500为例,手机接收到字符串为:

+CMT: ,24

0891683108200205F0240D91683157121468F0000860800331220000044F60597D

可以添加下分隔符来方便阅读:

0891683108200205F0240D91683157121468F0000860800331220000044F60597D

>>首先分析第一行:

+CMT  表示新短信指示代码格式为收到短消息立即显示;若+CMTI则指示收到短消息存储到存储器里;是否直接显示是通过CNMI设置的;

24     表示PDU数据中短信中心号码后面的字符串长度/2,即240D91683157121468F0000860800331220000044F60597D的长度除以2;(48)/2=24.

>>然后分析第二行,也就是分析接收到的PDU数据:

(1)08

信息中心号码的长度,将91683108200205F0的长度除2,格式化成2位的16进制字符串所得

也就是 16/2=8(10)=0x08(16).

(2)91 //短信中心号码类型

短信中心号码类型'91是TON/NPI遵守International/E.164标准,指在号码前需加‘+’号

       91—10010001 //每一位数字转换为4位二进制数

            1  固定为1

001 //数值类型(Type of Number):000—未知,001—国际,010—国内,111—留作扩展;
           0001//号码鉴别(Numbering plan identification):0000—未知,0001—ISDN/电话号码(E.164/E.163),1111—留作扩展;

image

image

 

(3)683108200205F0 //短信中心号码,转换方法:

短信中心号码: +8613800220500

转换方法:如果号码前面有+号,去掉“+”号→如果没有“86”,在号码前加上“86”:

86 13 80 02 20 50 0→看看现在号码的长度是否为偶数,如果不是,在号码后面加上“F”:8613800220500F→将奇数位和偶数位交换,得到结果:683108200205F0

(4)24 //TPDU头字节

PS.继续讲解前,先标志下数据,好区分点.

0D91683157121468F0000860800331220000044F60597D

(5)0D

发送源号码长度,8613752141860的长度格式化为2位16进制所得

也就是13(10)=0x0D(16)

(6)91 //发送源号码类型

(7)683157121468F0 //发送源号码

13752141860-(加86)-->8613752141860--(判断奇偶)—> 86 13 75 21 41 86 0F

然后奇偶互换,683157121468F0

(8)00 //协议标识 TP—PID

(9)08 //数据编码方案,08:中文编码,00为英文或数字,Bit No.7与Bit No.6

           00--00000000 //每一位转换为4位二进制数

           00    //Bit No.7与Bit No.6: 00—如下面定义的分配Bit No.0—Bit No.5;01—参见GSM03.40协议标识完全定义;10—预留;11—为服务中心(SC)特殊用途分配Bit No.0—Bit No.5。 一般将这两位置为00。
          0     //Bit No.5:0—不使用远程网络,只是短消息设备之间的协议;1—使用远程网络。
           00000 //Bit No.0—Bits No.4:00000—隐含;00001—电传;00010—group 3 telefax;00100—语音;00101—欧洲无线信息系统(ERMES);00110—国内系统;10001—任何基于X.400的公用信息处理系统;10010—Email。

(10)608003312200 //日期时间,奇偶互换:06-08-30 13:22:00,

(11)00 //时区

(12)04 //用户数据长度TP-UDL(TP-User-Data-Length),4F60597D的长度除2格式化为2位16进制数所得

(13) 4F60597D //”你好”的UNICODE码,同样提供一个DELPHI下的解码函数:

 

2、接收纯英文或数字

上面例子中接收到的是中文短信“你好”,那么当接收到的短信是纯中文或者数字的时候又如何解码呢?

例如接收到13752141860发送的英文短信“hello”,手机接收到的字符串为:

+CMT: ,24

0891683108200205F0240D91683157121468F00000608003416270000461F1980C

简单复习下:

  • +CMT  表示新短信指示代码格式为收到短消息立即显示
  • 24     表示PDU数据中短信中心号码,683108200205F0后面的字符串长度/2,
  • 08      将91683108200205F0的长度除2,格16进制字符串所得 16/2=8(10)=0x08(16).
  • 91     短信中心号码类型
  • 683108200205F0  短信中心号码
  • 24    TPDU头字节
  • 0D91683157121468F00000608003416270000461F1980C
  • 0D  发送源号码长度,8613752141860,16进制所得 13(10)=0x0D(16)
  • 91 发送源号码类型
  • 683157121468F0 发送源号码
  • 00 协议标识 TP—PID接下的的00:先前提到了这两位表示数据编码方案,08为中文编码,00为英文或数字,当手机发送普通的ASCII字符即使用7-bit编码方式,说明我们接收到的短信是英文或者数字格式的,而不是中文UNICODE码,比较一下:

0D91683157121468F00000608003416270000461F1980C (文本短信)

0D91683157121468F0000860800331220000044F60597D (中文短信)

继续复习:

  • 608003416270    日期时间,奇偶互换
  • 00                           时区
  • 04                             用户数据长度 61F1980C 的长度除2,16进制数为8(10)=04(16)
  • 61F1980C            ”你好”的7-bit码

 

根据前面的00我们知道这是一段7-bit码,而不再是UNICODE码,7-bit的解码过程很复杂,大体过程是:

将源数据每7个字节分为一组,解码成8个字符。基本自然是:将第n个字节左移n位,再加上前一字节的剩余数据,即第(n-1)个字节右移(8-n)位的数值,屏幕最高位,即得到一目标字符数据,n=0…6。第7个字节右移1位就得到解码后的第8个字符数据。

  以上改编自http://blog.csdn.net/god2469/article/details/6294070

3.GMS 03.38

image

Foreword 前言.................................................................................................................................5
1 Scope 范围.....................................................................................................................................7
2 Normative references标准的参考....................................................................................................7
3 Definitions and abbreviations .定义与缩写....................................................................7
4 SMS Data Coding Scheme 短消息数据编码方案...............................................................8
5 Cell Broadcast Data Coding Scheme蜂窝广播数据编码方案..................................9
6 Individual parameters 单独的参数.....................................10
   6.1 General principles 通用的规则.............................................................................10
      6.1.1 General notes.通用注释.........................................................................10
      6.1.2 Character packing字符封包.........................................................................11
            6.1.2.1 SMS Point-to-Point Packing 短消息点对点包装................................11
                6.1.2.1.1 Packing of 7-bit characters ............11
            6.1.2.2 SMS Cell Broadcast Packing...............................................12
              6.1.2.2.1 Packing of 7-bit characters ...................12
   6.2 Alphabet tables字母表..............................................................................12
   6.2.1 Default alphabet .默认字母表...........................................................................13
History历史............................................................................................................................................14

posted @ 2013-04-06 01:56  淅沥枫  阅读(1608)  评论(0编辑  收藏  举报