三 MMS PDU结构
MMS PDU(Protocol Data Unit,协议数据单元)由MMS头和MMS消息体组成,MMS头由多个域名和域值组成,由客户端指定, MMS头里面的一些域可以被MMS Proxy-Replay修改或补充,MMS Proxy-Replay使用这些头域信息生成MM通知以及构造接收MM PDU中的相关头域,连同消息实体一同送往接收方。消息体跟在MMS头之后,大多数MMS PDU只含有MMS头,它们起到建立和维持通信的作用,只有在M-Send.req和M-Retrieve.conf PDU中才有消息体。
3.1 MMS Header
MMS PDU和HTTP PDU极为类似,但要简单一些。一个MMS PDU对应一种消息格式。不同类型的MMS PDU有不同的MMS Header 。MMS Header根据WAP-209协议和RFC2387的规定,由一系列的域组成,这些域定义了PDU的各种属性,包括PDU类型,版本号,接受方,发送方,主题,发送时间等。MMS Header中的域分为可选项和必选项,根据PDU的类型不同而不同。
常见的PDU的类型有:
发送请求: M-send.req
发送确认: M-send.conf
彩信通知: M-notification.ind
通知回应: M-notifyresp.ind
获取彩信回应: M-retrieve.conf
接收确认: M-acknowledge.ind
彩信回执: M-delivery.ind
MMS Header后面立即接的就是Message Body。根据MMS Body组装的是否有序(是否有位置控制信息,有显示先后顺序),MMS消息体的组装方式分为:
application/vnd.wap.multipart.mixed方式
所有的消息内容混合在一起,没有时间上的顺序,内容怎么显示由客户端的显示控制策略来决定。
application/vnd.wap.multipart.related方式
各消息内容之间有一定关系,该关系可能是显示的时间上的先后,显示的位置等。这样在终端显示该消息的时候,就可以以幻灯片的方式显示一系列消息,使得该MM的显示更加趣味化。
在application/vnd.wap.multipart.related方式的MMS PDU之中,含有显示控制部分“presentation”,而application/vnd.wap.multipart.mixed不含有该部分。
“presentation”是 MMS 中一个特殊的消息内容(part),它决定了其他消息内容的显示控制信息。实现“presentation”这个消息内容的语言,就是SMIL (Synchronized Multimedia Integration Language)。SMIL是一种简单的标记性语言,内容书写格式和HTML类似。“presentation”正是用SMIL来表示这些多媒体元素显示的次序,位置,开始播放的时间,结束时间。下面给出一个SMIL结构的例子,其中注释-->是注释部分:
例子(包含两帧,每帧包括一张图片和一段文本)
<--!以smil开始-->
<--!header smil 头-->
<--!显示的底板控制-->
<--!显示的内容定义-->
<--!显示内容控制-->
<--!第一帧, 持续时间为20秒,显示文件名称是videofilename.3gp -->
<--!第二帧开始,持续2秒-->
<--!第二帧结束-->
<--!smil结束-->
看见了吧,和HTML语言差不多。SMIL写好了以后,在windows平台上,另存为.smil文件以后,可以用支持smil格式的视频播放器打开,前提是smil文件和里面引用到的多媒体元素放在同一个目录里面。
前面说过,同音频,视频,文本及图片文件这些多媒体元素一样,“presentation”也是一个消息part,它们在Message Body中的排列顺序可以是任意的。还记得前面说过的MMS Header最后一个域Content Type吧,当MM内容包含SMIL格式的表现层时,content type必须为application/vnd.wap.multipart.related,否则使用application/vnd.wap.multipart.mixed。
客户端怎么知道从哪个部分开始显示呢?当存在多媒体对象和显示控制信息时,即存在“presentation”部分,如果在Content Type中存在Start参数,“presentation”如果不是消息体的第一个part,则必须用start参数指出其所在位置;当不存在Start参数时,“presentation”部分应该排列在第一位的位置上,即紧接在MMS Header后面;当根本不存在“presentation”部分时,如何显示则由客户端的显示策略来决定。
3.3 MMS的封装(Encapsulation)
对于使用SMIL语言描述的MMS,在通过无线网络发送的时候,我们必须通过一种方式把SMIL和附属的多媒体内容包装在一起,能够以一个unit(整体)的形式发送出去,以便SMIL文件各个部分内容的reference变得有效。
这个解决的办法就是MIME(Multipart Internet Mail Extensions)规范,这个规范的最初作用是在email的plain text的主体中加入不同的内容。比如说,发送带有附件的email,这个时候你就使用了MIME的规范。MIME负责把所有的独立的文本、图像、声音、视频内容以及SMIL文件本身捆绑在一起,用于告诉接受的终端这个MMS的内容是相互相关(related to one another)并且相互参考的(referenced to one another)。MIME规范(RFC2045-2049)和OMA制定的Multimedia Messaging Service Encapsulation Protocol规定的二进制码格式有一一对应的关系。
MIME封装示例
下面是根据RFC文档给出的MIME的封装示例:
Content-Type: application/vnd.wap.multipart.related; boundary="boundary-example"; type="application/smil" --boundary-example Content-Type: text/html; charset="US-ASCII" ... ... ... ... ... ... ... ... --boundary-example Content-Type: image/gif Content-ID: Content-Location: fiction1/fiction2 …………………..Gif data --boundary-example Content-Type: image/gif Content-ID: Content-Location: fiction1/fiction3 …………………..Gif data --boundary-example-- |
Content-type
位于信息头部的content-type用于通知接收的终端消息的各个不同部分的内容是相互关联的、并且可能是相互索引的(refer to one another)。而在信息体里面的Content-Type用来指定该部分内容的数据类型。
Boundary
Boundary参数指定分隔符,用于分割各个不同的消息part。分隔符以两个短杠“-”开头。第一个部分是一个html类型的消息,这里只是取得了相关的部分。第二和第三部分省略了实际的images图像的实体。
Content-Location 和 Content-ID
在HTML文本部分我们可以看到,我们可以利用两种方式来索引消息内容的不同部分。这两种不同的方式是 content-ID 和 content–Location。这两个域的属性应该是唯一的,以便区分不同的数据块。
如果一部分的消息体想通过content-ID指向(refer to)另外一部分的消息体,可以使用“CID”。关于MIME的部分的信息可以参考RFC文档(RFC2387和RFC2357)。
Multipart data
Message Body的结构正如上面MIME的封装结构。在实际的MMS PDU中,为了压缩数据,每个域的域名用固定的字节编码,并且去掉了分隔符。Message Body多媒体数据(Multipart,对应于多媒体文件数据)的编码结构如图12所示:
图12 Application/vnd.wap.multipart 的格式
图13 uintvar变量结构
整个uintvar变量的长度少于5 byte因此,uintvar可以表示无符号整型数的表示范围(0~32bit)。实际使用过程中,先把要编码的数值的二进制从最低位按每7位一组分好,然后把它们填到PayLoad域中,高位不足的补零,举例说明
数值0x8715(1000 0111 1010 0101)编码成uintvar类型如下所示:
图14 0x8715的uintvar表示
注意,如果高7位正好是7个零的话,不能编码成0x80,而是略去该字节。
Entries域结构如表2所示:
表2 Entries结构
HeaderLen指示ContentType域和Header域的总长度,是一个Uintvar变量,DataLen指示后面Data域的长度,在这里指的是一块多媒体数据的字节数,ContentType域用来表示后面的数据块是什么类型的数据(如txt文本,jpeg图片,还是vidoe数据流),已经注册过的类型编码值可见附录A。Header域指定该块数据的其它信息,其中最重要的是Content Location和Content ID值,因此,在Message Body部分,Header域是不能省略的。Content Location和Content ID值通常是多媒体数据的文件名,Content Location域以单引号“””开始,后面一对<>里面包含文件名,Content ID域则直接就是一对<>里面包含文件名,关于这两个域的格式可参考MIME 的Part one,该部分在rfc2045里面。接着Header的是Data域,它的长度由DataLen指定,现在应该明白为什么MMS中的Message Body的MIME封装中不需要分隔符了吧,每个域的长度都是指定的。
一个Entries域的后面紧接着另外一个Entries域(如果有的话),直到整个的MMS PDU尾,smil部分也是一个Entries。
3.4 MMS PDU封装示例
下面举一个实际的MMS PDU编码示例来结束本节,该MMS是multipart/related类型。
实际发送MMS PDU完整的十六进制编码如下,为了节省篇幅,用“……”代替多媒体的具体数据:
8c 80 98 33 36 35 38 32 34 00 8d 92 89 1a 80 2b
38 36 31 33 34 36 39 30 37 32 34 30 34 2f 54 59
50 45 3d 50 4c 4d 4e 00 97 2b 38 36 31 35 38 37
34 32 38 39 37 36 36 2f 54 59 50 45 3d 50 4c 4d
4e 00 96 62 69 67 20 4d 4d 53 00 84 1f 1f b3 8a
3c 62 69 67 2e 73 6d 69 6c 3e 00 89 61 70 70 6c
69 63 61 74 69 6f 6e 2f 73 6d 69 6c 00 05 28 83
7c 61 70 70 6c 69 63 61 74 69 6f 6e 2f 73 6d 69
6c 00 c0 22 3c 62 69 67 2e 73 6d 69 6c 3e 00 8e
62 69 67 2e 73 6d 69 6c 00 3c 73 6d 69 6c 3e 0d
…………………………………………………………….
………………….22 b7 63 9e c0 22 3c 6c 69 6e 6d
65 69 6d 65 69 2e 6a 70 67 3e 00 8e 6c 69 6e 6d
65 69 6d 65 69 2e 6a 70 67 00 ff d8 ff e0………
………………………………………………… 1e d9 26
9d c0 22 3c 6c 6f 67 6f 5f 63 6e 2e 67 69 66 3e
00 8e 6c 6f 67 6f 5f 63 6e 2e 67 69 66 00 47 49
…………… 18 e4 36 9d c0 22 3c 32 30 30 38 2e
67 69 66 3e 00 8e 32 30 30 38 2e 67 69 66 00 47
………………… 1c cd 15 9d c0 22 3c 6d 6f 6e 6b
65 79 2e 67 69 66 3e 00 8e 6d 6f 6e 6b 65 79 2e
67 69 66 00 47 49 46………………………………….
……………………………………………………………..
上面青绿色和深黄色部分是MMS PDU Header,灰色部分是Multipart Header,下面是对上面数据的分析:
8c 80
80:即0C的最高位置1 表示X-Mms-Message-Type;
8C:m-send-req类型的PDU
98 33 36 35 38 32 34 00
98:0x18+0x80 X-Mms-Transaction-ID
33 36 35 38 32 34 00:365824的ASCⅡ编码,最后以00结尾
8D 92
8D:X-Mms-Version 92: 1.2, 高4位9是主版本号1+8,低4位是次版本号2
89 1A 80 2B 38 36 31 33 34 36 39 30 37 32 34 30 34 2F 54 59 50 45 3D 50 4C 4D 4E 00
89:From ;
1A:From域的长度
80:值域的类型
2B~4E:+8613469072404/TYPE=PLMN,最后以00结尾
97 2B 38 36 31 35 38 37 34 32 38 39 37 36 36 2F 54 59 50 45 3D 50 4C 4D 4E 00
97:TO
2B~00:+8615874289766/TYPE=PLMN
96 62 69 67 20 4d 4d 53 00
96:Subject
62~53 00: big MMS 最后以00结尾
84 1f 1f b3 8a
3c 62 69 67 2e 73 6d 69 6c 3e 00 89 61 70 70 6c
69 63 61 74 69 6f 6e 2f 73 6d 69 6c 00
84:Content-Type
1f:指示后面一个字节是uintwar长度
1f:Content-Type的长度为31字节
b3: application/vnd.wap.multipart.related类型,对应于附录A里面的0x33+0x80;
8a:Start参数,见WSP协议Table 38. Well-Known Parameter Assignments,编码值加0x80。
3c~3e 00:
89: Type参数,见WSP Table38
61~6c 00:application/smil,以00结尾
05 28 83
7c 61 70 70 6c 69 63 61 74 69 6f 6e 2f 73 6d 69
6c 00 c0 22 3c 62 69 67 2e 73 6d 69 6c 3e 00 8e
62 69 67 2e 73 6d 69 6c 00
这是Multipart部分,
05:表示后面有5个part
28:HeaderLen,uintvar变量,表示后面的Content-Type和Header有40个字节长度
83 7c:DataLen,uintvar变量,后面数据部分的长度(即smil文件的长度),转化成十进制就是508,
61 70 70 6c 69 63 61 74 69 6f 6e 2f 73 6d 69 6c 00
Content Type域:application/smil的ASC2编码,最后以00结尾
c0 22~3e 00:c0表示这是Content ID域
22~3e是"
8e 62 69 67 2e 73 6d 69 6c 00
8e:表示这是Content Location域
62~6c 00:是big.smil的ASC2编码,最后以00结尾
紫罗兰颜色部分是big.smil文件的具体数据
紧接着的青色部分是linmeimei.jpg部分的Header和数据
22 b7 63 9e c0 22 3c 6c 69 6e 6d
65 69 6d 65 69 2e 6a 70 67 3e 00 8e 6c 69 6e 6d
65 69 6d 65 69 2e 6a 70 67 00 ff d8 ff e0
22:HeaderLen
B7 63:DataLen,uintvar变量
9e:Content Type域,附录A中的image/jpeg 编码0x1e+0x80
c0:Content ID域名编码
22~3e:Content ID值"
ff d8 ff e0……:jpg的具体数据
后面的不同颜色部分表示不同的Data part,结构和分析同上,这里不再赘述。
说明:Content Type域名编码可以参照WSP协议说明的Table 39. Header Field Name Assignments,Content Type参数编码可以参照WSP 协议文档的Table 38. Well-Known Parameter Assignments,这两个类型的编码值在MMS PDU中都要把最高位置1,编码值+0x80。其它Header域的编码可参照WSP说明的8.4 Header Encoding章节,每个Header域可以有多种表示方法,其中诸如From,To这些域的格式需要参照MIME相关文档。
排版的效果不太理想,在网页上排版不容易呀,好在还插入表格和字体颜色,转载请注明出处。
<------- 未完待续 ------->
MMS Header编码
图10 由系列域名和域值组成了的Header域
预定义的消息域名(Header Name)都由唯一的单字节编码,域值(Header Value)可能是一个单字节,也可能是多字节,这取决于Header Name。表1列出了一些常见的域名及其编码值:
表1 常见的域名及其编码
域名 |
说明 |
编码 |
Bcc |
密送者地址 |
0x01 |
Cc |
抄送者地址 |
0x02 |
Content-Location |
短息通知时用于存放MM所在服务器的Uri地址 |
0x03 |
Content-Type |
内容类型 |
0x04 |
Date |
日期 |
0x05 |
Delivery-Report |
状态报告(默认为不需要) |
0x06 |
Delivery-Time |
报告时间 |
0x07 |
Expiry |
有效期 |
0x08 |
From |
发送者信息 |
0x09 |
Message-Class |
信息的类型(个人、广告、信息还是自动) |
0x0A |
Message-ID |
信息ID,识别不同的彩信 |
0x0B |
Message-Type |
PDU类型 |
0x0C |
MMS-Version |
使用MMS协议的版本 |
0x0D |
Message-Size |
MM的大小 |
0x0E |
Priority |
优先级 |
0x0F |
Read-Reply |
是否需要阅读报告 |
0x10 |
Report-Allowed |
是否允许报告 |
0x11 |
Response-Status |
回复状态 |
0x12 |
Response-Text |
回复文本 |
0x13 |
Sender-Visibility |
发送者是否可见(即是否匿名发送) |
0x14 |
Status |
信息状态(是否立即接收,拒绝还是不支持) |
0x15 |
Subject |
主题 |
0x16 |
To |
接收者地址 |
0x17 |
Transaction-Id |
传输ID(用于网络控制,识别不同的传输) |
0x18 |
在对MMS Header编码时,X-Mms-Message-Type, X-Mms-Transaction-ID和X-Mms-MMS-Version是必须存在的,且它们必须位于MMS Header的开始部分,并且按照前面所列的顺序排列。Content-Type必须在MMS头域的最后,其后为消息体。其它域的顺序可以随意安排。除了常用的消息域外,也可以自定义消息域,自定义消息域以X-开头,但不能以X-Mms-开头。
这里再强调一次,不同类型的PDU Header包括的域是不尽相同的,在同一个Header里面,有的域是必须存在的,有的域是在某些情况下才存在的,还有的域则是可选的,不同类型PDU Header的详细结构可参见OMA-MMS-ENC-V1_2-20040323-C.pdf 的第6节,详细的Header域名和对应域名的编码可参考OMA-MMS-ENC-V1_2-20040323-C.pdf的第7.2节和7.3节。说明一点:为了是传输的数据更紧凑,WSP协议规定,对于Header Field Name的编码,数值的最高位(即bit7)置1。因此,上述编码值在实际的MMS PDU中需要加上0x80。
3.2 Message Body
MMS 在终端上显示出来可以仅仅是一幅画面,也可以像一系列的幻灯片一样,一张接着一张有序地播放,每张“幻灯片”可以包括文字、图像和声音,甚至视频等多媒体元素,元素的显示位置和显示时间可以控制,“幻灯片”之间有一定的时间间隔。这些多媒体元素的数据和显示控制信息通过一定的方式组织起来,经过编码,就组成了MMS PDU的消息体。结构如图11所示:
图11 MMS PDU结构
MMS Header在语义上与HTTP协议类似,但是其编码方式并不一样,为了充分利用带宽,MMS Header采用二进制方式编码。Header中的每一个域由域名和域值组成,如下图: