• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hril_hdf.h"
17 #ifdef UDEV_SUPPORT
18 #include <libudev.h>
19 #endif
20 #include "dlfcn.h"
21 #include "hdf_base.h"
22 #include "hril_enum.h"
23 #include "modem_adapter.h"
24 #include "parameter.h"
25 #include "stdlib.h"
26 #include "telephony_log_c.h"
27 
28 #define RIL_VENDOR_LIB_PATH "persist.sys.radio.vendorlib.path"
29 #define BASE_HEX 16
30 
31 const char *VENDOR_LIB_PATH = "const.telephony.ril.vendorlib.path";
32 static void *g_dlHandle = NULL;
33 static struct HRilReport g_reportOps = {
34     OnCallReport,
35     OnDataReport,
36     OnModemReport,
37     OnNetworkReport,
38     OnSimReport,
39     OnSmsReport,
40     OnTimerCallback
41 };
42 
GetVendorLibPath(char * path)43 static int32_t GetVendorLibPath(char *path)
44 {
45     int32_t code = GetParameter(VENDOR_LIB_PATH, "", path, PARAMETER_SIZE);
46     if (code > 0) {
47         return HDF_SUCCESS;
48     } else {
49         TELEPHONY_LOGE("Failed to get const vendor library path through system properties. err:%{public}d", code);
50     }
51     code = GetParameter(RIL_VENDOR_LIB_PATH, "", path, PARAMETER_SIZE);
52     if (code <= 0) {
53         TELEPHONY_LOGE("Failed to get vendor library path through system properties. err:%{public}d", code);
54         return HDF_FAILURE;
55     }
56     return HDF_SUCCESS;
57 }
58 
59 #ifdef UDEV_SUPPORT
GetPresetInformation(const char * vId,const char * pId)60 static UsbDeviceInfo *GetPresetInformation(const char *vId, const char *pId)
61 {
62     if (vId == NULL || pId == NULL) {
63         return NULL;
64     }
65     char *out = NULL;
66     UsbDeviceInfo *uDevInfo = NULL;
67     int32_t idVendor = (int32_t)strtol(vId, &out, BASE_HEX);
68     int32_t idProduct = (int32_t)strtol(pId, &out, BASE_HEX);
69     for (uint32_t i = 0; i < sizeof(g_usbModemVendorInfo) / sizeof(UsbDeviceInfo); i++) {
70         if (g_usbModemVendorInfo[i].idVendor == idVendor && g_usbModemVendorInfo[i].idProduct == idProduct) {
71             TELEPHONY_LOGI("list index:%{public}d", i);
72             uDevInfo = &g_usbModemVendorInfo[i];
73             break;
74         }
75     }
76     return uDevInfo;
77 }
78 #endif
79 
GetUsbDeviceInfo(void)80 static UsbDeviceInfo *GetUsbDeviceInfo(void)
81 {
82     UsbDeviceInfo *uDevInfo = NULL;
83 #ifdef UDEV_SUPPORT
84     struct udev *udev;
85     struct udev_enumerate *enumerate;
86     struct udev_list_entry *devices, *devListEntry;
87     struct udev_device *dev;
88 
89     udev = udev_new();
90     if (udev == NULL) {
91         TELEPHONY_LOGE("Can't create udev");
92         return uDevInfo;
93     }
94     enumerate = udev_enumerate_new(udev);
95     if (enumerate == NULL) {
96         TELEPHONY_LOGE("Can't create enumerate");
97         udev_unref(udev);
98         return uDevInfo;
99     }
100     udev_enumerate_add_match_subsystem(enumerate, "tty");
101     udev_enumerate_scan_devices(enumerate);
102     devices = udev_enumerate_get_list_entry(enumerate);
103     udev_list_entry_foreach(devListEntry, devices) {
104         const char *path = udev_list_entry_get_name(devListEntry);
105         if (path == NULL) {
106             continue;
107         }
108         dev = udev_device_new_from_syspath(udev, path);
109         if (dev == NULL) {
110             continue;
111         }
112         dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");
113         if (!dev) {
114             TELEPHONY_LOGE("Unable to find parent usb device.");
115             return uDevInfo;
116         }
117         const char *cIdVendor = udev_device_get_sysattr_value(dev, "idVendor");
118         const char *cIdProduct = udev_device_get_sysattr_value(dev, "idProduct");
119         uDevInfo = GetPresetInformation(cIdVendor, cIdProduct);
120         udev_device_unref(dev);
121         if (uDevInfo != NULL) {
122             break;
123         }
124     }
125     udev_enumerate_unref(enumerate);
126     udev_unref(udev);
127 #endif
128     return uDevInfo;
129 }
130 
LoadVendor(void)131 static void LoadVendor(void)
132 {
133     const char *rilLibPath = NULL;
134     char vendorLibPath[PARAMETER_SIZE] = {0};
135     // Pointer to ril init function in vendor ril
136     const HRilOps *(*rilInitOps)(const struct HRilReport *) = NULL;
137     // functions returned by ril init function in vendor ril
138     const HRilOps *ops = NULL;
139 
140     UsbDeviceInfo *uDevInfo = GetUsbDeviceInfo();
141     if (GetVendorLibPath(vendorLibPath) == HDF_SUCCESS) {
142         rilLibPath = vendorLibPath;
143     } else if (uDevInfo != NULL) {
144         rilLibPath = uDevInfo->libPath;
145     } else {
146         TELEPHONY_LOGI("use default vendor lib.");
147         rilLibPath = g_usbModemVendorInfo[DEFAULT_MODE_INDEX].libPath;
148     }
149     if (rilLibPath == NULL) {
150         TELEPHONY_LOGE("dynamic library path is empty");
151         return;
152     }
153 
154     TELEPHONY_LOGI("RilInit LoadVendor start with rilLibPath:%{public}s", rilLibPath);
155     g_dlHandle = dlopen(rilLibPath, RTLD_NOW);
156     if (g_dlHandle == NULL) {
157         TELEPHONY_LOGE("dlopen %{public}s is fail. %{public}s", rilLibPath, dlerror());
158         return;
159     }
160     rilInitOps = (const HRilOps *(*)(const struct HRilReport *))dlsym(g_dlHandle, "RilInitOps");
161     if (rilInitOps == NULL) {
162         dlclose(g_dlHandle);
163         TELEPHONY_LOGE("RilInit not defined or exported");
164         return;
165     }
166     HRilInit();
167     ops = rilInitOps(&g_reportOps);
168     HRilRegOps(ops);
169     TELEPHONY_LOGI("HRilRegOps completed");
170 }
171 
InitRilAdapter(void)172 void InitRilAdapter(void)
173 {
174     LoadVendor();
175 }
176 
ReleaseRilAdapter(void)177 void ReleaseRilAdapter(void)
178 {
179     if (g_dlHandle == NULL) {
180         TELEPHONY_LOGE("g_dlHandle has been null");
181         return;
182     }
183     dlclose(g_dlHandle);
184 }
185