Android通信框架与Modem状态未同步——实际项目经验分享
来源:互联网 发布:linux进入单用户模式 编辑:程序博客网 时间:2024/05/18 13:27
问题描述:
Modem已经注册成功了,但是android系统显示仍然是无网状态。
背景知识:
Android为了屏蔽各Modem厂商之间的差异,并未直接使用AT指令,而是定义了通用接口——RIL命令来控制Modem(当然,RIL命令与AT指令之间存在某种不固定的映射关系,因厂商而异)。各Modem厂商则负责提供对应于RIL命令的Vender RIL。RIL是Modem的HAL(硬件抽象),是android系统与Modem之间的通信桥梁,为AP提供了控制Modem的无线接口,RIL实现了Android平台与Modem间的分离。
Android的通信栈共由4层构成:
1、应用程序——利用通信框架提供的API访问Modem;
2、通信框架——为上层提供API,负责将上层请求转成RIL指令,通过UNIX SOCKET(该socket可在/dev/socket/目录下找到,名为rild)方式传递到RIL守护进程(通常双卡系统会有两个rild进程,可通过“ps | grep rild”命令查看),并处理来自RIL进程的回复,将结果传递给上层;
3、RIL层————RIL守护进程利用Vender RIL控制Modem;
4、Vender RIL——是实际控制Modem的软件,由厂商提供;实现了android定义的标准Modem控制接口。它是*.so形式的共享库。
问题确认:
1、Radio日志包含了RIL层与Modem之间的交互信息(RIL指令),以及android通讯框架层的所有相关日志信息;Modem日志记录了其与基站的所有交互(鉴权)过程。因此分析通讯相关问题,Radio日志和Modem日志都是关键资料。
2、通过获取并分析Radio和Modem日志,确认是两边状态未同步所致(Modem日志明确显示已经通过鉴权注册成功)。
探索思路:
首先我们认定这是android系统通信框架的BUG,所以希望通过直接与Modem通信,而绕开android系统的通信框架。 理论上,的确是可以绕过android系统的通讯框架,而直接与RIL层通信,并通过RIL层发指令对Modem进行控制的; 但是首先,需要你伪装成Radio进程,其次一旦你的程序与RIL守护进程建立连接,那么android系统的通讯框架(包括上层Phone应用)将会与RIL失去连接,以致于功能失效; 因此,你的程序务必功能足够完善,能够模拟android通讯框架的绝大部分关键功能,其次你的程序还需要足够健壮,保证不会导致系统Crash。 顺着这个思路,实现的难度之大、开发调试的周期之长,可想而知。并且,有点“重复造轮子”的意味。因此,调试android系统框架层、及RIL层代码成为最(甚至是唯一)可行的方向。
问题解决:
由于笔者所参与开发的android设备,采用了虚拟sim卡(软sim)技术,所以发起扫卡和注册的时间并不固定。 通常的android设备只会在开机,或者打开飞行模式再关闭时,触发扫卡和注册,但采用虚拟sim卡技术的android设备,可能在任意时间点触发。基于这个差异,笔者发现了android通信框架与Modem状态未同步问题的必现场景——在开机等待了一定时间(超过1分半钟)后,再发起注册。
而后经过不懈努力,终于找到了AP侧与BP侧状态不同步的蛛丝马迹——有一个状态取值on和off的变量radio(可能象征了设备的无线射频是否开启),决定框架层是否会调用“> OPERATOR”等这些RIL指令去查询Modem的实际注册状态。如果radio的状态为off,框架层的确是不会发起注册结果相关的任何查询的,而在AP和BP采用异步通信的场景下,不查询意味着即使Modem注册成功,android系统也是不会知道的。
而正好发现,笔者开发的设备在开机等待了一定时间后radio的状态就off,且不会再自己on了。于是抓住radio状态这个关键点做文章,最终把这个问题成功修复了。
问题总结:这是android系统的一个BUG(或者说android系统并未考虑到虚拟sim卡这种应用场景)
- Android通信框架与Modem状态未同步——实际项目经验分享
- 与modem通信
- AP与modem通信
- StateFramework——Android状态通知通信快速开发框架
- 项目开发经验分享—分页查询
- 项目开发经验分享—导出Excel
- 项目开发经验分享—导入Excel
- 项目优化经验分享(三)数据调用同步与异步
- AngularJS实际项目应用——单元测试框架设计
- android modem调试的一点点经验
- 第一个实际项目经验
- C#中串口与Modem的通信
- 经验分享-项目基础生成框架的编写
- 项目经验分享——Java常用工具类集合
- 项目经验分享——Java常用工具类集合
- 项目经验分享——Java常用工具类集合
- 项目经验分享——Java常用工具类集合
- 项目经验分享——Java常用工具类集合
- 百度地图与谷歌地图坐标转换,WGS84、GCJ02、BD09地图坐标系间的坐标转换及坐标距离计算
- Linux 下压缩与解压缩 zip、binzip2、tar、zip命令的使用
- ImageView.ScaleType属性
- linux下使用rz上传文件,sz下载文件
- opencv-Python旋转矩形框裁减
- Android通信框架与Modem状态未同步——实际项目经验分享
- React Native 之 ScrollView使用
- Facade模式
- 滑动窗口最大值
- SDK&API&MFC 的区别
- 写一个宏可以将一个数字的奇数位和偶数位交换。
- 练习 1-20 编写程序 detab,将输入中的制表符替换成适当数目的空格,使空格充满到 下一个制表符终止位的地方。
- 图片上传并异步提交
- TCP/IP、Http、Socket的区别