基于Android的机顶盒CAS系统的开发
避免其未处理完此EMM,而又接收新的EMM。此时EMM任务从挂起进入就绪态,从而处理来自filter的EMM信息,处理完之后再次分配EMM的filter。 在ECM任务模块中,通过CAS_ECM_TASK()创建线程任务,在其内部调用CAS_ECM_ReceiveMessage()函数接收来自ECM的filter过滤出的CA信息;此时通过CAS_CARD_ReadMessage()读取智能卡内部用户授权信息,来判断ECM是否有效且取出对应的密文的CW;而用CAS_ECM_Send To Card()函数把密文CW送入到智能卡中解密,解密出明文CW;用CAS_CW_SendToSTB()函数送入到机顶盒,此时解复用模块接收到明文CW就可以得到解码加密流了。 如图6所示,在智能卡任务模块中,在系统启动之初,未进入文件系统之前,就要对智能卡进行初始化,分配内存池,强制为智能卡复位,从而选择通信类型(T0或T1),全部完成之后就可以进入文件系统。通过CAS_CARD_TASK()为智能卡建立线程,在其线程内部使用CAS_CARD _ReceiveMessage()接收来自EMM或者ECM的命令字。如果合法,通过CAS_CARD_SendMessage()可以把应答字给其两个模块,同时通知其他两个模块发送操作数,若是EMM则到此结束,若为ECM则智能卡会把解密的CW通过CAS_CARD_SendMessage()发送给机顶盒。 由于每个智能卡厂商的填充数据不一样,所以必须根据厂商的定义再去提取数据、处理数据。由于笔者参与设计的是某公司提供的智能卡,所以数据的格式也都以它为标准。最终设计包括12个源文件、5个头文件。 3.2 编写CAS子系统的makefile
2.2 ECM任务模块
通过解渎CAT表可知,此节目表是否加密,如果加密则设置相应ECM的filter过滤出对应的ECM表,此时结合智能卡中存储的EMM的CA信息,就可以判断出用户是否对此节目授权,若授权则取出智能卡中的SK业务密钥,找出对应的奇偶控制字(CW),送入到智能卡中,通过智能卡系统解密出CW,送入到STB中实现数据、视频、音频的解码。整个过程如图5所示。
2.3 智能卡任务模块
智能卡的通信标准有T0和T1两种,T0按字节传送,T1按块传送,而在设计过程中通常支持两种协议。一般采用I2C总线通信,而智能卡内部一般没有上拉电阻,所以在电路设计过程中,SCL和SDA的引脚处必须加上拉电阻,否则无法正常通信。根据通信协议,如果要对智能卡数据读写操作,首先要发送5字节的命令字,这5字节命令字依次为CLA、INS、P1、P2、P3,其中CLA为指令类型,INS为命令符,P1、P2为操作文件位置,P3为后续字符数。智能卡接收到命令符就可以根据命令种类对其后续数据进行操作,同时智能卡就可以发出两个字节W1、W2的应答符。如果成功,W1、W2分别为0x90、0x00;如果不成功则会返回相应的代码,以便给开发者提供调试。因为智能卡内部十分复杂,篇幅有限,所以想深入了解原理的话可以参考智能卡标准,这里仅介绍机顶盒操作智能卡过程的设计。
2.4 其他细节设计
CAS系统除了最重要的解扰以外,还有其他重要的附属功能,如邮件、在线付费、在线充值、节目点播、区域限制、用户管理。这些信息都存储在EMM表中,所以EMM和ECM表的解析也是一个十分重要的步骤,只有正确地提取出 EMM中的CA信息,才能顺利地进行下一步的操作。根据MPEG-2标准和PSI/SI协议,以及智能卡厂商的提供功能表,就能设计出EMM和ECM的解析函数。
表1列出了一个通用CA的描述符。
3 CAS子系统Android的移植
CAS终端子系统起初没计由于涉及到与底层交互,采用的是C语言。如果想要使上层的JAVA环境调用其API,就要遵循JNI规范添加新的头文件,使其应用层能够方便地调用。同时Google在设计Androld之初就提供了NDK套件,有着独有的交叉编译器,使得原有的许多C语言编写的驱动、应用程序可十分方便地移植到Android系统中。
3.1 搭建Android的NDK开发环境
由于是在Windows下进行开发,所以要在Windows下模拟Linux的开发环境,需要下载cygwin工具,下载地址为http://www.cygw in.com/setup.exe。安装方法请参考相关文档,这里就不赘述了。同样也需要Android的NDK套件,下载地址为http://developer.an droid.com/sdk/ndk/index.html;可以选择最新的版本下载,下载完毕,直接解压到同一路径下。然后在cygwin的安装目录home/Adm inistrator下的./bash_profile文件添加NDK的路径,就可以使用NDK下的ndk-build命令了,进入samples/hello-jni。在cygwin中调用ndk-build,如果出现如图7所示的结果,则NDK的环境已经搭建成功。
笔者使用的是android-ndk-r7b版本,也是目前最新版本,其交叉编译器位于其toolchains/arm-linux-an-droideabi-4.4.3/pre built/windows/arm-linux-android/bin中,库的头文件位于/platforms/android-xx/arch-arm/usr/include中,库位于platform /android-xx/arch-arm/usr/lib中。知道了编译器和C库的头文件,就可以容易地编写出 makefile。在编写makefile时需要注意,若用到了posix的pthread库,则需要添加“LDFLAGS+=-lpthread”,否则在执行链接的时候会出现错误。编译完成之后如图8所示。
3.3 实现CAS子系统的JNI接口函数
因为CAS子系统提供给外部使用的API达20多个,这里以CASTB_GetVersion()函数为例,其他都是如此实现。新建一个文件夹,命名为STBCA,在文件下建立两个文件夹分别命名为JNI和SRC。JNI存放为CAS的JNI本地API,源文件为castb_api_jni.c;SRC存放的是上层JAVA应用程序,根据JNI标准则需把CASTB_GetVersion()定义为“Java_com_jpf_stbca_STBCA_CASTB_GetVersion();”。只要调用3.2小节的中liBCAS.a库中的源函数就实现了对原函数的包装,在同一目录下添加android.mk,内容如下所示:
LOCAL PATH=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE=casjni
LOCAL_SRC FILES=castb_api_jni.c
LOCAL_LDLIBS+=-lcas\
-lpthread
include $(BUILD_SHARED LIBRARY)
通过3.1小节的步骤就可以生成cas_jni.so库,上层如果曼调用cas_jni.so库中的函数只要在JAVA文件中声明public native CASTB _GetVersion()函数,且使用“static{system.loadlibrary(“cas_jni”);}”把动态库加载到连接器中,就完成了全部的设计。通过实践,负责上层软件编写的同时能够无缝地实现CAS系统API的调用。
结语
本文详细阐述了CAS子系统的开发过程和Android系统移植。在Android机顶盒的开发过程中,使用的是华为的H3716C平台,笔者承担了CAS系统和PSI/SI节目表解析的开发与移植。使用此CAS子系统播放加密节目,持续稳定地播放一周而且没有出现马赛克或卡现象,说明此CAS子系统比较稳定。但CAS是一套功能完整的独立系统,而笔者只是重点探讨解密的过程,许多其他功能未有涉及,若想深入了解CAS系统,请参考CAS系统标准。
系统 开发 CAS 机顶盒 Android 基于 相关文章:
- 第四代移动通信系统中的多天线技术(08-05)
- 透析信道效应对MIMO系统运作效能的影响(01-18)
- 如何发展中国第二代导航卫星系统(02-02)
- 北斗卫星导航系统的特点(02-02)
- 基于无线传送的智能家居室内通信系统(01-03)
- 基于WiMAX技术的5.8G无线专网射频系统设计(10-06)