当前位置:   article > 正文

一种OpenHarmony电话子系统南向适配方案

一种OpenHarmony电话子系统南向适配方案

一种OpenHarmony电话子系统南向适配方案.md

1.电话子系统框架

官网电话子系统框架图
在这里插入图片描述

南向ril_adapter库框架图
在这里插入图片描述

2.适配方案

2.1 南向ril_adapter框架

ril_adapter分为三部分hril_hdf、hril、vendorlib。

  • hril_hdf

    hdf驱动接口。hdi服务(drivers/peripheral/ril/interfaces/hdi_service/src/ril_driver.cpp)调用InitRilAdapter和ReleaseRilAdapter使用ril_adapter的功能。

  • hril:

    负责与电话子系统框架层core_service模块ipc通信,接收框架层指令、返回指令执行结果。

  • vendorlib:

    厂商库,通过usb串口,发送at指令,接收串口回传信息。

2.2 修改hril_hdf

hril_hdf主要功能是加载vendorlib,库的名称默认是libril_vendor.z.so,对应vendorlib。

修改默认厂商库加载路径有两种方法:

  • 修改全局属性const.telephony.ril.vendorlib.path
  • 修改g_usbModemVendorInfo,通过usb的vendorid和productid筛选后加载

修改base/telephony/ril_adapter/services/hril_hdf/include/modem_adapter.h,添加厂商库配置

UsbDeviceInfo g_usbModemVendorInfo[] = {
    // MEIG modem
    {.idVendor = MEIG_VENDOR_ID, .idProduct = MEIG_PRODUCT_ID_SLM790, .libPath = "libril_vendor.z.so"},
    // Fibocom modem
    {.idVendor = FIBOCOM_VENDOR_ID, .idProduct = FIBOCOM_PRODUCT_ID_NL668, .libPath = "libfibocom_ril.z.so"},
    // my modem
    {.idVendor = MY_VENDOR_ID, .idProduct = MY_PRODUCT_ID, .libPath = "libril_vendor_my.z.so"},
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

vendorid和productid可以在hdc shell下通过lsusb查看。

修改base/telephony/ril_adapter/services/hril_hdf/src/hril_hdf.c,新增vendorid和productid判断逻辑。

这里笔者选择通过libusb来获取usb信息,主要代码如下:

static UsbDeviceInfo *GetPresetInformationByInt(const int32_t idVendor, const int32_t idProduct)
{
    UsbDeviceInfo *uDevInfo = NULL;
    for (uint32_t i = 0; i < sizeof(g_usbModemVendorInfo) / sizeof(UsbDeviceInfo); i++) {
        if (g_usbModemVendorInfo[i].idVendor == idVendor && g_usbModemVendorInfo[i].idProduct == idProduct) {
            TELEPHONY_LOGI("find usb device index=%{public}d", i);
            uDevInfo = &g_usbModemVendorInfo[i];
            break;
        }
    }
    return uDevInfo;
}
#include <libusb/libusb.h>
static UsbDeviceInfo *GetUsbDeviceInfo(void)
{
    UsbDeviceInfo *uDevInfo = NULL;

    libusb_context *ctx = NULL;
    libusb_device **devs;
    ssize_t cnt;

    // 初始化libusb
    if (libusb_init(&ctx) < 0) {
        TELEPHONY_LOGE("libusb_init failed");
        return NULL;
    }

    // 获取已连接的USB设备列表
    cnt = libusb_get_device_list(ctx, &devs);
    if (cnt < 0) {
        TELEPHONY_LOGE("libusb_get_device_list failed");
        libusb_exit(ctx);
        return NULL;
    }

    TELEPHONY_LOGI("usb device list:");

    // 遍历设备列表并输出信息
    for (ssize_t i = 0; i < cnt; i++) {
        libusb_device *dev = devs[i];
        struct libusb_device_descriptor desc;

        // 获取设备描述符
        if (libusb_get_device_descriptor(dev, &desc) < 0) {
            TELEPHONY_LOGE("libusb_get_device_descriptor failed");
            continue;
        }

        // 打印设备信息
        TELEPHONY_LOGI("USB Device %{public}zd : ID 0x%{public}04x:0x%{public}04x ADDR:%{public}d", i + 1, desc.idVendor, desc.idProduct, libusb_get_device_address(dev));
        uDevInfo = GetPresetInformationByInt(desc.idVendor, desc.idProduct);
        if (uDevInfo)
        {
            TELEPHONY_LOGI("USB Device found!");
            break;
        }

    }
    // 释放设备列表
    libusb_free_device_list(devs, 1);
    // 退出libusb
    libusb_exit(ctx);
    return uDevInfo;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

2.3 修改或新增厂商库

由于原vendorlib是适配美格SLM790模组的,在硬件不同的情况下,需要修改或新增厂商库。

厂商库框架:

  • at_call.c :呼叫业务相关at处理
  • at_data.c :数据业务相关at处理
  • at_modem.c : 调制解调器业务相关at处理
  • at_network.c : 网络相关at处理
  • at_sim.c : sim卡相关at处理
  • at_sms.c : 短信相关at处理
  • at_support.c :at处理通用接口,收发处理函数
  • vendor_adapter.c :对外接口
  • vendor_channel.c :at读写接口
  • vendor_report.c : at上报处理
  • vendor_util.c : 工具函数

修改方案:

  1. 初始化at修改

    修改base/telephony/ril_adapter/services/vendor/src/vendor_adapter.c文件,

    修改ModemInit()函数,这里是初始化时发送给modem的at指令,根据厂商提供的信息,删除报错的at,增加和修改部分的at命令。

  2. 各模块at修改

    AT+开头指令为3GPP规定的AT指令,modem基本都会支持。

    搜索全部的AT^开头的指令,将其修改为modem手册上对应的AT。

    例如,获取sim卡类型的AT指令,如果没有该AT,可以直接返回类型,如下:

    static int32_t GetSimType(void)
    {
        return HRIL_SIM_TYPE_USIM;
    }
    
    • 1
    • 2
    • 3
    • 4
  3. 构造at指令回复信息

有一些AT底层无法执行,可以构造虚假回复消息,发送空数据给框架层。

例如:

struct ReportInfo reportInfo = CreateReportInfo(requestInfo, HRIL_ERR_SUCCESS, HRIL_RESPONSE, 0);
OnSimReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
  • 1
  • 2

如果业务流程修改较大,无法在ril_adapter满足要求,建议修改电话子系统的框架层代码。
但如果只是修改at发送和接收就能满足业务流程,则不需要修改框架层代码。

综上,按照该方案修改的电话子系统可以做到一个板卡硬件通过usb接入不同的modem,均可以识别加载,实现电话子系统功能。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/605339
推荐阅读
相关标签
  

闽ICP备14008679号