111fccf17Sopenharmony_ci/* 211fccf17Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 311fccf17Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 411fccf17Sopenharmony_ci * you may not use this file except in compliance with the License. 511fccf17Sopenharmony_ci * You may obtain a copy of the License at 611fccf17Sopenharmony_ci * 711fccf17Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 811fccf17Sopenharmony_ci * 911fccf17Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1011fccf17Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1111fccf17Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1211fccf17Sopenharmony_ci * See the License for the specific language governing permissions and 1311fccf17Sopenharmony_ci * limitations under the License. 1411fccf17Sopenharmony_ci */ 1511fccf17Sopenharmony_ci 1611fccf17Sopenharmony_ci#include "hril_hdf.h" 1711fccf17Sopenharmony_ci#ifdef UDEV_SUPPORT 1811fccf17Sopenharmony_ci#include <libudev.h> 1911fccf17Sopenharmony_ci#endif 2011fccf17Sopenharmony_ci#include "dlfcn.h" 2111fccf17Sopenharmony_ci#include "hdf_base.h" 2211fccf17Sopenharmony_ci#include "hril_enum.h" 2311fccf17Sopenharmony_ci#include "modem_adapter.h" 2411fccf17Sopenharmony_ci#include "parameter.h" 2511fccf17Sopenharmony_ci#include "stdlib.h" 2611fccf17Sopenharmony_ci#include "telephony_log_c.h" 2711fccf17Sopenharmony_ci#include "securec.h" 2811fccf17Sopenharmony_ci 2911fccf17Sopenharmony_ci#define RIL_VENDOR_LIB_PATH "const.sys.radio.vendorlib.path" 3011fccf17Sopenharmony_ci#define VIRTUAL_MODEM_SWITCH "const.booster.virtual_modem_switch" 3111fccf17Sopenharmony_ci#define VIRTUAL_MODEM_DEFAULT_SWITCH "false" 3211fccf17Sopenharmony_ci#define TEL_SIM_SLOT_COUNT "const.telephony.slotCount" 3311fccf17Sopenharmony_ci#define DEFAULT_SLOT_COUNT "1" 3411fccf17Sopenharmony_ci#define BASE_HEX 16 3511fccf17Sopenharmony_ci 3611fccf17Sopenharmony_cistatic void *g_dlHandle = NULL; 3711fccf17Sopenharmony_cistatic struct HRilReport g_reportOps = { 3811fccf17Sopenharmony_ci OnCallReport, 3911fccf17Sopenharmony_ci OnDataReport, 4011fccf17Sopenharmony_ci OnModemReport, 4111fccf17Sopenharmony_ci OnNetworkReport, 4211fccf17Sopenharmony_ci OnSimReport, 4311fccf17Sopenharmony_ci OnSmsReport, 4411fccf17Sopenharmony_ci OnTimerCallback 4511fccf17Sopenharmony_ci}; 4611fccf17Sopenharmony_ci 4711fccf17Sopenharmony_cistatic int32_t GetVendorLibPath(char *path) 4811fccf17Sopenharmony_ci{ 4911fccf17Sopenharmony_ci int32_t code = -1; 5011fccf17Sopenharmony_ci code = GetParameter(RIL_VENDOR_LIB_PATH, "", path, PARAMETER_SIZE); 5111fccf17Sopenharmony_ci char simSlotCount[PARAMETER_SIZE] = {0}; 5211fccf17Sopenharmony_ci GetParameter(TEL_SIM_SLOT_COUNT, DEFAULT_SLOT_COUNT, simSlotCount, PARAMETER_SIZE); 5311fccf17Sopenharmony_ci int32_t slotCount = atoi(simSlotCount); 5411fccf17Sopenharmony_ci char virtualModemSwitch[PARAMETER_SIZE] = {0}; 5511fccf17Sopenharmony_ci GetParameter(VIRTUAL_MODEM_SWITCH, VIRTUAL_MODEM_DEFAULT_SWITCH, virtualModemSwitch, PARAMETER_SIZE); 5611fccf17Sopenharmony_ci if (slotCount == 0 && strcmp(virtualModemSwitch, "true") == 0) { 5711fccf17Sopenharmony_ci if (strcpy_s(path, PARAMETER_SIZE, "libril_msgtransfer.z.so") == EOK) { 5811fccf17Sopenharmony_ci TELEPHONY_LOGI("virtualModemSwitch on set path libril_msgtransfer.z.so"); 5911fccf17Sopenharmony_ci code = 1; 6011fccf17Sopenharmony_ci } 6111fccf17Sopenharmony_ci } 6211fccf17Sopenharmony_ci if (code > 0) { 6311fccf17Sopenharmony_ci return HDF_SUCCESS; 6411fccf17Sopenharmony_ci } 6511fccf17Sopenharmony_ci TELEPHONY_LOGE("Failed to get vendor library path through system properties. err:%{public}d", code); 6611fccf17Sopenharmony_ci return HDF_FAILURE; 6711fccf17Sopenharmony_ci} 6811fccf17Sopenharmony_ci 6911fccf17Sopenharmony_ci#ifdef UDEV_SUPPORT 7011fccf17Sopenharmony_cistatic UsbDeviceInfo *GetPresetInformation(const char *vId, const char *pId) 7111fccf17Sopenharmony_ci{ 7211fccf17Sopenharmony_ci if (vId == NULL || pId == NULL) { 7311fccf17Sopenharmony_ci return NULL; 7411fccf17Sopenharmony_ci } 7511fccf17Sopenharmony_ci char *out = NULL; 7611fccf17Sopenharmony_ci UsbDeviceInfo *uDevInfo = NULL; 7711fccf17Sopenharmony_ci int32_t idVendor = (int32_t)strtol(vId, &out, BASE_HEX); 7811fccf17Sopenharmony_ci int32_t idProduct = (int32_t)strtol(pId, &out, BASE_HEX); 7911fccf17Sopenharmony_ci for (uint32_t i = 0; i < sizeof(g_usbModemVendorInfo) / sizeof(UsbDeviceInfo); i++) { 8011fccf17Sopenharmony_ci if (g_usbModemVendorInfo[i].idVendor == idVendor && g_usbModemVendorInfo[i].idProduct == idProduct) { 8111fccf17Sopenharmony_ci TELEPHONY_LOGI("list index:%{public}d", i); 8211fccf17Sopenharmony_ci uDevInfo = &g_usbModemVendorInfo[i]; 8311fccf17Sopenharmony_ci break; 8411fccf17Sopenharmony_ci } 8511fccf17Sopenharmony_ci } 8611fccf17Sopenharmony_ci return uDevInfo; 8711fccf17Sopenharmony_ci} 8811fccf17Sopenharmony_ci#endif 8911fccf17Sopenharmony_ci 9011fccf17Sopenharmony_cistatic UsbDeviceInfo *GetUsbDeviceInfo(void) 9111fccf17Sopenharmony_ci{ 9211fccf17Sopenharmony_ci UsbDeviceInfo *uDevInfo = NULL; 9311fccf17Sopenharmony_ci#ifdef UDEV_SUPPORT 9411fccf17Sopenharmony_ci struct udev *udev; 9511fccf17Sopenharmony_ci struct udev_enumerate *enumerate; 9611fccf17Sopenharmony_ci struct udev_list_entry *devices, *devListEntry; 9711fccf17Sopenharmony_ci struct udev_device *dev; 9811fccf17Sopenharmony_ci 9911fccf17Sopenharmony_ci udev = udev_new(); 10011fccf17Sopenharmony_ci if (udev == NULL) { 10111fccf17Sopenharmony_ci TELEPHONY_LOGE("Can't create udev"); 10211fccf17Sopenharmony_ci return uDevInfo; 10311fccf17Sopenharmony_ci } 10411fccf17Sopenharmony_ci enumerate = udev_enumerate_new(udev); 10511fccf17Sopenharmony_ci if (enumerate == NULL) { 10611fccf17Sopenharmony_ci TELEPHONY_LOGE("Can't create enumerate"); 10711fccf17Sopenharmony_ci udev_unref(udev); 10811fccf17Sopenharmony_ci return uDevInfo; 10911fccf17Sopenharmony_ci } 11011fccf17Sopenharmony_ci udev_enumerate_add_match_subsystem(enumerate, "tty"); 11111fccf17Sopenharmony_ci udev_enumerate_scan_devices(enumerate); 11211fccf17Sopenharmony_ci devices = udev_enumerate_get_list_entry(enumerate); 11311fccf17Sopenharmony_ci udev_list_entry_foreach(devListEntry, devices) { 11411fccf17Sopenharmony_ci const char *path = udev_list_entry_get_name(devListEntry); 11511fccf17Sopenharmony_ci if (path == NULL) { 11611fccf17Sopenharmony_ci continue; 11711fccf17Sopenharmony_ci } 11811fccf17Sopenharmony_ci dev = udev_device_new_from_syspath(udev, path); 11911fccf17Sopenharmony_ci if (dev == NULL) { 12011fccf17Sopenharmony_ci continue; 12111fccf17Sopenharmony_ci } 12211fccf17Sopenharmony_ci dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); 12311fccf17Sopenharmony_ci if (!dev) { 12411fccf17Sopenharmony_ci TELEPHONY_LOGE("Unable to find parent usb device."); 12511fccf17Sopenharmony_ci return uDevInfo; 12611fccf17Sopenharmony_ci } 12711fccf17Sopenharmony_ci const char *cIdVendor = udev_device_get_sysattr_value(dev, "idVendor"); 12811fccf17Sopenharmony_ci const char *cIdProduct = udev_device_get_sysattr_value(dev, "idProduct"); 12911fccf17Sopenharmony_ci uDevInfo = GetPresetInformation(cIdVendor, cIdProduct); 13011fccf17Sopenharmony_ci udev_device_unref(dev); 13111fccf17Sopenharmony_ci if (uDevInfo != NULL) { 13211fccf17Sopenharmony_ci break; 13311fccf17Sopenharmony_ci } 13411fccf17Sopenharmony_ci } 13511fccf17Sopenharmony_ci udev_enumerate_unref(enumerate); 13611fccf17Sopenharmony_ci udev_unref(udev); 13711fccf17Sopenharmony_ci#endif 13811fccf17Sopenharmony_ci return uDevInfo; 13911fccf17Sopenharmony_ci} 14011fccf17Sopenharmony_ci 14111fccf17Sopenharmony_cistatic void LoadVendor(void) 14211fccf17Sopenharmony_ci{ 14311fccf17Sopenharmony_ci const char *rilLibPath = NULL; 14411fccf17Sopenharmony_ci char vendorLibPath[PARAMETER_SIZE] = {0}; 14511fccf17Sopenharmony_ci // Pointer to ril init function in vendor ril 14611fccf17Sopenharmony_ci const HRilOps *(*rilInitOps)(const struct HRilReport *) = NULL; 14711fccf17Sopenharmony_ci // functions returned by ril init function in vendor ril 14811fccf17Sopenharmony_ci const HRilOps *ops = NULL; 14911fccf17Sopenharmony_ci 15011fccf17Sopenharmony_ci UsbDeviceInfo *uDevInfo = GetUsbDeviceInfo(); 15111fccf17Sopenharmony_ci if (GetVendorLibPath(vendorLibPath) == HDF_SUCCESS) { 15211fccf17Sopenharmony_ci rilLibPath = vendorLibPath; 15311fccf17Sopenharmony_ci } else if (uDevInfo != NULL) { 15411fccf17Sopenharmony_ci rilLibPath = uDevInfo->libPath; 15511fccf17Sopenharmony_ci } else { 15611fccf17Sopenharmony_ci TELEPHONY_LOGE("no vendor lib"); 15711fccf17Sopenharmony_ci return; 15811fccf17Sopenharmony_ci } 15911fccf17Sopenharmony_ci if (rilLibPath == NULL || rilLibPath[0] == '\0') { 16011fccf17Sopenharmony_ci TELEPHONY_LOGE("dynamic library path is empty"); 16111fccf17Sopenharmony_ci return; 16211fccf17Sopenharmony_ci } 16311fccf17Sopenharmony_ci 16411fccf17Sopenharmony_ci TELEPHONY_LOGI("RilInit LoadVendor start with rilLibPath:%{public}s", rilLibPath); 16511fccf17Sopenharmony_ci g_dlHandle = dlopen(rilLibPath, RTLD_NOW); 16611fccf17Sopenharmony_ci if (g_dlHandle == NULL) { 16711fccf17Sopenharmony_ci TELEPHONY_LOGE("dlopen %{public}s is fail. %{public}s", rilLibPath, dlerror()); 16811fccf17Sopenharmony_ci return; 16911fccf17Sopenharmony_ci } 17011fccf17Sopenharmony_ci rilInitOps = (const HRilOps *(*)(const struct HRilReport *))dlsym(g_dlHandle, "RilInitOps"); 17111fccf17Sopenharmony_ci if (rilInitOps == NULL) { 17211fccf17Sopenharmony_ci dlclose(g_dlHandle); 17311fccf17Sopenharmony_ci TELEPHONY_LOGE("RilInit not defined or exported"); 17411fccf17Sopenharmony_ci return; 17511fccf17Sopenharmony_ci } 17611fccf17Sopenharmony_ci HRilInit(); 17711fccf17Sopenharmony_ci ops = rilInitOps(&g_reportOps); 17811fccf17Sopenharmony_ci HRilRegOps(ops); 17911fccf17Sopenharmony_ci TELEPHONY_LOGI("HRilRegOps completed"); 18011fccf17Sopenharmony_ci} 18111fccf17Sopenharmony_ci 18211fccf17Sopenharmony_civoid InitRilAdapter(void) 18311fccf17Sopenharmony_ci{ 18411fccf17Sopenharmony_ci LoadVendor(); 18511fccf17Sopenharmony_ci} 18611fccf17Sopenharmony_ci 18711fccf17Sopenharmony_civoid ReleaseRilAdapter(void) 18811fccf17Sopenharmony_ci{ 18911fccf17Sopenharmony_ci if (g_dlHandle == NULL) { 19011fccf17Sopenharmony_ci TELEPHONY_LOGE("g_dlHandle has been null"); 19111fccf17Sopenharmony_ci return; 19211fccf17Sopenharmony_ci } 19311fccf17Sopenharmony_ci dlclose(g_dlHandle); 19411fccf17Sopenharmony_ci} 195