文档库

最新最全的文档下载
当前位置:文档库 > 短信息收发有关的规范主要包括GSM 03

短信息收发有关的规范主要包括GSM 03

短信息收发有关的规范主要包括GSM 03.38、GSM 03.40和GSM 07.05。前二者着重描述SMS的技术实现(含编码方式),后者则规定了SMS的DTE-DCE接口标准(AT 命令集)。短信息的收发共有三钟方式:Block方式, Text方式和PDU方式。Block方式目前很少用;Text方式是纯文本方式,可使用不同的字符集,从技术上说也可用于发送中文短信息,但国内手机基本上不支持,主要用于欧美地区;PDU方式被所有手机支持,可以使用任何字符集,这也是手机默认的编码方式。

PDU串表面上是一串ASCII码,由‘ 0’-‘9’、‘A’-‘F’这些数字和字母组成。它们是8位字节的十六进制数。PDU串不仅包含可显示的消息本身,还包含很多其它信息,如SMS服务中心号码、目标号码、编码方式等。PDU方式下可以采用三种编码发送短信息:7位编码、8位编码和16位(UCS2)编码。

在GSM的介绍中,PDU由两部分组成:短信息中心地址(SMSC)和传输协议数据单元(Transfer Protocol Data Unit)。下面以实例介绍PDU数据格式。短信中心号码为:+8613800546500,目标地址为:138********,短信内容为:中国移动。短信编码为:0891683108506405F011500B813168934922F60008FF084E2D56FD79FB52A8。其中,下划线部分为SMSC部分,剩余的为TPDU部分。红色是编码后的短信中心号码,绿色是编码后的目标号码,蓝色是编码后的信息内容。

1 SMSC的格式

短信息收发有关的规范主要包括GSM 03

1.1地址长度

一个字节,表示地址类型和地址值所占的字节数。

1.2地址类型

一个字节,如下定义:

短信息收发有关的规范主要包括GSM 03

a)号码类型(TON)

短信息收发有关的规范主要包括GSM 03

1-号码前没有其他信息,如同正常拨号的号码。

2-使用国际号码格式,如+8613800546500。

3-普通格式,如138********。

b)编码标识(NPI,当TON=000,001,010)

短信息收发有关的规范主要包括GSM 03

一般情况下,地址类型设置为十六进制的“91”。

如果地址长度设置为0,则SMSC地址使用+CSCA设置。这种情况下,SMSC的地址类型字节就不应再出现在PDU中,也就是说,TPDU紧随地址长度字节。

例子中“0891683108506405F0”表示的就是SMSC。“08”表示地址类型和地址值共占8个字节。“91”表示地址类型,采用的是国际电话号码格式。剩余的7个字节是地址值。将数据中心的地址从左至右两个一组掉换位置看作一个十六进制数作为一个字节组成地址值(如果号码个数为奇数,则在右边以‘F’补足凑成偶数后再换位)。

2TPDU的格式

短信息收发有关的规范主要包括GSM 03

2.1 First-Octet

短信息收发有关的规范主要包括GSM 03

上面给出的是最简单的一种情况,具体设置参考GSM03.40(9.2.3小节)。a)TP-MTI(Message Type Indicator)

发送短信息时需要将位0和位1设置为1和0。

b)TP-RD(Reject Duplicates)

位2设置位0表示信息中心能够接收从同一个地址发送的具有相同TP-DA 和TP-MR的短信息。

c)TP-VPF(Validity Period Format)

短信息的有效期,用于指示TP-VP。

00表示无有效期,TP-VP设置为00。

10表示相对格式,TP-VP占用1字节。

01表示增加格式,TP-VP占用7字节。

11表示绝对格式,TP-VP占用7字节。

其余设置为非法设置。相对格式下的有效时间计算公式为:

短信息收发有关的规范主要包括GSM 03

d)TP-SRR(Status Report Request)

简单起见,不要求发送报告则设置为0。

e)TP-UDHI(User Data Header Indicator)

PDU方式没有在信息内增加任何头信息,因此设置为0。

f)TP-RP(Reply Path)

未定义回复路径时设置为1。

2.2 TP-MR(Message Reference)

发送消息的引用值。每发送一条短信息,MR值就自动加1,最大为255。使用+CMGS发送信息之后返回的整数既是MR。

信息中心可能丢弃那些与已经接收到的信息出于同一地址且TP-MR值相同的新信息。可以通过设置First-Octet的TP-RD解决此问题。

2.3 TP-DA(Destination Address)

短信息的目标地址。格式与SMSC格式相同。区别在于目标地址的长度表示的是目标地址的个数而不是其所占用的字节数。

2.4 TP-PID(Protocol Identifier)

短信息收发有关的规范主要包括GSM 03

信息中心可能丢弃那些包含保留值或者值不在定义范围内的新信息。

位5设置为0表示点对点方式。简单起见,将该字节设置为“00”。

2.5 TP-DCS(Data Coding Schema)

数据解码方式。一般数据解码时将6、7位设置为0。第5位设置为1表示使用了GSM标准的压缩算法进行了压缩。第4位设置为1说明第1和0位表示信息的类别。第3、2位表示使用哪知字母表。

