《OpenHarmony 3GPP协议开发深度剖析》之--PLMN业务源码解读

本文深入剖析了OpenHarmony中PLMN选择的源码流程,从Modem初始化、创建监听事件线程到处理Modem上报的业务事件。在AP侧,PLMN业务涉及搜网模块,通过HRIL架构与modem交互,接收modem的AT指令响应,进而更新运营商信息。整个流程包括Modem初始化、业务事件回调以及通过观察者模式处理RadioEvent,如RadioNetworkState。

接续上一篇《OpenHarmony 3GPP协议开发深度剖析》之--搜网流程之PLMN选择
搜网流程可以简单概括为PLMN选择、小区搜索、网络注册,而PLMN选择主要在cp侧完成,而PLMN在OpenHarmony源码中(即AP侧)主要涉及到的业务就是搜网模块中的运营商相关信息获取的业务,比如我们常见的手机状态栏上的运营商名称显示。

下面来针对AP侧中搜网相关的PLMN业务解读下源码流程。

Ril架构回顾

在进行代码解读之前,还是对电话子系统的架构再讲解下,如下图

modem厂商针对OpenHarmony定制自己的lib库,lib库里面主要就是一些AT指令操作,在hril层会根据当前设备的modem指定加载modem对应的厂商库,从而屏蔽直接与modem打交道。而hril层通过HDF驱动框架与tel_ril层进行通信,tel_ril层以上就是AP侧的具体业务逻辑处理了,再往上走就是tel framework层了,该层和tel_ril层主要通过proxy-stub架构进行通信,再framework层就可以定义一些上层api提供给上层应用调用,比如说定义一个api为getOperatorName提供给上层app获取运营商的名称,然后在systemui中调用该api就可以获取到运营商名称并且更新手机状态栏上的运营商名称显示,比如显示“中国移动”。

1.完成Modem初始化,并创建监听modem业务事件监听。

首先从modem侧出发,modem会对电话子系统相关业务事件进行主动上报。

在ril的驱动初始化的时候会加载modem厂商库,见hri_hdf.c中的代码,如下:

struct HdfDriverEntry g_rilAdapterDevEntry = {
    .moduleVersion = 1,
    .moduleName = "hril_hdf",
    .Bind = RilAdapterBind,
    .Init = RilAdapterInit,
    .Release = RilAdapterRelease,
};
HDF_INIT(g_rilAdapterDevEntry);

static int32_t RilAdapterInit(struct HdfDeviceObject *device)
{
	......
    LoadVendor();//加载厂商库
    return HDF_SUCCESS;
}

static void LoadVendor(void)
{
	......
    rilInitOps = (const HRilOps *(*)(const struct HRilReport *))dlsym(g_dlHandle, "RilInitOps");
    if (rilInitOps == NULL) {
        dlclose(g_dlHandle);
        TELEPHONY_LOGE("RilInit not defined or exported");
        return;
    }
    ops = rilInitOps(&g_reportOps);	//初始化modem厂商库
    HRilRegOps(ops);
    TELEPHONY_LOGI("HRilRegOps completed");
}

在LoadVendor中调用了RilInitOps接口,modem厂商库运行的入口在vendor_adapter.c文件中的const HRilOps *RilInitOps(const struct HRilReport * reportOps)接口,代码如下:

const HRilOps *RilInitOps(const struct HRilReport *reportOps)
{
    pthread_attr_t attr;
    SetReportOps(reportOps);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    int32_t ret = pthread_create(&g_eventListeners, &attr, (void *(*)(void *))EventListeners, NULL);	//创建g_eventListeners线程监听modem上报的业务事件
    if (ret < 0) {
        TELEPHONY_LOGE("EventListeners create failed %d \n", ret);
    }
    if (g_hrilOps.smsOps == NULL) {
        TELEPHONY_LOGE("g_hrilOps.smsOps is null");
    }
    TELEPHONY_LOGI("g_hrilOps.smsOps:%{public}p", g_hrilOps.smsOps);
    return &g_hrilOps;
}

在创建g_eventListeners线程传入的EventListeners里面有如下核心代码:

... 
if (devicePath != NULL) {
                g_fd = open(devicePath, O_RDWR);// 打开设备节点,入参g_devicePath是Modem设备节点
 }
...
int32_t ret = ATStartReadLoop(g_fd, OnNotifyOps);//启动循环,读取处理Modem上报的消息。
ModemInit();//modem初始化
</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值