• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "wpa_common_cmd.h"
16 
17 #include <hdf_log.h>
18 #include <string.h>
19 #include <securec.h>
20 #include <hdf_base.h>
21 #include <osal_time.h>
22 #include <osal_mem.h>
23 #include <arpa/inet.h>
24 #include <dirent.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <dlfcn.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <dlfcn.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <pthread.h>
34 
35 #include "hdi_wpa_hal.h"
36 #include "utils/common.h"
37 #include "wpa_supplicant_i.h"
38 #include "ctrl_iface.h"
39 #include "main.h"
40 #include "wps_supplicant.h"
41 #include "config.h"
42 #include "common/defs.h"
43 #include "common/wpa_ctrl.h"
44 #include "ethernet_eap_client.h"
45 #include "securec.h"
46 #include "wpa_hdi_util.h"
47 
48 #ifdef LOG_TAG
49 #undef LOG_TAG
50 #endif
51 #define LOG_TAG "EthWpaCmd"
52 #ifdef LOG_DOMAIN
53 #undef LOG_DOMAIN
54 #endif
55 #define LOG_DOMAIN 0xD0015b0
56 
57 #define BUF_SIZE 2048
58 #define START_CMD_BUF_SIZE 512
59 #define WPA_CMD_RETURN_TIMEOUT (-2)
60 #define WPA_SLEEP_TIME (100 * 1000) /* 100ms */
61 #define MAX_WPA_WAIT_TIMES 30
62 #define CTRL_LEN 128
63 
64 pthread_t g_tid;
65 pthread_mutex_t g_wpaLock = PTHREAD_MUTEX_INITIALIZER;
66 
SplitCmdString(const char * startCmd,struct WpaMainParam * pParam)67 static void SplitCmdString(const char *startCmd, struct WpaMainParam *pParam)
68 {
69     if (pParam == NULL) {
70         return;
71     }
72     if (startCmd == NULL) {
73         pParam->argc = 0;
74         return;
75     }
76     const char *p = startCmd;
77     int i = 0;
78     int j = 0;
79     while (*p != '\0') {
80         if (*p == ' ') {
81             if (j <= MAX_WPA_MAIN_ARGV_LEN - 1) {
82                 pParam->argv[i][j] = '\0';
83             } else {
84                 pParam->argv[i][MAX_WPA_MAIN_ARGV_LEN - 1] = '\0';
85             }
86             ++i;
87             j = 0;
88             if (i >= MAX_WPA_MAIN_ARGC_NUM) {
89                 break;
90             }
91         } else {
92             if (j < MAX_WPA_MAIN_ARGV_LEN - 1) {
93                 pParam->argv[i][j] = *p;
94                 ++j;
95             }
96         }
97         ++p;
98     }
99     if (i >= MAX_WPA_MAIN_ARGC_NUM) {
100         pParam->argc = MAX_WPA_MAIN_ARGC_NUM;
101     } else {
102         pParam->argc = i + 1;
103     }
104 }
105 
WpaThreadMain(void * p)106 static void *WpaThreadMain(void *p)
107 {
108     const char *startCmd;
109     struct WpaMainParam param = {0};
110     char *tmpArgv[MAX_WPA_MAIN_ARGC_NUM] = {0};
111     if (p == NULL) {
112         HDF_LOGE("%{public}s: input parameter invalid!", __func__);
113         return NULL;
114     }
115     startCmd = (const char *)p;
116     HDF_LOGI("%{public}s: run wpa_main -> %{public}s.", __func__, startCmd);
117     SplitCmdString(startCmd, &param);
118     for (int i = 0; i < param.argc; i++) {
119         tmpArgv[i] = param.argv[i];
120     }
121     int ret = wpa_main(param.argc, tmpArgv);
122     HDF_LOGI("%{public}s: run wpa_main ret:%{public}d.", __func__, ret);
123     g_tid = 0;
124     return NULL;
125 }
126 
StartWpaSupplicant(const char * startCmd)127 static int32_t StartWpaSupplicant(const char *startCmd)
128 {
129     int32_t ret;
130     int32_t times = 0;
131     if (startCmd == NULL) {
132         HDF_LOGE("%{public}s input parameter invalid!", __func__);
133         return HDF_ERR_INVALID_PARAM ;
134     }
135     while (g_tid != 0) {
136         HDF_LOGI("%{public}s: wpa_supplicant is already running!", __func__);
137         usleep(WPA_SLEEP_TIME);
138         times++;
139         if (times > MAX_WPA_WAIT_TIMES) {
140             HDF_LOGE("%{public}s: wait supplicant time out!", __func__);
141             return HDF_FAILURE;
142         }
143     }
144     ret = pthread_create(&g_tid, NULL, WpaThreadMain, (void *)startCmd);
145     if (ret != HDF_SUCCESS) {
146         HDF_LOGE("%{public}s: Create wpa thread failed, error code: %{public}d", __func__, ret);
147         return HDF_FAILURE;
148     }
149     pthread_setname_np(g_tid, "WpaMainThread");
150     HDF_LOGI("%{public}s: pthread_create successfully.", __func__);
151     usleep(WPA_SLEEP_TIME);
152     EthWpaInstance *pWpaInstance = GetEthWpaGlobalInstance();
153     if (pWpaInstance == NULL) {
154         HDF_LOGE("Get wpa interface failed!");
155         return HDF_FAILURE;
156     }
157     if (pWpaInstance->wpaCliConnect(pWpaInstance) < 0) {
158         HDF_LOGE("Failed to connect to wpa!");
159         return HDF_FAILURE;
160     }
161     return HDF_SUCCESS;
162 }
163 
RemoveLostCtrl(void)164 static void RemoveLostCtrl(void)
165 {
166     DIR *dir = NULL;
167     char path[CTRL_LEN];
168     struct dirent *entry;
169     dir = opendir(CONFIG_ROOR_DIR);
170     if (dir == NULL) {
171         HDF_LOGE("can not open dir");
172         return;
173     }
174     while ((entry = readdir(dir)) != NULL) {
175         if (strncmp(entry->d_name, "wpa_ctrl_", strlen("wpa_ctrl_")) != 0) {
176             continue;
177         }
178         int ret = sprintf_s(path, sizeof(path), "%s/%s", CONFIG_ROOR_DIR, entry->d_name);
179         if (ret == -1) {
180             HDF_LOGE("sprintf_s dir name fail");
181             break;
182         }
183         if (entry->d_type != DT_DIR) {
184             remove(path);
185         }
186     }
187     closedir(dir);
188 }
189 
EthStartEap(struct IEthernet * self,const char * ifName)190 int32_t EthStartEap(struct IEthernet *self, const char *ifName)
191 {
192     int32_t ret;
193     (void)self;
194     HDF_LOGI("enter %{public}s", __func__);
195     InitEthWpaGlobalInstance();
196     EthWpaInstance *pWpaInstance = GetEthWpaGlobalInstance();
197     if (pWpaInstance == NULL) {
198         HDF_LOGI("fail get global interface");
199         return HDF_FAILURE;
200     }
201     pthread_mutex_lock(&g_wpaLock);
202     RemoveLostCtrl();
203     char startCmd[START_CMD_BUF_SIZE];
204     ret = sprintf_s(startCmd, sizeof(startCmd), "%s -i%s", START_CMD, ifName);
205     if (ret == -1) {
206         pthread_mutex_unlock(&g_wpaLock);
207         HDF_LOGE("%{public}s: sprintf_s start cmd fail", __func__);
208         return HDF_FAILURE;
209     }
210     ret = StartWpaSupplicant(startCmd);
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("%{public}s: StartWpaSupplicant failed, error code: %{public}d", __func__, ret);
213         pthread_mutex_unlock(&g_wpaLock);
214         return HDF_FAILURE;
215     }
216     pthread_mutex_unlock(&g_wpaLock);
217     HDF_LOGI("%{public}s: wpa_supplicant start successfully!", __func__);
218     return HDF_SUCCESS;
219 }
220 
StopWpaSupplicant(void)221 static int32_t StopWpaSupplicant(void)
222 {
223     EthWpaInstance *pWpaInstance = GetEthWpaGlobalInstance();
224     if (pWpaInstance == NULL) {
225         HDF_LOGE("%{public}s: Get wpa global interface failed!", __func__);
226         return HDF_FAILURE;
227     }
228     int ret = pWpaInstance->wpaCliTerminate();
229     HDF_LOGI("%{public}s: wpaCliTerminate ret = %{public}d", __func__, ret);
230     return HDF_SUCCESS;
231 }
232 
EthStopEap(struct IEthernet * self,const char * ifName)233 int32_t EthStopEap(struct IEthernet *self, const char *ifName)
234 {
235     int32_t ret;
236     int32_t times = 0;
237     (void)self;
238     pthread_mutex_lock(&g_wpaLock);
239     HDF_LOGI("enter %{public}s", __func__);
240     ret = StopWpaSupplicant();
241     if (ret != HDF_SUCCESS) {
242         HDF_LOGE("%{public}s: stop failed, error code: %{public}d", __func__, ret);
243         pthread_mutex_unlock(&g_wpaLock);
244         return HDF_FAILURE;
245     }
246     while (g_tid != 0) {
247         HDF_LOGI("%{public}s: wpa_supplicant is not stop!", __func__);
248         usleep(WPA_SLEEP_TIME);
249         times++;
250         if (times > MAX_WPA_WAIT_TIMES) {
251             HDF_LOGE("%{public}s: wait supplicant stop time out!", __func__);
252             break;
253         }
254     }
255     ReleaseEthWpaGlobalInstance();
256     pthread_mutex_unlock(&g_wpaLock);
257     HDF_LOGI("%{public}s: wpa_supplicant stop successfully!", __func__);
258     return HDF_SUCCESS;
259 }
260 
EthEapShellCmd(struct IEthernet * self,const char * ifName,const char * cmd)261 int32_t EthEapShellCmd(struct IEthernet *self, const char *ifName, const char *cmd)
262 {
263     (void)self;
264     HDF_LOGI("enter %{public}s", __func__);
265     pthread_mutex_lock(&g_wpaLock);
266     if (ifName == NULL || cmd == NULL) {
267         pthread_mutex_unlock(&g_wpaLock);
268         HDF_LOGE("%{public}s: input param invalid!", __func__);
269         return HDF_ERR_INVALID_PARAM;
270     }
271     EthWpaInstance *pWpaInstance = GetEthWpaGlobalInstance();
272     if (pWpaInstance == NULL) {
273         pthread_mutex_unlock(&g_wpaLock);
274         HDF_LOGE("%{public}s: pWpaInstance = NULL", __func__);
275         return HDF_FAILURE;
276     }
277     int ret = pWpaInstance->wpaCliCmdStaShellCmd(pWpaInstance, ifName, cmd);
278     if (ret < 0) {
279         pthread_mutex_unlock(&g_wpaLock);
280         HDF_LOGE("%{public}s: fail ret = %{public}d", __func__, ret);
281         return HDF_FAILURE;
282     }
283     pthread_mutex_unlock(&g_wpaLock);
284     HDF_LOGI("%{public}s: success", __func__);
285     return HDF_SUCCESS;
286 }
287 
EthRegisterEapEventCallback(struct IEthernet * self,struct IEthernetCallback * cbFunc,const char * ifName)288 int32_t EthRegisterEapEventCallback(struct IEthernet *self, struct IEthernetCallback *cbFunc,
289     const char *ifName)
290 {
291     int32_t ret = HDF_FAILURE;
292     (void)self;
293     pthread_mutex_lock(&g_wpaLock);
294     if (cbFunc == NULL || ifName == NULL) {
295         pthread_mutex_unlock(&g_wpaLock);
296         HDF_LOGE("%{public}s: input parameter invalid!", __func__);
297         return HDF_ERR_INVALID_PARAM;
298     }
299     ret = EthEapClientRegisterCallback(cbFunc, ifName);
300     if (ret != HDF_SUCCESS) {
301         HDF_LOGE("%{public}s: Register failed!, error code: %{public}d", __func__, ret);
302     } else {
303         HDF_LOGI("%{public}s: Register success", __func__);
304     }
305     pthread_mutex_unlock(&g_wpaLock);
306     return ret;
307 }
308 
EthUnregisterEapEventCallback(struct IEthernet * self,struct IEthernetCallback * cbFunc,const char * ifName)309 int32_t EthUnregisterEapEventCallback(struct IEthernet *self, struct IEthernetCallback *cbFunc,
310     const char *ifName)
311 {
312     (void)self;
313     pthread_mutex_lock(&g_wpaLock);
314     if (cbFunc == NULL || ifName == NULL) {
315         pthread_mutex_unlock(&g_wpaLock);
316         HDF_LOGE("%{public}s: input parameter invalid!", __func__);
317         return HDF_ERR_INVALID_PARAM;
318     }
319     int32_t ret = EthEapClientUnregisterCallback(cbFunc, ifName);
320     if (ret != HDF_SUCCESS) {
321         HDF_LOGE("%{public}s: Unregister failed!, error code: %{public}d", __func__, ret);
322     } else {
323         HDF_LOGI("%{public}s: Register success", __func__);
324     }
325     pthread_mutex_unlock(&g_wpaLock);
326     return HDF_SUCCESS;
327 }
328