短信息收发有关的规范主要包括GSM 03

该字节设置位“00”表示使用7位编码,设置为“02”使用8位编码,设置为“08”使用UCS2编码。

2.5 TP-VP(Validy Period)

简单起见,只考虑PDU方式的SMS,可以设置为“00”。

2.5 TP-UDL(User Data Length)

用户数据最多使用140个字节,对于PDU方式的7位编码,一次最多能够发送160(140*8/7)个字符,8位编码为140个字符,UCS2编码为70个字符(一个字符占2个字节)。

在7位编码时,UDL表示的是原始字符数,8位编码为字节数,UCS2编码也为字节数,即原始字符数的2倍。

对0891683108506405F011500B 813168934922F60008FF084E2D56FD79FB52A8解码的意义如下:

短信息收发有关的规范主要包括GSM 03

TP-UD的最大长度为140个字节,由此可以计算出在不同的编码方式下所能发送的最大字符的数量。7位编码方式下,最大字符数为160(140×8/7);8位编码方式下为140;UCS2编码方式下为70(140/2)。这里,将一个英文字母和一个汉字都视为一个字符。

3 TP-UD编码原理和程序实现

7位编码用于发送普通的ASCII字符,它将一串7位的字符(最高位为0)编码成8位的数据,每8个字符可“压缩”成7个;8位编码通常用于发送数据信息,比如图片和铃声等;而UCS2编码用于发送Unicode字符。

3.1适用于ASCII字符的7位编码

7位编码将一串7位字符编码成8位字符数据。“Hello!”编码的过程如下:

短信息收发有关的规范主要包括GSM 03

7位编码的字符集与ANSI标准字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、阿拉伯数字和常用符号的位置两者是一样的。上面的算法编码纯英文短信息,一般情况应该是够用了。如果是法语、德语、西班牙语等,含有“?/FONT>”、“é”这一类字符,则要按上面编码的输出去查表,请参阅GSM 03.38的规定。

3.2适用于Unicode字符的UCS2(16位)编码

UCS2编码是将每个字符(1-2个字节)按照ISO/IEC10646的规定,转变为16位的Unicode字符。在Windows系统中,可以简单地调用API函数实现编码和解码。如果没有系统的支持,比如用单片机控制手机模块收发短消息,只好用查表法解决了

短信息收发有关的规范主要包括GSM 03

3.3编码实现

实现7位编码的Java代码实现如下:

public String encode(String src){

StringBuilder sb = new StringBuilder();//存放目标串

char[] cs = src.toCharArray(); //将字符串转换为字符数组

int iLeft = 0;//上一个字符剩余的部分

int iChar = 0;//当前字符应处理位的个数,即表2中每个源二进制数中带下划线数码的个数

int tmp = 0; //中间变量

int i = 0; //循环变量

while(i

if(iChar==0)

iLeft = cs[i]; //如果iChar为0,则先保存该值

else{

tmp = cs[i]<<(8 - iChar);//将当前值左移(8-iChar)位

tmp &= 0xff; //取低8位

tmp = tmp | iLeft; //并与上个值剩余的部分做逻辑或运算

sb.append(String.format("%02x", tmp));

iLeft = cs[i]>>iChar; //当前值剩余的部分

}

i++;

iChar++;

if(iChar==8){

iChar = 0;

}

}

//处理余下的部分

if(iLeft!=0)

sb.append(String.format("%02x", iLeft));

return sb.toString().toUpperCase();

}

实现UCS2编码的Java代码如下:

public String encode(String src){

StringBuilder sb = new StringBuilder(); //存放目标串

char[] cs = src.toCharArray(); //将字符串转换为字符数组

int tmp = 0;

for(int i=0;i

tmp = cs[i] >> 8; //先编码高8位

sb.append(String.format("%02x", tmp));

tmp = cs[i] & 0xff; //再编码低8位

sb.append(String.format("%02x", tmp));

}

return sb.toString().toUpperCase();

}

3.4解码实现

实现7位解码的Java代码实现如下:

public String decode(String src) {

StringBuilder sb = new StringBuilder();

int[] cs = new int[src.length() / 2];

//将字符串形式的十六进制数转换位整数

for(int i=0;i

cs[i] = Integer.parseInt(src.substring(i * 2, i * 2 + 2), 16);

int iLeft = 0;//上一个字符剩余的部分

int iChar = 0;//当前字符应处理位的个数

int tmp = 0;//中间变量

int i = 0;//循环变量

while(i

tmp = ((cs[i]<

sb.append((char)tmp);

iLeft = cs[i]>>(7 - iChar);

i++;

iChar++;

if(iChar==7){

sb.append((char)iLeft);

iLeft = 0;

iChar = 0;

}

}

if(iLeft!=0)

sb.append((char)iLeft);

return sb.toString();

}

实现UCS2解码的Java代码如下:

public String decode(String src){

StringBuilder sb = new StringBuilder();

int tmp = 0;

for(int i=0;i

tmp = Integer.parseInt(src.substring(i * 4, (i + 1) * 4), 16);

sb.append((char)tmp);

}

return sb.toString();

}