Q: CMMB是什么意思?MBBMS又是什么?它们的关系是什么?
CMMB是China Mobile Multimedia Broadcasting (中国移动多媒体广播)的简称。是国内自主研发的第一套面向手机、笔记本电脑等多种移动终端的系统,利用S波段信号实现“天地”一体覆盖、全国漫游,支持25套电视和30套广播节目。2006年10月24日,国家广电总局正式颁布中国移动多媒体广播(俗称手机电视)行业标准,确定采用我国自主研发的移动多媒体广播行业标准。标准适用于30MHz到3000MHz频率范围内的广播业务频率,通过卫星和/或地面无线发射电视、广播、数据信息等多媒体信号的广播系统,可实现全国漫游。
MBBMS是指Mobile Broadcast Business Management System (广播式手机电视业务管理系统),它的基础是利用现有移动通信网络的管理、计费系统和认证鉴权机制,实现对手机电视用户的管理。
CMMB是一个独立的系统,它可以脱离MBBMS独立的运行,但是无法使用MBBMS所带来的现有的移动通信网络资源。比如,MBBMS的密钥核心算法在SIM卡上存储和执行,CMMB CA的密钥核心算法在小卡/SMD/大卡上存储和执行。再比如,仅仅是CMMB无法使用移动网络现有的计费系统。
MBBMS提供了一系列使用现有移动资源的方法,除CMMB之外的其他手机电视标准也可以使用这些方法,比如MBMS。
Q: CMMB+MBBMS系统需要手机提供什么样的软硬件资源?
首先说硬件,需要提供一颗CMMB芯片,负责调频,接收数据,改芯片上还需要集成一块UAM芯片,负责一些核心解密算法的实现。
如果是单独的CMMB系统,还需要提供一块小卡,该小卡的功能在MBBMS中被UAM+SIM卡取代。
Q: CMMB使用什么频段?
理论上是30MHz~3000MHz频率范围。全国的频段分布是:
http://wenku.baidu.com/view/27a1baa2b0717fd5360cdc66.html
Q: CMMB+MBBMS的基本流程是哪些?
1. 更新节目单 2. 更新订购关系表 3. GBA 4. 获取MSK 5. 若是扰流,进行解扰 6. 将音视频以RTP的形式输出
Q: CMMB芯片的基本工作原理是什么?
调到一定的频段,然后读取某个或某些时隙。物理层逻辑信道分为控制逻辑信道(CLCH)和业务逻辑信道(SLCH)。控制逻辑信道用于承载广播控制信息,业务逻辑信道用于承载广播业务。物理层只有一个固定的控制逻辑信道,占用系统的第0时隙发送。业务逻辑信道由系统配置,每个物理层带宽内业务逻辑信道的数目可以为1~39个,每个业务逻辑信道占用整数个时隙。
Q: 电子业务指南是什么?
就是ESG(Electronic Service Guide),它分为SGDD和SGDU,使用HTTP协议进行传输。
Q: 节目单是如何传送到手机的?
对于CMMB+MBBMS,业务指南是通过移动通信网络数据业务(如GPRS,TDSCDMA等)下发的;对于单独的CMMB,业务指南是放到复用数据的数据段里下发的,需要通过解复用才能拿到。
Q: 什么是GBA?它有什么作用?
通用认证机制GBA(GeneralBootstrappingArchitecture),是3GPP定义的一种利用现有移动通信网络资源的认证机制。最终的一个目的就是为了在终端与业务平台之间共享一个秘密的密钥,用于安全通信。
手机打开手机电视后的基本流程如下:
第一步,更新节目单:
1. APP试图查找存在手机存储空间(如sdcard)里的SG文件,如发现没有,于是开始下载SG。
2. MBBMS发送一个HTTP REQ来请求一个gzip包。然后解压缩到手机存储空间。
3. 进行SG的解析,其实就是XML数据的解析。最终得到SG相应分片的信息
如purchaseChannel,purchaseItem,purchaseData,service,previewData,schedule,interactivityData等。
第二步,更新订购关系表:
更新订购关系表,并在手机存储空间存成文件。订购关系表就是提供了一堆已经订购了的服务的MSKID,举例:
....
第三步,GBA
Generic Bootstrapping Architecture (GBA) 是一种用来进行用户鉴权的技术。
GBA流程(使用HTTP Digest,此协议的好处是无需明文传password,跟目前网站流行的加密密码是一个道理。明文传username,然后查询password并算出。所谓Digest,是因为采用了某些摘要算法,如MD5。另外,需要用到2G和3G的鉴权机制)
1. mbbmsExecuteGBA,通过SetRequest把REQ放入g_requestListHeader,然后通过GetRequest把REQ拿到g_currentRequest
此REQ的特征:
req.cmd = REQCMD_INITIALIZE;
req.param = force;
2. 在REQ处理线程中,进入InnerInitialize
3. get imsi, HTTP_SendRequest(httpHandle, NULL, gbaBuf, STRLEN(gbaBuf), 0, 0, 0),其中有HTTP的header和gbaBuf
(HTTP的请求消息体,类似这样的消息
"
xmlns:xs="http://www.w3.org/2001/XMLSchema\" xmlns="urn:3GPP:metadata:2005:mTV:IMPIRequest"
Type="IMSI"
TerminalCapability="%s"
UserAgent="%s">
%s
",
其中UserID就是imsi)
4. 然后函数进入循环死等RESP,成功后 解析Bootstrapping_Initiation.RESP
5. Create一个IMPI,impi:[email protected],通过uam_get_version来获取Version
6. Create一个Digest请求,继续死等RESP
7. 开始鉴权ProcessGbaUnAuthorized,具体步骤是首先是SIM Card鉴权(2G,3G不同的鉴权步骤),然后是UAM鉴权。
卡鉴权做完之后(即AV3,5鉴权)利用鉴权的中间结果,进行UAM鉴权。发送给UAM的中间结果是:如果是SIM卡,在命令中携带(Kc,RAND,Ks-Input,SRES), 如果是USIM卡,在命令中携带(RES,CK,IK)。UAM计算Ks和RES‘,并生成cnonce,把Ks存储下来,并将RES'和cnonce返回给终端。然后发送RES’给网络,网络生成Ks生命周期和B-TID,并发给终端。
8. 网络生成Ks生命周期和B-TID,返回给终端,写入UAM中。
综上,GBA之后,终端和网络都生成了用户共享密钥Ks,这是以后所有密钥工作的基础。
Q:如何获取MSK?
MSK是通过HTTP交互获取的:根据订购关系表拿到MSKID,然后向网络发起请求
Field name Content-Type, value application/mbms-msk+xml
里面带有KeyDomainID和MSKID。
然后收到HTTP RESP,从中拿到 MSK Mikey。·
这是一个MSK Mikey的例子:
MSK:010015000C84B26D00010503000B00030100000104025A22E40B0250E7A1D9061031353730313439303936383836353833060000196E61662E6D62626D732E6368696E616D6F62696C652E636F6D010000355677744A2B62657733794B30487532535259494F74673D3D406273662E626A2E6D62626D732E6368696E616D6F62696C652E636F6D0001001E4534458CE203062C74A37816FCC3ABFAD4D3D39B58F5452BFFB4EB60CF7601041C2A6A570E7F3EE0F07494EDD3642714F61D75
拿到MSK Mikey后,通过UAM计算出MSK。
Q:如何对扰流进行解扰?
1. 然后试图播放一个频道。如果是加密频道,需要解析SG里的SDP,拿到相关的解扰参数。这里是一个SDP的例子
其中下划线的部分就是一些对加密进行描述的参数。
然后根据加扰相关参数信息从加密节目流中RTP包的AU头取出key Indicator和IV。
根据协议AU Header的结构如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
|AU-headers-length|AU-header|AU-header| |AU-header|padding|
| | (1) | (2) | | (n) | bits |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
例子:
比如某数据流第一秒数据的第一个视频单元,原数据如下:
0, 2a, f5, 85, 4d, fe, 6f, 0, fd, 63, b2, 2e, 70, 92, 70,e0….
其中0,2a是指的是AuHeader的长度(42 bits ,换算成byte是6)所以真正的加密数据从fd,63… 开始。在AuHeader中ismaCrypIVLength为4, ismaCrypKeyIndicatorLength为1,所以KeyIndicator为6f,而IV为f5, 85, 4d, fe
然后,根据key Indicator从key Indicator和MTK(CW)的对应关系表中查找对应的MTK(CW)
对于UAM来说,输入Mikey, 输出Mtk。
然后就是解扰,使用MTK(CW)以及CW、IV、SDP中的Salt等信息,解密节目流。
比较常用的是AES解密方法。
综上,整个MBBMS的安全架构已经比较清晰了,可以用下面这张图来概括一下:
Q:解扰后的音视频是如何播放的?
解扰后,对于视频,RAW NAL的帧被存储在m_vBuf,长度为m_vNalLen。
在目前看到的Sample Data中,视频是每秒25个NAL左右,有时候能到23个,或者30个,基本能组成25帧。目前在Sample Data,只有I帧和P帧,没有发现B帧。且,每秒必有一个I帧。
这些NAL单元有可能是一个帧的。
FRAME_MID = 0,//Neither the BEGIN or TAIL
FRAME_TAIL = 1,//This Piece of NAL data ends a frame
FRAME_BEGIN = 2,//This Piece of NAL data begins a frame
WHOLE_FRAME = 3,//This is a complete frame NAL data. normally A P-frame
我们要组成一个完整的帧之后再进行RTP传输。
音视频都会被打包成RTP进行发送,其中RTP时间戳会在解析复用子帧头的时候打上去。
音频是使用LATM的方式传输的,该格式也以帧为单位,主要由音频特定配置单元与音频负载组成。LATM帧通过RTP包发送出,而通过SDP把StreamMuxConfig信息发送到解码端。音频负载由音频数据长度和音频数据组成。
对于音频来说,RAW Data的AAC数据前面会有一个Byte来描述数据的长度(Except the Byte itself),
扰流格式为AU Header + Encrypted AAC DATA
下面的函数可以给AAC加上头以形成可以播放的ADTS文件:
void CDemuxClient::OnSaveAACFile(LPBYTE data,WORD wDatalen)
{
static FILE *file = NULL;
BYTE buf[7]={0xff,0xf9,0x58,0x80,0x00,0x1f,0xfc};
buf[5]|=((wDatalen+7) & 0x7)<<5;
buf[4]|=((wDatalen+7) & 0x1FF8)>>3;
buf[3]|=((wDatalen+7) & 0x1800)>>11;
if(NULL==file)
file = fopen("/mnt/sdcard/Download/audio","wb");
if (!file)
{
fprintf(stderr, "Unable to open file\n");
return;
}
if(wDatalen>0)
{
fwrite(buf, 1, 7, file);
fwrite(data, 1, wDatalen, file);
}
}
其中参数data必须是真正AAC RAW DATA的开始。
附录1:HTTP Digest 认证基本框架
1.客户端希望取到服务器上的某个资源,向服务器发送Get请求。
challenge = "Digest" digest-challenge
digest-challenge = 1#( realm | [ domain ] | nonce |
[ opaque ] |[ stale ] | [ algorithm ] |
[ qop-options ] | [auth-param] )
domain = "domain" "=" <"> URI ( 1*SP URI ) <">
URI = absoluteURI | abs_path
nonce = "nonce" "=" nonce-value
nonce-value = quoted-string
opaque = "opaque" "=" quoted-string
stale = "stale" "=" ( "true" | "false" )
algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" |
token )
qop-options = "qop" "=" <"> 1#qop-value <">
qop-value = "auth" | "auth-int" | token
3.客户端收到服务器的401(Unauthorized)回复后,使用服务器回复报文中的nonce值,加上 username,password, http method, http uri利用MD5(或者服务器指定的其他算法)计算出request-digest,作为repsonse头域的值。并重新发送请求,请求报文中包含 Authorization 头,其中有如下信息:
credentials = "Digest" digest-response
digest-response = 1#( username | realm | nonce | digest-uri
| response | [ algorithm ] | [cnonce] |
[opaque] | [message-qop] |
[nonce-count] | [auth-param] )
username = "username" "=" username-value
username-value = quoted-string
digest-uri = "uri" "=" digest-uri-value
digest-uri-value = request-uri ; As specified by HTTP/1.1
message-qop = "qop" "=" qop-value
cnonce = "cnonce" "=" cnonce-value
cnonce-value = nonce-value
nonce-count = "nc" "=" nc-value
nc-value = 8LHEX
response = "response" "=" request-digest
request-digest = <"> 32LHEX <">
LHEX = "0" | "1" | "2" | "3" |
"4" | "5" | "6" | "7" |
"8" | "9" | "a" | "b" |
"c" | "d" | "e" | "f"
4.服务器收到客户端发来的请求后,根据username,查找出用户的password,用和客户端同样的方法计算出request- digest(response)。然后和收到的request-digest进行对比,如果一致,则验证成功,接受客户端的请求,成功返回结果。
上一篇:如何理解敏捷开发?
下一篇:如何优雅的使用“看板”?