鞍山市沛芝堂药房电话:WapPush编码,wappush分包与长短信等(转)

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 22:29:38
WapPush编码标签: 杂谈
分类: MSN搬家
Wappush编码续--分包研究
(2009-12-08 10:09:30)转载
标签: 杂谈
分类: MSN搬家
长短信及wappush分包实施
(2010-05-13 18:29:50)转载
标签: 杂谈
分类: MSN搬家
20110402索引整理,便于各位查阅.
1.WapPush编码
2.Wappush编码续--分包研究
3.长短信及wappush分包实施
---------------------------------------------------------
均为基于cmpp协议实现,其他短信协议应该大同小异。
长短信
长短信息:是指超过70个汉字,140个字节的信息内容,手机接收后做为一条短信展示(大部分手机支持)
方式为指定Msg_Fmt为0x08(UCS2) ;TP_pId 为 0 ;TP_udhi 为 1
Msg_Content 包含6字节或7字节的长短信包头,剩余部分为USC2(注1)编码短信内容。
Pk_total及Pk_number无需特别指定,都为1即可。
包头规则如下(网络资料):
6位协议头格式:05 00 03 XX MM NN
byte 1 : 05, 表示剩余协议头的长度
byte 2 : 00, 这个值在GSM 03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为1(格式中的XX值)。
byte 3 : 03, 这个值表示剩下短信标识的长度
byte 4 : XX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯
一并不是很 重要。
byte 5 : MM, 这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
byte 6 : NN, 这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
例如:05 00 03 39 02 01
7位的协议头格式:06 08 04 XX XX MM NN
byte 1 : 06, 表示剩余协议头的长度
byte 2 : 08, 这个值在GSM 03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为2(格式中的XX值)。
byte 3 : 04, 这个值表示剩下短信标识的长度
byte 4-5 : XX XX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯一并不是很重要。
byte 6 : MM, 这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
byte 7 : NN, 这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
例如:06 08 04 00 39 02 01
实现方式:
实现方式比较简单,将短信内容转码后按 总长度/140-包头长度 ,并拼入包头信息,来拼接各个长短信包下发给网关。
说说网上资料没有的部分,每个Submit请求都会有单独的SubmitResp以及对应的状态报告。
所以处理时,需要将一组长短信包同一处理,即全部成功才认为成功,否则丢弃该长短信同组其他包,并返回应用失败。
上行时需要收完所有包再转码后上送给应用处理(注2),也需要注意同组包同一处理。
注1:USC2转码需要注意在linux环境wchar_t占用4字节,非2字节。aix与windows为2字节。
所以转码时最好统一用unsigned short任何平台都是2字节,不会出错。
注2:多通道连接时,长短信上行有几率会从不同的通道上来,这时就需要有一个统一管理的模块进行合并组包(取决与各通道是否独立)。
WapPush分包
wappush部分多包与长短信类似。实现方式也类似。
方式为指定Msg_Fmt为0x04(二进制) ;TP_pId 为 0 ;TP_udhi 为 1
Msg_Content 为7字节(单包)或12字节(多包)WDP,及WSP + WBXML内容,需要注意多包时是把WSP + WBXML的内容拆分到每个包内。这部分实现与前面那篇"Wappush编码续--分包研究"的分析结果一致。
Pk_total及Pk_number无需特别指定,都为1即可。
实现方式:
因为UTF8是1至4字节编码(特指UNICODE转换情况下。UTF8的完全编码范围是1-6字节。),如果按照内容拆分计算会负责一点,如直接按长度拆可能会把一个中文的UTF8编码拆断。实现确比预想的简单,测试中发现直接按字节拆分工作也正常,猜想是手机接收到完整编码后才做拼接转码显示。
具体方式,按协议完成WSP+WBXML编转码,总长度/140-包头长度(WDP),然后拼入WDP包头信息,依次拼接各wappush分包下发。
同样每包均会有resp及对应状态报告。以及同组分包同一处理。
另UTF8转GB编码的时候用GB18030。GB2312只有6000多个汉字,生僻一点的汉字就转码失败。
20110402索引整理,便于各位查阅.
1.WapPush编码
2.Wappush编码续--分包研究
3.长短信及wappush分包实施
---------------------------------------------------------------------------
分包情况暂未验证,只是网上资料研究与手上多包字节流分析。
前面部分见http://blog.sina.com.cn/s/blog_71e37eb20100mh81.html
分包方法:
1.分包每包 140字节
2. 分包的后续包没有wsp信息。只有第一个包有
第一包 wdp(填充多包标志,包总数,包序号) wsp con1
第二包 wdp(填充多包标志,包总数,包序号) con2
....
...
最后包 wdp 填充多包标志,包总数,包序号) conN 结束符
处理步骤:
1.需要算出单包协议信息占用字节数。比较URL及内容与之总数是否会超出 140
算出WBXML部分信息长度。如果加上单包头超长(140)则分包。第一次拆出包含wdp,wsp的剩余字节长度。后续
只需要拆出wdp外剩余长度。
返回一个大buffer,由应用按140分解发送。
2.超出则分包。
3.注意几个短信序列的生成。
-------------------------------------以下内容中的部分资料来源于网络--------------------------------------------------------------
根据OTA的规范,WDP的一般格式是“0B0504C34FC002000304xxyy”,其中xx就是整个数据包的总片断数目,而yy
表示当前片断是第几个片断。举个例子,一个简单的bookmark全部放在一个sms中这样xx=01,yy=01。
下面是每个byte的意思:
# 0B | User-Data-Header (UDHL) Length = 11 bytes
# 05 | UDH IE identifier: Port numbers
# 04 | UDH port number IE length
# C3 | Destination port (high)
# 4F | Destination port (low)
# C0 | Originating port (high)
# 02 | Originating port (low)
# 00 | UDH IE identifier: SAR (固定值)
# 03 | UDH SAR IE length      (后续长度)
# 01 | Datagram ref no.       (短信序列,用于区分不同短信。如果序列相同的分包短信,手机无法区
分)
#
# Two variable bytes, intentionally missing from WDP header, user must
# calculate and add at send time.
#
# xx | Total number of segments in datagram
# yy | Segment count
WSP部分类似HTTP头域部分,指定一些头域信息。基本上就是Content-Type和Content-Length,PDU类型及流
水号
WSP:01060603AE81EA8D4A
# 01    | Transaction ID /
# 06    | PDU type (push)
# 06    | Header length (content type headers)
# 03 AE | Content-type: application/vnd.wap.sic
# 81 EA | charset=utf-8
# 8D 4A | content-length: 74 (wbxml部分长度)
SI/SL是用WBXML来描述,WBXML其实就是压缩后的XML,例如:用0x0C表示“href="http://"”,首先必须有个
xml的头"01016A00"
# 01 | Version | WBXML 1.1
# 01 | Unknown public identifier |
# 6A | Charset | UTF-8
# 00 | String table length |
分段发送的
例如  URL:wap.gd.monternet.com/?userType=B&serviceID=04020028提示信息:神秘激情地带,江湖儿女情长神
秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长
第一包:
0B05040B8423F0
0003550201
55060403AE81EA02056A0045C60C037761702E67642E6D6F6E74657
26E65742E636F6D2F3F75736572547970653D42267365727669636549443D303430323030323800
070103
E7A59EE7A798E6BF80E68385E59CB0E5B8A62CE6B19FE6B996E584BFE5A5B3E68385E995BF
E7A59EE7A798E6BF80E68385E59CB0E5B8A62C
第二包:
0B05040B8423F0
0003550202
E6B19FE6B996E584BFE5A5B3E68385E995BF
E7A59EE7A798E6BF80E68385E59CB0E5B8A62CE6B19FE6B996E584BFE5A5B3E68385E995BF000101 ,解释可参考WDP
WSP,我就不具体说了
E7 A5 9E E7 A7 98 E6 BF 80 E6 83  8...绁炵婵.鎯
01BDF97A  85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5  呭湴甯.,姹熸箹.
01BDF989  84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7  効濂虫儏闀跨.
01BDF998  A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C  婵.鎯呭湴甯.,
01BDF9A7  E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85  姹熸箹鍎垮コ鎯.
01BDF9B6  E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85  闀跨绉樻縺鎯.
01BDF9C5  E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84  鍦板甫,姹熸箹鍎
01BDF9D4  BF E5 A5 B3 E6 83 85 E9 95 BF 00 01 01
0b 05 04 0b 84 23 f0
多包时WDP多5个字节信息
00(固定) 03(后续长度) 01(短信序列区分短信用) 02(包总数) 01(包序号)
01 06 0a 03 ae 81 ea af 82 8d 31 b4  84 01 05 6a  00 45 c6 0b
03 77 61 70  2e 67 64 2e  6d 6f 6e 74  65 72 6e 65
74 2e 63 6f  6d 2f 3f 75  73 65 72 54  79 70 65 3d
42 26 73 65  72 76 69 63  65 49 44 3d  30 34 30 32
30 30 32 38  00 08 01 03
e7 a5 9e e7  a7 98 e6 bf
80 e6 83 85  e5 9c b0 e5  b8 a6 2c e6  b1 9f e6 b9
96 e5 84 bf  e5 a5 b3 e6  83 85 e9 95  bf e7 a5 9e
e7 a7 98 e6  bf 80 e6 83  85 e5 9c b0  0b 05 04 0b
84 23 f0 00  03 01 02 02  e5 b8 a6 2c  e6 b1 9f e6
b9 96 e5 84  bf e5 a5 b3  e6 83 85 e9  95 bf e7 a5
9e e7 a7 98  e6 bf 80 e6  83 85 e5 9c  b0 e5 b8 a6
2c e6 b1 9f  e6 b9 96 e5  84 bf e5 a5  b3 e6 83 85
e9 95 bf 00  01 01
0B是头的总长度
05040B8423F0是固定的,表示接下来是一个WAP PUSH
分包的关键是0003550201,对应GSM 03.40里9.2.3.24.1,00表示是Concatenated Short Messages,03是长度,
55是reference number,楼主在这儿固定编码会有问题的,
如果同时下发两条这样的多包短信给同一个手机,手机就区分不开了,02表示分成2个短信发送,01是当前包的
序号。
一个扩展包wappush包是这么构成的
3.
20110402索引整理,便于各位查阅.
1.WapPush编码
2.Wappush编码续--分包研究
3.长短信及wappush分包实施
-------------------------------------------------------------------------------------------
网上找了些WapPush编码资料,大部分不怎么靠谱。
贴个比较靠谱的link:http://hi.baidu.com/pisvia/blog/item/38e2b335dd97c78ea71e122b.html
总结一下目前为止查阅资料的收获。
公司的应用环境是通过CMPP协议,将编码好的WapPush数据发送到手机。以下内容可能仅局限于此.
WapPush编码有三个组成部分,WDP,WSP,WBXML..网上资料对WBXML的描述比较多,对WDP及WSP部分描述比较少。
WDP及WSP协议内容也比较庞杂,此处讨论的是以最少字段实现WapPush,WDP及WSP协议具体内容见wap-230-wsp-20010705-a及
wap-259-wdp-20010614-a
看一个例子
一个完整的字节流为:
0605040B8423F081060603AE81EA8D4A02056A0045C6080C037761702E73696E612E636F6D00010374657374E6B58BE8AF95000101
其中WDP:0605040B8423F0
# 06      | User-Data-Header (UDHL) Length = 6 bytes
# 05      | UDH IE identifier: Port numbers
# 04      | UDH port number IE length
# 0B 84 | Destination port
# 23 F0 | Originating port
这是单包情况下,多包情况需要额外5字节分包信息,相应长度字段0x06->0x0B
下面是多出来的5字节内容
# 00 | UDH IE identifier: SAR
# 03 | UDH SAR IE length
# 04 | Datagram ref no.
# xx | Total number of segments in datagram
# yy | Segment count
WSP部分类似HTTP头域部分,指定一些头域信息。基本上就是Content-Type和Content-Length,PDU类型及流水号
WSP:01060603AE81EA8D4A
# 01      | Transaction ID (流水号)
# 06      | PDU type           (push)
# 06      | Header length (头域部分长度,不包括PDU类型及流水号)
# 03 AE | Content-type: application/vnd.wap.sic   (03表示头域Content-type,AE表示头域值application/vnd.wap.sic   下面2个类似)
# 81 EA | charset=utf-8
# 8D 4A | content-length: 74 (wbxml部分长度)
然后就是最后的WBXML部分
WBXML部分基本上是一样的差异不大,网上WapPush讲的最多的也是这一部分,这里就不详细描述了。
WBXML:02056A0045C6080C037761702E73696E612E636F6D00010374657374E6B58BE8AF95000101
测试中的问题,WSP有个不定长整形数据(uintvar),就是超过8bit的数值进行拆分,低7位存放数据,高位补1表示有后续。最大32bit。
比较诡异的是。对协议看有些字段定义的是uintvar,但是不符合规范的填充也是允许.这也是很多资料WSP第一个字段为0x81(0x01高位补1)的原因。
另一个比较诡异的地方是WSP部分content-length填充的长度实际为WBXML字节数×2...不知道为啥.但是工作正常.
这个地方网上很多资料也是填的数值不一,有填字节数的,有字节数以uintvar方式填充的。
多包情况没有试,看资料是将WBXML部分拆开,如果这样不知道手机收到的时候是所有包收全展示,还是收一个展示一部分(数据不全,多半不会是这种方式)。
目前为止就是这样,以后有新的发现再补充...
补完计划一:
这两天把代码移植到AIX..记录一下其中的问题.准确的说不算wappush的问题,而是移植过程中的问题。
1.UTF8与GB编码转换,AIX和Linux下用iconv转换,本来想用wcstombs和wctomb替换MultiByteToWideChar和WideCharToMultiByte;但是发现死活只能转到UCS2..后来上网查阅资料发现Aix和Linux下可以用iconv的库来转换很方便,而且还有对应windows的库 =-=.不过windows部分的转换代码写好了就懒得换了。iconv的使用中还有一个问题,就是在调用iconv_open的时候指定源和目标字符集的时候要用大写“UTF8,GB2312”,奇怪的是小写Linux没问题,Aix会转换失败,改成大写就都可以跑。这个问题当时卡了很久,比较崩溃。还有个地方需要注意iconv的参数outlen输入的时候需要是outbuf的实际长度,执行完后outlen的值会被修改为outbuf的剩余长度。
2.字符串比较函数
windows平台。
函数: stricmp、strnicmp.
Linux&Aix平台。
函数: strcasecmp、strncasecmp.
3.网络字节序的问题
2.