移植RIL让Android平板支持3G Modem电话功能

时间:2022-11-09 09:40:46

一个不支持电话功能的Android平板,我们可以通过usb连接上外置modem,让其支持电话短信及上网功能。在让内核正确识别出ttyUSB设备后,AT命令将通过该usb转串口发送。至于语音通道可以直接从直至模拟方式的modem上进行语音的输入输出,也就是语音不走AP这一侧,这样就大大简化AP侧的开发工作。本例即是如此。

移植时,一是reference-ril中的初始化工作,即initilizeCallback函数,一般来说各modem大同小异。Google的Android默认实现能满足大多数需求,但有的modem需要添加额外设置。二是:不同的modem往往在标准AT命令集上添加了自己的AT命令,或某些AT命令的参数不够标准,这时就需要针对这些差异,检查Android中的实现做出相应修改。

本例中,在调试时,还发生过其它问题,记录如下:

(1)将驱动各方面准备就绪后,各种AT命令可以正常执行。但无法拨打电话,用AT+CSQ查询信号强度,总是返回99,没有网络。用AT+CREG查询,返回的参数也是没有网络,也不搜寻网络。强行注册,modem直接挂了。经过咨询这方面相关资深人士后,怀疑射频不好。果其不然,厂家没有邮寄射频天线。第一次邮寄板子时,没有任何天线,第二次邮寄来一个长天线,却没带射频连接线,把长天线接到GPS天线口上,误把其当作Modem射频天线了,怎会有射频信号进入呢?

(2)rild不能将消息送到RILJ,因为套接字s_fdCommand总是小于0.更改/dev/sokcet/下面的权限,跟log,发现是listenCallback没有被调用,因而没有accept,所以s_fdCommand<0。再继续查,原来RILJ会去判断有无mobile网络,有则启动RILSender,发送连接请求,rild的listenCallback会被调用,否则不创建RILSender,也就没有连接请求,rild中的消息状态什么的也就上报不过去了。对于是否存在mobile网络,由ConnectivityManager提供API进行返回,实际由ConnectivityService进行实际的判断,这则是根据一个config.xml文件来配置。当平台厂商覆盖了该配置文件后,可能导致不支持mobile网络。

(3) rild崩溃。当一切就绪后,片刻后rild崩溃,遇到signal11错误,打出调用堆栈。导致套接字关闭,rild也重启。反复找寻,在onRequest中注释掉一些RIL请求,由其来自RILJ层的SIM IO,终于使其恢复正常。

(4)主动查询AT+CREG时,modem总是返回ERROR,导致上层总是以为网络没注册上。因此电话功能不可用,也就是上层的整个GSMPhone不可工作,也就是该Modem与Android的RIl/Telephony框架不能协调工作。经过一天的努力后放弃该途径。

(5)重写个DemoPhone程序,取代Android框架中的GSMPhone,只接收SIM卡是否就绪这个上报来的消息,不做过多检查和查询。当就绪,则可拨号/挂断/拒接/接听(incoming call响铃通知),短信收发(新短信通知),数据业务激活与去激活。

(6)pppd的拨号脚本wcdma中,当在pc上拨号正;但在板子上,就不正常,执行完后,没看到任何输出。调了好久,最好在main的log中发现

是上锁失败,因为不存在/var/tmp/的目录,后将wcdma脚本中的lock注释掉,一切ok。

最后又发现问题电话功能和数据业务有冲突。当上网后,电话进不来,后得知是挂断脚本中的ATZ命令导致系统设置重置。去掉即可。

(7)在UI界面通过ril请求到onRequest,在onRequest的switch-case分支中,执行pppd  call wcdma脚本,总提示pppd内核模块选项不支持。而在init.rc中,直接执行拨号脚本,也未见执行。后来改为,在onRequest的switch-case分支中设置属性,当熟性变化后,让init.rc脚本执行某个服务(即start 某个service),而这个service则是执行拨号脚本。因为直接执行脚本,不被android的init 初始化执行语言支持。这也是在init.rc中直接执行脚本时,并未执行的原因。