【三大困扰,两宗罪】
1. 神秘的 celltsp 。
2. modem 特性的差异
3. 无诚意的 connection manager
1. 未知的 celltsp 。这是一个动态库,是 tapi 和 ril 之间的桥梁,比如要完成一个呼叫过程, celltsp 和 ril 驱动是有许多的互动,奈何 celltsp 没有源码,只能根据手册和调试信息来猜测 celltsp 的行为。 MSDN 只有此一句: CellTSP ignores RIL_NOTIFY_CONNECT. Use RIL_NOTIFY_CALLPROGRESSINFO to indicate call state transitions. 好家伙,这算嘛回事?
2. modem 特性差异。 AT 标准是只有一份,可是各家解读不同,同一个命令,有些可能会认为处理完毕正确返回 OK ,有些可能会立刻返回 OK 。更特别的是专有命令,比如微软手册提到的 CPI 命令,俺家用的模块就没有, CPI 是 call progress information 。这个差异可是会导致 RIL 驱动中呼叫流程变化。
3. 无诚意的 connection manager 。 CM 功能充满诱惑力,在 CE6 R3 中呈现时眼前为之一亮。兴奋打包进去后才发现,没法用,或者说不会用。原来 CM 是需要配置的,用 DMProcessConfigXML 来配置一个 xml 脚本。好家伙,这个函数芳踪何在?这算嘛事。
【简介】
RIL 是移动通讯核心( cellcore )和无线硬件设备( modem )之间通讯的控制接口,由此集成 GSM, CDMA 等不同 Modem 设备,适应不同无线网络。 RIL 由两部分组成: RIL proxy 和 RIL driver 。 RILproxy 是一个基于 CE 的动态链接库 (DLL) --- ril.dll ,微软已经提供,它简化上层各个应用对驱动的访问。 而 RIL driver 即流驱动需要自己实现。 RILdriver 向系统提供无线服务,包括语音、 数据和 SMS 。 RILdriver 同时也通知无线状态的改变,例如服务区 (coverage) 、信息强度和来电等。 RIL 模型类同音频模型, ril proxy 好比 waveapi , ril driver 好比 wave 流驱动。
图 1.
【 RIL 结构和接口】
一:串口驱动。
最下层是串口硬件和串口驱动。 Modem 串口连接最普遍的说法是需要用到 9pin 的全功能串口,我的看法,在 RIL 驱动中对 DCD 配置的修改,使用 3 线串口也是可以的,但是在完整的产品还是要通过 3 线之外的其他 io 来辅助,不然会牺牲掉硬件流控以及唤醒,通知等功能。
二:可选的 mux 驱动。
考虑到 modem 不仅有 at 控制通道,还有数据传输通道,而串口是无协议的接口,所以从软件实现和性能考虑,最好的方式当然是 2 个串口分别提供。但实际中常见的都是 1 个串口的,支持 gsm0710 协议的 modem 能够实现在 1 个物理串口基础上虚拟多路串口。怎么判断是否支持多路复用? modem 用 AT+CMUX 命令来完成多路复用协议。 Cellcore 里面 Gsm 07.10 协议已经提供源码实现 mux07_10.dll ,默认的虚拟出 2 个串口 COM7 和 COM9. 典型应用中, COM7 作为 AT 命令通道, COM9 作为数据通道,这样意味着在 gprs 状态下语言短信业务有可能可以同时使用,不必退出 data 模式。如果你的 modem 本身就已经有 2 路物理串口,那么 710mux 驱动是不需要的。如果你的 modem 并不支持 GSM 07.10 协议,只有 +++ 退出 data 模式了。
三: RIL 驱动。
710mux 驱动之上就是 ril 驱动了。 MS 已经抽象了大部分 ril 驱动的功能,通过了 MDD 源码,所以写一个 ril 驱动就是把自己 modem 相关的代码和 MDD 链接成一个流驱动 rilgsm.dll 。 ril 驱动与串口驱动的最大不同在于, ril 是同时支持多个应用使用的,每次 open 都 new 一个 Instance 对应。
DWORD RIL_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
pDevice = (CRilHandle)dwData ;
pHandle = new CRilInstanceHandle ;
pHandle->Init(pDevice);
pDevice->AddToList(pHandle);
return (DWORD)pHandle;
}
上层应用打开 RIL 之后就可以使用 RIL 流驱动的 IOCTL 来使用 RIL 驱动。
四: RIL 代理层
直接使用 ril 驱动显得不方便,所以 MS 继续封装了一个 RIL Proxy 的层,由它来和驱动打交道,这个 RIL Proxy 的实体是 ril.dll ,函数形式都是 RIL_XXX() ,函数声明在 ril.h 文件。基本上所有的应用都是使用代理层来实现。
五:应用层
RIL Proxy 的上层是 TAPI/ExTAPI , SIM 管理程序, SMS 管理程序,电话,以及是基于 gprs 的网络应用程序。如图 1 ,这些顶层的应用也许并没有直接和 RIL 驱动打交道,中间还有一些代理层,如下面列出的 celltsp.dll, sms.dll 等。
tapi-> tsp(celltsp.dll) -> ril 代理 (ril.dll) –> rilgsm.dll
Sim -> sim api(cellcore.lib) -> ril.dll ->rilgsm.dll
Sms -> sms api(sms.dll) -> sms provider(sms_provider.dll) -> smsdrv.dll -> ril.dll -> rilgsm.dll
再往上,还有 connection manager( 在 CE6 R3 包含 ) 连接管理器 api , ATCI 和 Assisted tapi 这些。 ATCI 是保留给应用一条对 modem 直接发 AT 命令的管道,但只在 wm 中有 ce 并没有包含。 Assisted Tapi 在 ce6 的文档仅仅包含 tapiRequestMakeCall ,按照理解,这个是提供给系统拨号软件之外的第三方软件一个请求 拨号的接口,会转发到系统的拨号软件处理。至于 connection manager 是 09 年 10 月发布 R3 版本中的新增内容,如同 wm 中的 CM 模块,这对应用而言是很有吸引力的模块,具有自动完成各种网络连接,自动选择网络,自动重拨,永远在线按需使用等功能,遗憾的是根据我目前实验,因为 DMProcessConfigXML 在 CE 无实现, CM 配置存在困难,如您有答案不吝赐教。