1 /*
2  * Copyright (C) 2021-2022 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 "wifi_hal_adapter.h"
17 #include <dlfcn.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include "securec.h"
23 #include "wifi_common_def.h"
24 #include "wifi_log.h"
25 
26 #undef LOG_TAG
27 #define LOG_TAG "WifiHalAdapter"
28 
29 WifiHalVendorInterface *g_wifiHalVendorInterface = NULL;
30 
31 #define MODULE_NAME_MAX_LEN 256
32 #define MODULE_CONFIG_FILE_PATH CONFIG_ROOR_DIR"/wifi_hal_vendor.conf"
33 #define PATH_NUM 2
34 #define BUFF_SIZE 256
35 
ReadConfigModuleName(char * name,int size)36 static int ReadConfigModuleName(char *name, int size)
37 {
38     if (name == NULL) {
39         return HAL_FAILURE;
40     }
41     FILE *fp = fopen(MODULE_CONFIG_FILE_PATH, "r");
42     if (fp == NULL) {
43         LOGE("open module configuration file failed");
44         return HAL_SUCCESS; /* file not exist, use default operators */
45     }
46     int flag = 0;
47     do {
48         if (fseek(fp, 0, SEEK_END) != 0) {
49             LOGE("ReadConfigModuleName fseek failed!");
50             fclose(fp);
51             return HAL_FAILURE;
52         }
53         int len = ftell(fp);
54         if ((len >= size) || (len == -1)) {
55             LOGE("config file size too big, config file may not correct!");
56             break;
57         }
58         rewind(fp);
59         int ret = fread(name, sizeof(char), (size_t)len, fp);
60         if (ret != len) {
61             LOGE("read file failed!");
62             break;
63         }
64         flag += 1;
65     } while (0);
66     fclose(fp);
67     return (flag == 0) ? -1 : 0;
68 }
69 
OpenHalVendorModule(WifiHalVendorInterface * pInterface)70 static int OpenHalVendorModule(WifiHalVendorInterface *pInterface)
71 {
72     if (pInterface == NULL) {
73         return HAL_FAILURE;
74     }
75     char name[MODULE_NAME_MAX_LEN] = {0};
76     if (ReadConfigModuleName(name, MODULE_NAME_MAX_LEN) < 0) {
77         return HAL_FAILURE;
78     }
79     if (strlen(name) <= 0) {
80         LOGW("module name is null.");
81         return HAL_SUCCESS;
82     }
83 
84     void *handle = dlopen(name, RTLD_LAZY);
85     if (handle == NULL) {
86         LOGE("open config [%{public}s] so failed![%{public}s]", name, dlerror());
87         return HAL_FAILURE;
88     }
89     int flag = 0;
90     do {
91         pInitHalVendorFunc pFunc = (pInitHalVendorFunc)dlsym(handle, "InitHalVendorFunc");
92         if (pFunc == NULL) {
93             LOGE("Not find InitHalVendorFunc, cannot use this [%{public}s] so", name);
94             break;
95         }
96         HalVendorError err = pFunc(&pInterface->func);
97         if (err != HAL_VENDOR_SUCCESS) {
98             LOGE("init hal vendor function table failed! name [%{public}s], ret[%{public}d]", name, err);
99             break;
100         }
101         err = pInterface->func.wifiInitialize();
102         if (err != HAL_VENDOR_SUCCESS) {
103             LOGE("init vendor hal failed!, ret[%{public}d]", err);
104             break;
105         }
106         pInterface->handle = handle;
107         flag += 1;
108     } while (0);
109     if (flag == 0) {
110         dlclose(handle);
111         return HAL_FAILURE;
112     }
113     return HAL_SUCCESS;
114 }
115 
GetWifiHalVendorInterface(void)116 WifiHalVendorInterface *GetWifiHalVendorInterface(void)
117 {
118     if (g_wifiHalVendorInterface != NULL) {
119         return g_wifiHalVendorInterface;
120     }
121     g_wifiHalVendorInterface = (WifiHalVendorInterface *)calloc(1, sizeof(WifiHalVendorInterface));
122     if (g_wifiHalVendorInterface == NULL) {
123         return NULL;
124     }
125     InitDefaultHalVendorFunc(&g_wifiHalVendorInterface->func);
126     int ret = OpenHalVendorModule(g_wifiHalVendorInterface);
127     if (ret < 0) {
128         ReleaseWifiHalVendorInterface();
129     }
130     return g_wifiHalVendorInterface;
131 }
132 
ReleaseWifiHalVendorInterface(void)133 void ReleaseWifiHalVendorInterface(void)
134 {
135     if (g_wifiHalVendorInterface != NULL) {
136         if (g_wifiHalVendorInterface->handle != NULL) {
137             if (g_wifiHalVendorInterface->func.wifiCleanUp) {
138                 g_wifiHalVendorInterface->func.wifiCleanUp();
139             }
140             dlclose(g_wifiHalVendorInterface->handle);
141         }
142         free(g_wifiHalVendorInterface);
143         g_wifiHalVendorInterface = NULL;
144     }
145     return;
146 }
147 
ExcuteCmd(const char * szCmd)148 int ExcuteCmd(const char *szCmd)
149 {
150     LOGI("Execute cmd: %{private}s", szCmd);
151     int ret = system(szCmd);
152     if (ret == -1) {
153         LOGE("Execute system cmd %{private}s failed!", szCmd);
154         return HAL_FAILURE;
155     }
156     if (WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)) {
157         return HAL_SUCCESS;
158     }
159     LOGE("Execute system cmd %{private}s failed: %{private}d", szCmd, WEXITSTATUS(ret));
160     return HAL_FAILURE;
161 }
162 
FileIsExisted(const char * file)163 int FileIsExisted(const char* file)
164 {
165     if (file == NULL) {
166         LOGE("%{pubic}s: invalid parameter", __func__);
167         return HAL_FAILURE;
168     }
169     if (access(file, F_OK) != -1) {
170         return HAL_SUCCESS;
171     }
172     LOGE("%{public}s: file isn't existed", __func__);
173     return HAL_FAILURE;
174 }
175 
CopyConfigFile(const char * configName)176 int CopyConfigFile(const char* configName)
177 {
178     char buf[BUFF_SIZE] = {0};
179     if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%s/wpa_supplicant/%s", CONFIG_ROOR_DIR, configName) < 0) {
180         LOGE("snprintf_s dest dir failed.");
181         return HAL_FAILURE;
182     }
183     char path[PATH_NUM][BUFF_SIZE] = {"/system/etc/wifi/", "/vendor/etc/wifi/"};
184     for (int i = 0; i != PATH_NUM; ++i) {
185         if (strcat_s(path[i], sizeof(path[i]), configName) != EOK) {
186             LOGE("strcat_s failed.");
187             return HAL_FAILURE;
188         }
189         if (access(path[i], F_OK) != -1) {
190             char cmd[BUFF_SIZE] = {0};
191             char dstPath[BUFF_SIZE] = P2P_CONFIG_DIR;
192             if (strcat_s(dstPath, sizeof(dstPath), configName) != EOK) {
193                 LOGE("%{public}s: failed to strcat_s %{public}s", __func__, configName);
194                 return HAL_FAILURE;
195             }
196             LOGD("%{public}s: destination is %{public}s", __func__, dstPath);
197             if ((strcmp(dstPath, P2P_WPA_CONFIG_FILE) == 0) && (FileIsExisted(dstPath) == HAL_SUCCESS)) {
198                 LOGW("%{public}s: dstPath is existed", __func__);
199                 memset_s(dstPath, sizeof(dstPath), 0x0, sizeof(dstPath));
200                 continue;
201             }
202             memset_s(dstPath, sizeof(dstPath), 0x0, sizeof(dstPath));
203             if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1,
204                 "cp %s %s/wpa_supplicant/", path[i], CONFIG_ROOR_DIR) < 0) {
205                 LOGE("snprintf_s cp cmd failed.");
206                 return HAL_FAILURE;
207             }
208             return ExcuteCmd(cmd);
209         }
210     }
211     LOGD("success to copy file %{public}s", configName);
212     return HAL_SUCCESS;
213 }