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