分类: IT业界
2013-04-07 11:13:41
原文地址:基于WSP/WTP的MMS传输(3)——MMS PDU结构 作者:duanqz
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中才有消息体。
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”部分时,如何显示则由客户端的显示策略来决定。
的封装(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。
封装示例
下面举一个实际的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