• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "hdi_hostapd_hal.h"
17 
18 #include <errno.h>
19 #include <hdf_base.h>
20 #include <hdf_log.h>
21 #include <linux/wireless.h>
22 #include <malloc.h>
23 #include <poll.h>
24 #include <pthread.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/ioctl.h>
29 #include <unistd.h>
30 
31 #include "common/wpa_ctrl.h"
32 #include "securec.h"
33 
34 #undef LOG_DOMAIN
35 #define LOG_DOMAIN 0xD001560
36 
37 #undef LOG_TAG
38 #define LOG_TAG "HdiHostapdHal"
39 
40 #define CONFIG_ROOR_DIR "/data/service/el1/public/wifi"
41 
42 #define CONFIG_DENY_MAC_FILE_NAME "deny_mac.conf"
43 #define SLEEP_TIME_100_MS (100 * 1000)
44 #define CONFIG_PATH_DIR CONFIG_ROOR_DIR"/wpa_supplicant"
45 #define CTRL_LEN 128
46 #define IFACENAME_LEN 6
47 #define CFGNAME_LEN 30
48 #define MAX_RETRY_COUNT 20
49 
50 #if (AP_NUM > 1)
51 #define WIFI_5G_CFG "hostapd_0.conf"
52 #define WIFI_2G_CFG "hostapd_1.conf"
53 #define HOSTAPD_5G_CFG CONFIG_ROOR_DIR"/wpa_supplicant/"WIFI_5G_CFG
54 #define HOSTAPD_2G_CFG CONFIG_ROOR_DIR"/wpa_supplicant/"WIFI_2G_CFG
55 #define HOSTAPD_5G_UDPPORT ""
56 #define HOSTAPD_2G_UDPPORT ""
57 
58 WifiHostapdHalDeviceInfo g_hostapdHalDevInfo[] = {
59     {AP_5G_MAIN_INSTANCE, NULL, WIFI_5G_CFG, HOSTAPD_5G_CFG, HOSTAPD_5G_UDPPORT},
60     {AP_2G_MAIN_INSTANCE, NULL, WIFI_2G_CFG, HOSTAPD_2G_CFG, HOSTAPD_2G_UDPPORT},
61 };
62 #else
63 #define AP_IFNAME "wlan0"
64 #define AP_IFNAME_COEX "wlan1"
65 #define HOSTAPD_DEFAULT_CFG "hostapd.conf"
66 #define HOSTAPD_CTRL_GLOBAL_INTERFACE CONFIG_ROOR_DIR"/sockets/wpa/hostapd"
67 #define HOSTAPD_DEFAULT_CFG_PATH CONFIG_ROOR_DIR"/wpa_supplicant/"HOSTAPD_DEFAULT_CFG
68 #define HOSTAPD_DEFAULT_UDPPORT ""
69 #define AP_SET_CFG_DELAY 500000
70 #define SOFTAP_MAX_BUFFER_SIZE 4096
71 #define IFNAMSIZ 16
72 #define ADDITIONAL_SPACE_FOR_FORMATTING 3
73 
74 WifiHostapdHalDeviceInfo g_hostapdHalDevInfo[] = {
75     {AP_2G_MAIN_INSTANCE, NULL, HOSTAPD_DEFAULT_CFG, HOSTAPD_DEFAULT_CFG_PATH, HOSTAPD_DEFAULT_UDPPORT}
76 };
77 static char g_ctrlInterfacel[CTRL_LEN];
78 static char g_hostapdCfg[CTRL_LEN];
79 static char g_apIfaceName[IFACENAME_LEN];
80 static char g_apCfgName[CFGNAME_LEN];
81 static char g_hostapdPasswd[CTRL_LEN];
82 #endif
83 
84 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
85 
InitCfg(const char * ifaceName)86 int InitCfg(const char *ifaceName)
87 {
88     if (memcpy_s(g_apCfgName, CFGNAME_LEN, HOSTAPD_DEFAULT_CFG, sizeof(HOSTAPD_DEFAULT_CFG)) != EOK) {
89         HDF_LOGE("memcpy cfg fail");
90         return -1;
91     }
92     if (memcpy_s(g_apIfaceName, IFACENAME_LEN, ifaceName, strlen(ifaceName)) != EOK) {
93         HDF_LOGE("memcpy ap name fail");
94         return -1;
95     }
96     if (memcpy_s(g_hostapdCfg, CTRL_LEN, HOSTAPD_DEFAULT_CFG_PATH,
97         sizeof(HOSTAPD_DEFAULT_CFG_PATH)) != EOK) {
98         HDF_LOGE("memcpy hostapd fail");
99         return -1;
100     }
101     if (memcpy_s(g_ctrlInterfacel, CTRL_LEN, HOSTAPD_CTRL_GLOBAL_INTERFACE,
102         sizeof(HOSTAPD_CTRL_GLOBAL_INTERFACE)) != EOK) {
103         HDF_LOGE("memcpy ctrl fail");
104         return -1;
105     }
106     g_hostapdHalDevInfo[0].cfgName = g_apCfgName;
107     g_hostapdHalDevInfo[0].config = g_hostapdCfg;
108     return 0;
109 }
110 
GetWifiCfg(int * len)111 const WifiHostapdHalDeviceInfo *GetWifiCfg(int *len)
112 {
113     *len = sizeof(g_hostapdHalDevInfo) / sizeof(WifiHostapdHalDeviceInfo);
114     return g_hostapdHalDevInfo;
115 }
116 
ReleaseHostapdCtrl(int id)117 static void ReleaseHostapdCtrl(int id)
118 {
119     if (g_hostapdHalDevInfo[id].hostapdHalDev == NULL) {
120         return;
121     }
122     if (g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn != NULL) {
123         wpa_ctrl_close(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn);
124         g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn = NULL;
125     }
126     if (g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv != NULL) {
127         wpa_ctrl_close(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv);
128         g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv = NULL;
129     }
130 }
131 
InitHostapdCtrl(const char * ctrlPath,int id)132 static int InitHostapdCtrl(const char *ctrlPath, int id)
133 {
134     if (g_hostapdHalDevInfo[id].hostapdHalDev == NULL || ctrlPath == NULL) {
135         HDF_LOGE("InitHostapdCtrl id %{public}d hostapdHalDev or ifname is null", id);
136         return -1;
137     }
138     int flag = 0;
139     do {
140         g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv = wpa_ctrl_open(ctrlPath);
141         if (g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv == NULL) {
142             HDF_LOGE("open hostapd control interface ctrlRecv failed");
143             break;
144         }
145         if (wpa_ctrl_attach(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv) != 0) {
146             HDF_LOGE("attach hostapd monitor interface failed");
147             break;
148         }
149         g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn = wpa_ctrl_open(ctrlPath);
150         if (g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn == NULL) {
151             HDF_LOGE("open hostapd control interface ctrlConn failed");
152             break;
153         }
154         flag += 1;
155     } while (0);
156     if (!flag) {
157         ReleaseHostapdCtrl(id);
158         return -1;
159     }
160     return 0;
161 }
162 
GetDestPort(char * destPort,size_t len,int id)163 void GetDestPort(char *destPort, size_t len, int id)
164 {
165     if (strcpy_s(destPort, len, g_hostapdHalDevInfo[id].udpPort) != EOK) {
166         HDF_LOGE("failed to copy the destPort");
167     }
168 }
169 
GetCtrlInterface(char * ctrlPath,size_t len,int id)170 static void GetCtrlInterface(char *ctrlPath, size_t len, int id)
171 {
172     if (strcpy_s(ctrlPath, len, g_ctrlInterfacel) != EOK) {
173         HDF_LOGE("failed to copy the ctrl_path");
174     }
175 }
176 
HostapdCliConnect(int id)177 static int HostapdCliConnect(int id)
178 {
179     if (g_hostapdHalDevInfo[id].hostapdHalDev == NULL) {
180         HDF_LOGE("hostapdHalDev is NULL");
181         return -1;
182     }
183     if (g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn != NULL) {
184         HDF_LOGI("Hostapd already initialized");
185         return 0;
186     }
187     int retryCount = MAX_RETRY_COUNT;
188     char ctrlPath[BUFFER_SIZE_128] = {0};
189     GetCtrlInterface(ctrlPath, sizeof(ctrlPath), id);
190     HDF_LOGI("HostapdCliConnect Ifname is: %{public}s", ctrlPath);
191     while (retryCount-- > 0) {
192         if (InitHostapdCtrl(ctrlPath, id) == 0) {
193             HDF_LOGI("Global hostapd interface connect successfully");
194             break;
195         } else {
196             HDF_LOGD("Init hostapd ctrl failed");
197         }
198         usleep(SLEEP_TIME_100_MS);
199     }
200     if (retryCount <= 0) {
201         HDF_LOGI("Retry init hostapd ctrl failed, retryCount: %{public}d", retryCount);
202         return -1;
203     }
204     return 0;
205 }
206 
HostapdCliClose(int id)207 static int HostapdCliClose(int id)
208 {
209     if (g_hostapdHalDevInfo[id].hostapdHalDev == NULL) {
210         return 0;
211     }
212     if (g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn != NULL) {
213         wpa_ctrl_close(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv);
214         g_hostapdHalDevInfo[id].hostapdHalDev->ctrlRecv = NULL;
215         wpa_ctrl_close(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn);
216         g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn = NULL;
217     }
218     return 0;
219 }
220 
WpaCtrlCommand(struct wpa_ctrl * ctrl,const char * cmd,char * buf,size_t bufSize)221 static int WpaCtrlCommand(struct wpa_ctrl *ctrl, const char *cmd, char *buf, size_t bufSize)
222 {
223     HDF_LOGI("enter WpaCtrlCommand");
224     if (ctrl == NULL || cmd == NULL || buf == NULL || bufSize <= 0) {
225         HDF_LOGE("Request parameters not correct");
226         return -1;
227     }
228     size_t len = bufSize - 1;
229     HDF_LOGD("wpa_ctrl_request -> cmd: %{private}s", cmd);
230     int ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL);
231     if (ret == REQUEST_FAILED) {
232         HDF_LOGE("[%{private}s] command timed out", cmd);
233         return ret;
234     } else if (ret < 0) {
235         HDF_LOGE("[%{private}s] command failed", cmd);
236         return -1;
237     }
238     if (len < bufSize) {
239         buf[len] = '\0';
240     } else {
241         HDF_LOGE("len is invalid,current len is %{public}zu, bufSize is %{public}zu", len, bufSize);
242         return -1;
243     }
244     if (memcmp(buf, "FAIL", FAIL_LENGTH) == 0) {
245         HDF_LOGE("[%{private}s] request success, but result %{public}s", cmd, buf);
246         return -1;
247     }
248     return 0;
249 }
250 
ReleaseHostapdDev(int id)251 void ReleaseHostapdDev(int id)
252 {
253     if (g_hostapdHalDevInfo[id].hostapdHalDev != NULL) {
254         HostapdCliClose(id);
255         free(g_hostapdHalDevInfo[id].hostapdHalDev);
256         g_hostapdHalDevInfo[id].hostapdHalDev = NULL;
257     }
258 }
259 
GetIfaceState(const char * ifaceName)260 int GetIfaceState(const char *ifaceName)
261 {
262     int state = 0;
263     int sock = socket(AF_INET, SOCK_DGRAM, 0);
264     if (sock < 0) {
265         HDF_LOGE("GetIfaceState: create socket fail");
266         return state;
267     }
268 
269     struct ifreq ifr = {};
270     (void)memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
271     if (strcpy_s(ifr.ifr_name, IFNAMSIZ, ifaceName) != EOK) {
272         HDF_LOGE("GetIfaceState: strcpy_s fail");
273         close(sock);
274         return state;
275     }
276     if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
277         HDF_LOGE("GetIfaceState: can not get interface state: %{public}s", ifaceName);
278         close(sock);
279         return state;
280     }
281     state = ((ifr.ifr_flags & IFF_UP) > 0 ? 1 : 0);
282     HDF_LOGD("GetIfaceState: current interface state: %{public}d", state);
283     close(sock);
284     return state;
285 }
286 
InitHostapdHal(int id)287 static int InitHostapdHal(int id)
288 {
289     if (g_hostapdHalDevInfo[id].hostapdHalDev == NULL) {
290         HDF_LOGE("InitHostapdHal id %d hostapdHalDev is null", id);
291         return -1;
292     }
293     if (HostapdCliConnect(id) != 0) {
294         HDF_LOGE("InitHostapdHal id %d HostapdCliConnect fail", id);
295         return -1;
296     }
297     return 0;
298 }
299 
EnableAp(int id)300 static int EnableAp(int id)
301 {
302     char cmdAdd[BUFSIZE_CMD] = {0};
303     char cmdSet[BUFSIZE_CMD] = {0};
304     char cmdEnable[BUFSIZE_CMD] = {0};
305     char buf[BUFSIZE_REQUEST_SMALL] = {0};
306     if (sprintf_s(cmdSet, sizeof(cmdSet), "SET_WPA_PASS %s", g_hostapdPasswd) < 0) {
307         HDF_LOGE("set ap passphrase sprintf_s fail");
308         return -1;
309     }
310     if (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmdSet, buf, sizeof(buf)) < 0) {
311         HDF_LOGE("set ap passphrase failed");
312         return -1;
313     }
314     if (sprintf_s(cmdAdd, sizeof(cmdAdd), "ADD %s config=%s", g_apIfaceName, g_hostapdCfg) < 0) {
315         HDF_LOGE("add config sprintf_s fail");
316         return -1;
317     }
318     HDF_LOGD("cmdAdd is %{public}s", cmdAdd);
319     if (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmdAdd, buf, sizeof(buf)) < 0) {
320         HDF_LOGE("add ap failed");
321         return -1;
322     }
323     if (sprintf_s(cmdEnable, sizeof(cmdEnable), "IFNAME=%s ENABLE", g_apIfaceName) < 0) {
324         HDF_LOGE("enableAp sprintf_s fail");
325         return -1;
326     }
327     HDF_LOGD("enable ap cmd is %{public}s", cmdEnable);
328     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmdEnable, buf, sizeof(buf));
329 }
330 
DisableAp(int id)331 static int DisableAp(int id)
332 {
333     char cmd[BUFSIZE_CMD] = {0};
334     char buf[BUFSIZE_REQUEST_SMALL] = {0};
335     if (sprintf_s(cmd, sizeof(cmd), "REMOVE %s", g_apIfaceName) < 0) {
336         HDF_LOGE("remove ap sprintf_s fail");
337         return -1;
338     }
339     HDF_LOGD("remove ap cmd is %{public}s", cmd);
340     g_hostapdHalDevInfo[id].hostapdHalDev->execDisable = 1;
341     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
342 }
343 
StopAp(int id)344 static int StopAp(int id)
345 {
346     char buf[BUFSIZE_REQUEST_SMALL] = {0};
347     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, "TERMINATE", buf, sizeof(buf));
348 }
349 
SetApName(const char * name,int id)350 static int SetApName(const char *name, int id)
351 {
352     if (name == NULL) {
353         HDF_LOGE("SetApName name is null");
354         return -1;
355     }
356     char cmd[BUFSIZE_CMD] = {0};
357     char buf[BUFSIZE_REQUEST_SMALL] = {0};
358 
359     if (sprintf_s(cmd, sizeof(cmd), "SET ssid %s", name) < 0) {
360         HDF_LOGE("SetApName sprintf_s fail");
361         return -1;
362     }
363     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
364 }
365 
SetApRsnPairwise(const char * type,int id)366 static int SetApRsnPairwise(const char *type, int id)
367 {
368     if (type == NULL) {
369         HDF_LOGE("SetApRsnPairwise type is null");
370         return -1;
371     }
372 
373     char cmd[BUFSIZE_CMD] = {0};
374     char buf[BUFSIZE_REQUEST_SMALL] = {0};
375 
376     if (sprintf_s(cmd, sizeof(cmd), "SET rsn_pairwise %s", type) < 0) {
377         HDF_LOGE("SetApRsnPairwise sprintf_s fail");
378         return -1;
379     }
380     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
381 }
382 
SetApWpaPairwise(const char * type,int id)383 static int SetApWpaPairwise(const char *type, int id)
384 {
385     if (type == NULL) {
386         HDF_LOGE("SetApWpaPairwise type is null");
387         return -1;
388     }
389     char cmd[BUFSIZE_CMD] = {0};
390     char buf[BUFSIZE_REQUEST_SMALL] = {0};
391 
392     if (sprintf_s(cmd, sizeof(cmd), "SET wpa_pairwise %s", type) < 0) {
393         HDF_LOGE("SetApWpaPairwise sprintf_s fail");
394         return -1;
395     }
396     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
397 }
398 
SetApWpaKeyMgmt(const char * type,int id)399 static int SetApWpaKeyMgmt(const char *type, int id)
400 {
401     if (type == NULL) {
402         HDF_LOGE("SetApWpaPairwise type is null");
403         return -1;
404     }
405     char cmd[BUFSIZE_CMD] = {0};
406     char buf[BUFSIZE_REQUEST_SMALL] = {0};
407 
408     if (sprintf_s(cmd, sizeof(cmd), "SET wpa_key_mgmt %s", type) < 0) {
409         HDF_LOGE("SetApWpaKeyMgmt sprintf_s fail");
410         return -1;
411     }
412     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
413 }
414 
SetApWpaValue(int securityType,int id)415 static int SetApWpaValue(int securityType, int id)
416 {
417     int retval = -1;
418     char cmd[BUFSIZE_CMD] = {0};
419     char buf[BUFSIZE_REQUEST_SMALL] = {0};
420 
421     switch (securityType) {
422         case NONE: /* The authentication mode is NONE. */
423             retval = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "SET wpa 0");
424             break;
425         case WPA_PSK: /* The authentication mode is WPA-PSK. */
426             retval = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "SET wpa 1");
427             break;
428         case WPA2_PSK: /* The authentication mode is WPA2-PSK. */
429             retval = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "SET wpa 2");
430             break;
431         default:
432             HDF_LOGE("Unknown encryption type");
433             return retval;
434     }
435     if (retval < 0) {
436         HDF_LOGE("%{public}s snprintf_s failed, cmd is: %{public}s, type is: %{public}d", __func__, cmd, securityType);
437         return -1;
438     }
439 
440     retval = WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
441     if (retval == 0 && securityType != NONE) {
442         /*
443          * If the value of wpa is switched between 0, 1, and 2, the wpa_key_mgmt,
444          * wpa_pairwise, and rsn_pairwise attributes must be set. Otherwise, the
445          * enable or STA cannot be connected.
446          */
447         retval = SetApWpaKeyMgmt("WPA-PSK", id);
448     }
449     if (retval == 0 && securityType == WPA_PSK) {
450         retval = SetApWpaPairwise("CCMP", id);
451     }
452     if (retval == 0 && securityType == WPA2_PSK) {
453         retval = SetApRsnPairwise("CCMP", id);
454     }
455     if (retval != 0) {
456         HDF_LOGE("%{public}s: hostapd failed to set securityType", __func__);
457         return -1;
458     }
459     return retval;
460 }
461 
SetApPasswd(const char * pass,int id)462 static int SetApPasswd(const char *pass, int id)
463 {
464     if (pass == NULL) {
465         HDF_LOGE("SetApPasswd pass is null");
466         return -1;
467     }
468     if (memset_s(g_hostapdPasswd, CTRL_LEN, 0, strlen(g_hostapdPasswd)) != 0) {
469         HDF_LOGE("SetApPasswd memset_s is null");
470         return -1;
471     }
472     if (memcpy_s(g_hostapdPasswd, CTRL_LEN, pass, strlen(pass)) != 0) {
473         HDF_LOGE("SetApPasswd memcpy_s fail");
474         return -1;
475     }
476     return 0;
477 }
478 
SetApChannel(int channel,int id)479 static int SetApChannel(int channel, int id)
480 {
481     char cmd[BUFSIZE_CMD] = {0};
482     char buf[BUFSIZE_REQUEST_SMALL] = {0};
483 
484     if (sprintf_s(cmd, sizeof(cmd), "SET channel %d", channel) < 0) {
485         HDF_LOGE("SetApChannel sprintf_s fail");
486         return -1;
487     }
488     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
489 }
490 
SetApWmm(int value,int id)491 static int SetApWmm(int value, int id)
492 {
493     char cmd[BUFSIZE_CMD] = {0};
494     char buf[BUFSIZE_REQUEST_SMALL] = {0};
495 
496     if (sprintf_s(cmd, sizeof(cmd), "SET wmm_enabled %d", value) < 0) {
497         HDF_LOGE("SetApWmm sprintf_s fail");
498         return -1;
499     }
500     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
501 }
502 
SetAp80211n(int value,int id)503 static int SetAp80211n(int value, int id)
504 {
505     char cmd[BUFSIZE_CMD] = {0};
506     char buf[BUFSIZE_REQUEST_SMALL] = {0};
507 
508     if (sprintf_s(cmd, sizeof(cmd), "SET ieee80211n %d", value) < 0) {
509         HDF_LOGE("SetAp80211n sprintf_s fail");
510         return -1;
511     }
512     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
513 }
514 
SetApBand(int band,int id)515 static int SetApBand(int band, int id)
516 {
517     char cmd[BUFSIZE_CMD] = {0};
518     char buf[BUFSIZE_REQUEST_SMALL] = {0};
519     const char *hwMode = NULL;
520 
521     switch (band) {
522         case AP_NONE_BAND:
523             hwMode = "any"; /* Unknown frequency band */
524             break;
525         case AP_2GHZ_BAND:
526             hwMode = "g";   /* BAND_2_4_GHZ */
527             break;
528         case AP_5GHZ_BAND:
529             hwMode = "a";   /* BAND_5_GHZ */
530             break;
531         default:
532             HDF_LOGE("Invalid band");
533             return -1;
534     }
535 
536     if (sprintf_s(cmd, sizeof(cmd), "SET hw_mode %s", hwMode) < 0) {
537         HDF_LOGE("SetApBand sprintf_s fail");
538         return -1;
539     }
540     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
541 }
542 
SendPrivateCmd(struct iwreq * wrq,struct iw_priv_args * privPtr,const char * fName,int bufLen,int sock,char dataBuf[])543 static int SendPrivateCmd(struct iwreq *wrq, struct iw_priv_args *privPtr, const char *fName,
544     int bufLen, int sock, char dataBuf[])
545 {
546     int ret;
547     int cmd = 0;
548     int subCmd = 0;
549 
550     if (wrq == NULL || privPtr == NULL || fName == NULL) {
551         HDF_LOGE("SendPrivateCmd input parameter invalid");
552         return -1;
553     }
554     /* Find the matching command from the privPtr array */
555     int i;
556     for (i = 0; i < wrq->u.data.length; i++) {
557         if (strncmp(privPtr[i].name, fName, strlen(fName)) == 0) {
558             cmd = (int)privPtr[i].cmd;
559             break;
560         }
561     }
562     /* No matching command found */
563     if (i == wrq->u.data.length) {
564         HDF_LOGE("fName: %{public}s - function not supported", fName);
565         return -1;
566     }
567     /* Process sub-command for a private command */
568     if (cmd < SIOCDEVPRIVATE) {
569         int j;
570         for (j = 0; j < i; j++) {
571             if ((privPtr[j].set_args == privPtr[i].set_args) &&
572                 (privPtr[j].get_args == privPtr[i].get_args) &&
573                 (privPtr[j].name[0] == '\0')) {
574                 break;
575             }
576         }
577         /* No valid sub-command found */
578         if (j == i) {
579             HDF_LOGE("fName: %{public}s - invalid private ioctl", fName);
580             return -1;
581         }
582         /* Set the sub-command and update the main command */
583         subCmd = cmd;
584         cmd = (int)privPtr[j].cmd;
585     }
586     wrq->ifr_name[IFNAMSIZ - 1] = '\0';
587     /* Set the data length and pointer based on bufLen and dataBuf */
588     if ((bufLen == 0) && (*dataBuf != 0)) {
589         wrq->u.data.length = strlen(dataBuf) + 1;
590     } else {
591         wrq->u.data.length = (uint16_t)bufLen;
592     }
593     wrq->u.data.pointer = dataBuf;
594     wrq->u.data.flags = (uint16_t)subCmd;
595     /* Perform the ioctl operation */
596     ret = ioctl(sock, cmd, wrq);
597     HDF_LOGD("the data length is:%hu, ret is %d", wrq->u.data.length, ret);
598     return ret;
599 }
600 
SetCommandHwHisi(const char * iface,const char * fName,unsigned int bufLen,char dataBuf[])601 static int SetCommandHwHisi(const char *iface, const char *fName, unsigned int bufLen, char dataBuf[])
602 {
603     char buf[SOFTAP_MAX_BUFFER_SIZE] = { 0 };
604     struct iwreq wrq;
605     int ret;
606 
607     if (iface == NULL || fName == NULL) {
608         HDF_LOGE("SetCommandHwHisi: iface or fName is null.");
609         return -1;
610     }
611 
612     ret = strncpy_s(wrq.ifr_name, sizeof(wrq.ifr_name), g_apIfaceName, strlen(g_apIfaceName));
613     if (ret != EOK) {
614         HDF_LOGE("%{public}s strncpy_s wrq fail", __func__);
615         return -1;
616     }
617     wrq.ifr_name[IFNAMSIZ - 1] = '\0';
618     wrq.u.data.pointer = buf;
619     wrq.u.data.length = sizeof(buf) / sizeof(struct iw_priv_args);
620     wrq.u.data.flags = 0;
621     HDF_LOGD("the interface name is: %{public}s", wrq.ifr_name);
622 
623     int sock = socket(AF_INET, SOCK_DGRAM, 0);
624     if (sock < 0) {
625         HDF_LOGE("Softap SetCommandHw - failed to open socket");
626         return -1;
627     }
628     ret = ioctl(sock, SIOCGIWPRIV, &wrq);
629     if (ret < 0) {
630         HDF_LOGE("SIOCGIPRIV failed: %{public}d", ret);
631         close(sock);
632         return ret;
633     }
634     struct iw_priv_args *privPtr = (struct iw_priv_args *)wrq.u.data.pointer;
635     ret = strncpy_s(wrq.ifr_name, sizeof(wrq.ifr_name), g_apIfaceName, strlen(g_apIfaceName));
636     if (ret != EOK) {
637         HDF_LOGE("%{public}s strncpy_s wrq fail", __func__);
638         close(sock);
639         return -1;
640     }
641     ret = SendPrivateCmd(&wrq, privPtr, fName, bufLen, sock, dataBuf);
642     close(sock);
643     return ret;
644 }
645 
AddParam(unsigned int position,const char * cmd,const char * arg,char outDataBuf[],unsigned int outSize)646 static int AddParam(unsigned int position, const char *cmd, const char *arg, char outDataBuf[], unsigned int outSize)
647 {
648     if (cmd == NULL || arg == NULL) {
649         HDF_LOGE("%{public}s cmd == NULL or arg == NULL", __func__);
650         return -1;
651     }
652     /* ADDITIONAL_SPACE_FOR_FORMATTING 3: for "=" "," and terminator */
653     if ((unsigned int)(position + strlen(cmd) + strlen(arg) + ADDITIONAL_SPACE_FOR_FORMATTING) >= outSize) {
654         HDF_LOGE("%{public}s Command line is too big", __func__);
655         return -1;
656     }
657 
658     int ret = sprintf_s(&outDataBuf[position], outSize - position, "%s=%s,", cmd, arg);
659     if (ret == -1) {
660         HDF_LOGE("%{public}s sprintf_s cmd fail", __func__);
661         return -1;
662     }
663     position += ret;
664     return position;
665 }
666 
SetApMaxConnHw(int maxConn,int channel)667 static int SetApMaxConnHw(int maxConn, int channel)
668 {
669     char dataBuf[SOFTAP_MAX_BUFFER_SIZE] = { 0 };
670     if (memset_s(dataBuf, SOFTAP_MAX_BUFFER_SIZE, 0, SOFTAP_MAX_BUFFER_SIZE) != EOK) {
671         HDF_LOGE("SetApMaxConnHw  memset_s fail");
672         return -1;
673     }
674     int index = 0;
675     if ((index = AddParam(index, "ASCII_CMD", "AP_CFG", dataBuf, SOFTAP_MAX_BUFFER_SIZE)) == -1) {
676         HDF_LOGE("AddParam ASCII_CMD fail");
677         return -1;
678     }
679     char chann[10] = {0};
680     if (sprintf_s(chann, sizeof(chann), "%d", channel) == -1) {
681         HDF_LOGE("AddParam CHANNEL sprintf_s failed");
682         return -1;
683     }
684     if ((index = AddParam(index, "CHANNEL", chann, dataBuf, SOFTAP_MAX_BUFFER_SIZE)) == -1) {
685         HDF_LOGE("AddParam CHANNEL fail");
686         return -1;
687     }
688     char maxStaNum[10] = {0};
689     if (sprintf_s(maxStaNum, sizeof(maxStaNum), "%d", maxConn) == -1) {
690         HDF_LOGE("AddParam maxStaNum sprintf_s failed");
691         return -1;
692     }
693     if ((index = AddParam(index, "MAX_SCB", maxStaNum, dataBuf, SOFTAP_MAX_BUFFER_SIZE)) == -1) {
694         HDF_LOGE("AddParam MAX_SCB fail");
695         return -1;
696     }
697     if ((unsigned int)(index + 4) >= sizeof(dataBuf)) { // 4 : for "END" and terminator
698         HDF_LOGE("Command line is too big");
699         return -1;
700     }
701     int ret = sprintf_s(&dataBuf[index], sizeof(dataBuf) - index, "END");
702     if (ret == -1) {
703         HDF_LOGE("sprintf_s fail.");
704         return -1;
705     }
706     HDF_LOGD("the command is :%{public}s", dataBuf);
707 
708     ret = SetCommandHwHisi(AP_IFNAME, "AP_SET_CFG", SOFTAP_MAX_BUFFER_SIZE, dataBuf);
709     if (ret) {
710         HDF_LOGE("SetSoftapHw - failed: %{public}d", ret);
711     } else {
712         HDF_LOGI("SetSoftapHw - Ok");
713         usleep(AP_SET_CFG_DELAY);
714     }
715     return 0;
716 }
717 
SetApMaxConn(int maxConn,int id)718 static int SetApMaxConn(int maxConn, int id)
719 {
720     char cmd[BUFSIZE_CMD] = {0};
721     char buf[BUFSIZE_REQUEST_SMALL] = {0};
722 
723     if (sprintf_s(cmd, sizeof(cmd), "SET max_num_sta %d", maxConn) < 0) {
724         HDF_LOGE("SetApMaxConn sprintf_s fail");
725         return -1;
726     }
727     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
728 }
729 
ModBlockList(const char * mac,int id)730 static int ModBlockList(const char *mac, int id)
731 {
732     if (mac == NULL) {
733         HDF_LOGD("ModBlockList mac is null");
734         return -1;
735     }
736     char buf[BUFSIZE_REQUEST_SMALL] = {0};
737     char cmd[BUFSIZE_CMD] = {0};
738     char file[FILE_NAME_SIZE] = {0};
739     if (snprintf_s(file, sizeof(file), sizeof(file) - 1, "%s/%s", CONFIG_PATH_DIR, CONFIG_DENY_MAC_FILE_NAME) < 0) {
740         HDF_LOGE("ModBlockList sprintf_s file fail");
741         return -1;
742     }
743     FILE *fp = fopen(file, "w");
744     if (fp == NULL) {
745         HDF_LOGE("ModBlockList fopen fail");
746         return -1;
747     }
748     if (fprintf(fp, "%s\n", mac) < 0) {
749         fclose(fp);
750         HDF_LOGE("ModBlockList fprintf fail");
751         return -1;
752     }
753     if (fclose(fp) != 0) {
754         HDF_LOGE("ModBlockList fclose error");
755         return -1;
756     }
757     if (sprintf_s(cmd, sizeof(cmd), "IFNAME=%s SET deny_mac_file %s/%s", g_apIfaceName,
758         CONFIG_PATH_DIR, CONFIG_DENY_MAC_FILE_NAME) < 0) {
759         HDF_LOGE("ModBlockList sprintf_s cmd fail");
760         return -1;
761     }
762     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
763 }
764 
AddBlocklist(const char * mac,int id)765 static int AddBlocklist(const char *mac, int id)
766 {
767     if (mac == NULL) {
768         HDF_LOGE("AddBlocklist mac is null");
769         return -1;
770     }
771     char cmd[BUFSIZE_CMD] = {0};
772     char buf[BUFSIZE_REQUEST_SMALL] = {0};
773 
774     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s DENY_ACL ADD_MAC %s", g_apIfaceName, mac) < 0) {
775         HDF_LOGE("AddBlocklist sprintf_s cmd fail");
776         return -1;
777     }
778     if (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf)) != 0) {
779         HDF_LOGE("AddBlocklist WpaCtrlCommand Failed");
780         return -1;
781     }
782     if (strncasecmp(buf, "UNKNOWN COMMAND", UNKNOWN_COMMAND_LENGTH) == 0) {
783         HDF_LOGE("AddBlocklist DENY_ACL command return %{public}s, use SET command", buf);
784         /**
785          * The hostapd of an earlier version does not support the DENY_ACL command and uses the configuration file.
786          */
787         return ModBlockList(mac, id);
788     }
789     return 0;
790 }
791 
DelBlocklist(const char * mac,int id)792 static int DelBlocklist(const char *mac, int id)
793 {
794     if (mac == NULL) {
795         HDF_LOGE("DelBlocklist mac is null");
796         return -1;
797     }
798     char cmd[BUFSIZE_CMD] = {0};
799     char buf[BUFSIZE_REQUEST_SMALL] = {0};
800 
801     if (sprintf_s(cmd, sizeof(cmd), "IFNAME=%s DENY_ACL DEL_MAC %s", g_apIfaceName, mac) < 0) {
802         HDF_LOGE("DelBlocklist sprintf_s DENY_ACL cmd fail");
803         return -1;
804     }
805     if (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf)) != 0) {
806         HDF_LOGE("DelBlocklist WpaCtrlCommand Failed");
807         return -1;
808     }
809     if (strncasecmp(buf, "UNKNOWN COMMAND", UNKNOWN_COMMAND_LENGTH) == 0) {
810         HDF_LOGD("DelBlocklist DENY_ACL command return %{public}s, use SET command", buf);
811         if (sprintf_s(cmd, sizeof(cmd), "-%s", mac) < 0) {
812             HDF_LOGE("DelBlocklist sprintf_s set cmd fail");
813             return -1;
814         }
815         return ModBlockList(cmd, id);
816     }
817     return 0;
818 }
819 
GetApStatus(StatusInfo * info,int id)820 static int GetApStatus(StatusInfo *info, int id)
821 {
822     if (info == NULL) {
823         HDF_LOGD("GetApStatus info is null");
824         return -1;
825     }
826     char *buf = (char *)calloc(BUFSIZE_RECV, sizeof(char));
827     if (buf == NULL) {
828         HDF_LOGE("GetApStatus buf calloc fail");
829         return -1;
830     }
831 
832     if (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, "STATUS", buf, BUFSIZE_RECV) != 0) {
833         HDF_LOGE("Status WpaCtrlCommand failed");
834         free(buf);
835         buf = NULL;
836         return -1;
837     }
838 
839     char *p = strstr(buf, "state=");
840     if (p == NULL) {
841         HDF_LOGD("Status not find state result!");
842         free(buf);
843         buf = NULL;
844         return 0;
845     }
846     p += strlen("state=");  // skip state=
847     unsigned pos = 0;
848     while (pos < sizeof(info->state) - 1 && *p != '\0' && *p != '\n') {
849         info->state[pos++] = *p;
850         ++p;
851     }
852     info->state[pos] = 0;
853     free(buf);
854     buf = NULL;
855     return 0;
856 }
857 
ShowConnectedDevList(char * buf,int size,int id)858 static int ShowConnectedDevList(char *buf, int size, int id)
859 {
860     if (buf == NULL) {
861         HDF_LOGE("ShowConnectedDevList buf is null");
862         return -1;
863     }
864     char cmd[BUFSIZE_CMD] = {0};
865     char *reqBuf = (char *)calloc(BUFSIZE_REQUEST, sizeof(char));
866     if (reqBuf == NULL) {
867         HDF_LOGD("ShowConnectedDevList reqBuf calloc fail");
868         return -1;
869     }
870     if (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, "STA-FIRST",
871         reqBuf, BUFSIZE_REQUEST) != 0) {
872         HDF_LOGE("ShowConnectedDevList WpaCtrlCommand Failed");
873         free(reqBuf);
874         reqBuf = NULL;
875         return -1;
876     }
877     do {
878         char *pos = reqBuf;
879         while (*pos != '\0' && *pos != '\n') { /* return station info, first line is mac address */
880             pos++;
881         }
882         *pos = '\0';
883         if (strcmp(reqBuf, "") != 0) {
884             int bufLen = strlen(buf);
885             int staLen = strlen(reqBuf);
886             if (bufLen + staLen + 1 >= size) {
887                 free(reqBuf);
888                 reqBuf = NULL;
889                 return 0;
890             }
891             buf[bufLen++] = ',';
892             for (int i = 0; i < staLen; ++i) {
893                 buf[bufLen + i] = reqBuf[i];
894             }
895             buf[bufLen + staLen] = '\0';
896         }
897         if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "STA-NEXT %s", reqBuf) < 0) {
898             break;
899         }
900     } while (WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, reqBuf, BUFSIZE_REQUEST) == 0);
901     free(reqBuf);
902     reqBuf = NULL;
903     return 0;
904 }
905 
ReloadApConfigInfo(int id)906 static int ReloadApConfigInfo(int id)
907 {
908     char buf[BUFSIZE_REQUEST_SMALL] = {0};
909     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, "RELOAD", buf, sizeof(buf));
910 }
911 
DisConnectedDev(const char * mac,int id)912 static int DisConnectedDev(const char *mac, int id)
913 {
914     if (mac == NULL) {
915         HDF_LOGE("DisConnectedDev mac is null");
916         return -1;
917     }
918     char cmd[BUFSIZE_CMD] = {0};
919     char buf[BUFSIZE_REQUEST_SMALL] = {0};
920 
921     if (sprintf_s(cmd, sizeof(cmd), "IFNAME=%s DISASSOCIATE %s", g_apIfaceName, mac) < 0) {
922         HDF_LOGE("DisConnectedDev sprintf_s fail");
923         return -1;
924     }
925     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
926 }
927 
SetCountryCode(const char * code,int id)928 static int SetCountryCode(const char *code, int id)
929 {
930     if (code == NULL) {
931         HDF_LOGE("SetCountryCode code is null");
932         return -1;
933     }
934     char cmd[BUFSIZE_CMD] = {0};
935     char buf[BUFSIZE_REQUEST_SMALL] = {0};
936 
937     if (sprintf_s(cmd, sizeof(cmd), "SET country_code %s", code) < 0) {
938         HDF_LOGE("SetCountryCode sprintf_s fail");
939         return -1;
940     }
941     return WpaCtrlCommand(g_hostapdHalDevInfo[id].hostapdHalDev->ctrlConn, cmd, buf, sizeof(buf));
942 }
943 
GetWifiHostapdDev(int id)944 WifiHostapdHalDevice *GetWifiHostapdDev(int id)
945 {
946     pthread_mutex_lock(&g_mutex);
947     HDF_LOGI("enter GetWifiHostapdDev");
948 
949     if (id < 0 || id >= AP_MAX_INSTANCE) {
950         HDF_LOGE("Invalid id: %{public}d!", id);
951         pthread_mutex_unlock(&g_mutex);
952         return NULL;
953     }
954 
955     if (g_hostapdHalDevInfo[id].hostapdHalDev != NULL) {
956         pthread_mutex_unlock(&g_mutex);
957         return g_hostapdHalDevInfo[id].hostapdHalDev;
958     }
959 
960     g_hostapdHalDevInfo[id].hostapdHalDev = (WifiHostapdHalDevice *)calloc(1, sizeof(WifiHostapdHalDevice));
961     if (g_hostapdHalDevInfo[id].hostapdHalDev == NULL) {
962         HDF_LOGE("GetWifiHostapdDev hostapdHalDev calloc fail");
963         pthread_mutex_unlock(&g_mutex);
964         return NULL;
965     }
966 
967     /* ************ Register hostapd_cli Interface ************************* */
968     g_hostapdHalDevInfo[id].hostapdHalDev->stopAp = StopAp;
969     g_hostapdHalDevInfo[id].hostapdHalDev->enableAp = EnableAp;
970     g_hostapdHalDevInfo[id].hostapdHalDev->disableAp = DisableAp;
971     g_hostapdHalDevInfo[id].hostapdHalDev->setApName = SetApName;
972     g_hostapdHalDevInfo[id].hostapdHalDev->setApRsnPairwise = SetApRsnPairwise;
973     g_hostapdHalDevInfo[id].hostapdHalDev->setApWpaPairwise = SetApWpaPairwise;
974     g_hostapdHalDevInfo[id].hostapdHalDev->setApWpaKeyMgmt = SetApWpaKeyMgmt;
975     g_hostapdHalDevInfo[id].hostapdHalDev->setApWpaValue = SetApWpaValue;
976     g_hostapdHalDevInfo[id].hostapdHalDev->setApPasswd = SetApPasswd;
977     g_hostapdHalDevInfo[id].hostapdHalDev->setApChannel = SetApChannel;
978     g_hostapdHalDevInfo[id].hostapdHalDev->setApWmm = SetApWmm;
979     g_hostapdHalDevInfo[id].hostapdHalDev->setAp80211n = SetAp80211n;
980     g_hostapdHalDevInfo[id].hostapdHalDev->setApBand = SetApBand;
981     g_hostapdHalDevInfo[id].hostapdHalDev->setApMaxConnHw = SetApMaxConnHw;
982     g_hostapdHalDevInfo[id].hostapdHalDev->setApMaxConn = SetApMaxConn;
983     g_hostapdHalDevInfo[id].hostapdHalDev->addBlocklist = AddBlocklist;
984     g_hostapdHalDevInfo[id].hostapdHalDev->delBlocklist = DelBlocklist;
985     g_hostapdHalDevInfo[id].hostapdHalDev->status = GetApStatus;
986     g_hostapdHalDevInfo[id].hostapdHalDev->showConnectedDevList = ShowConnectedDevList;
987     g_hostapdHalDevInfo[id].hostapdHalDev->reloadApConfigInfo = ReloadApConfigInfo;
988     g_hostapdHalDevInfo[id].hostapdHalDev->disConnectedDev = DisConnectedDev;
989     g_hostapdHalDevInfo[id].hostapdHalDev->setCountryCode = SetCountryCode;
990 
991     if (InitHostapdHal(id) != 0) {
992         HDF_LOGE("InitHostapdHal return failed!!");
993         free(g_hostapdHalDevInfo[id].hostapdHalDev);
994         g_hostapdHalDevInfo[id].hostapdHalDev = NULL;
995         pthread_mutex_unlock(&g_mutex);
996         return NULL;
997     }
998     pthread_mutex_unlock(&g_mutex);
999     return g_hostapdHalDevInfo[id].hostapdHalDev;
1000 }
1001