blob: 77cc924107570107126ff65239cbb0d3459dd00b [file] [log] [blame]
zw.wang00477802025-06-12 19:48:37 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <sys/wait.h>
6#include <pthread.h>
7
8#include "gsw_wifi_interface_sdk.h"
9#include <dlfcn.h>
10#define MAX_COMMAND_LEN 512
11#define MAX_SSID_LEN 32
zw.wanga8267052025-06-20 10:03:00 +080012#define MIN_SSID_LEN 6
zw.wang00477802025-06-12 19:48:37 +080013#define MIN_PASSWORD_LEN 8
14#define MAX_PASSWORD_LEN 64
15#define MAX_IP_LEN 32
16#define MAX_MAC_LEN 32
17
18#define WLAN_STA_DEV "wlan0-vxd"
19#define WLAN_AP_DEV "wlan0"
20
21#define HOSTAPD_CONF_PATH "/etc/wifi/hostapd.conf"
22#define HOSTAPD_LOG_PATH "/etc/wifi/hostapd.log"
23#define WPA_SUPPLICANT_CONF_PATH "/etc/wifi/wpa_supplicant.conf"
24#define AIC8800_BSP_DRIVER_PATH "aic8800_bsp"
25#define AIC8800_FDRV_DRIVER_PATH "aic8800_fdrv"
26#define CTRL_INTERFACE "/var/run/hostapd"
27
28#define WPA_SUPPLICANT_CTRL_PATH "/var/run/wpa_supplicant"
29
30#define VALID_2G_CHANNELS {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
31#define VALID_5G_CHANNELS {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}
32
33#ifndef LOG_ERR_LEVEL
34#define LOG_ERR_LEVEL 3 /* error conditions */
35#endif
36#ifndef LOG_WARN_LEVEL
37#define LOG_WARN_LEVEL 4 /* warning conditions */
38#endif
39#ifndef LOG_INFO_LEVEL
40#define LOG_INFO_LEVEL 6 /* informational */
41#endif
42#ifndef LOG_DEBUG_LEVEL
43#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
44#endif
45#ifndef LOG_VERBOSE_LEVEL
46#define LOG_VERBOSE_LEVEL 8
47#endif
48
49#define GSW_UART "[HAL][GSW_WIFI]"
50
51#define LOGV(fmt, args...) \
52 do \
53 { \
54 char *file_ptr_1001 = __FILE__; \
55 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
56 char line_1001[10] = {0}; \
57 sprintf(line_1001, "%d", __LINE__); \
58 while (ptr_1001 >= file_ptr_1001 && *ptr_1001) \
59 { \
60 if (*ptr_1001 == '/') \
61 break; \
62 ptr_1001--; \
63 } \
64 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: " GSW_UART "" fmt, ptr_1001 + 1, line_1001, ##args); \
65 } while (0)
66
67#define LOGI(fmt, args...) \
68 do \
69 { \
70 char *file_ptr_1001 = __FILE__; \
71 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
72 char line_1001[10] = {0}; \
73 sprintf(line_1001, "%d", __LINE__); \
74 while (ptr_1001 >= file_ptr_1001 && *ptr_1001) \
75 { \
76 if (*ptr_1001 == '/') \
77 break; \
78 ptr_1001--; \
79 } \
80 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: " GSW_UART "" fmt, ptr_1001 + 1, line_1001, ##args); \
81 } while (0)
82
83#define LOGD(fmt, args...) \
84 do \
85 { \
86 char *file_ptr_1001 = __FILE__; \
87 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
88 char line_1001[10] = {0}; \
89 sprintf(line_1001, "%d", __LINE__); \
90 while (ptr_1001 >= file_ptr_1001 && *ptr_1001) \
91 { \
92 if (*ptr_1001 == '/') \
93 break; \
94 ptr_1001--; \
95 } \
96 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: " GSW_UART "" fmt, ptr_1001 + 1, line_1001, ##args); \
97 } while (0)
98
99#define LOGW(fmt, args...) \
100 do \
101 { \
102 char *file_ptr_1001 = __FILE__; \
103 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
104 char line_1001[10] = {0}; \
105 sprintf(line_1001, "%d", __LINE__); \
106 while (ptr_1001 >= file_ptr_1001 && *ptr_1001) \
107 { \
108 if (*ptr_1001 == '/') \
109 break; \
110 ptr_1001--; \
111 } \
112 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: " GSW_UART "" fmt, ptr_1001 + 1, line_1001, ##args); \
113 } while (0)
114
115#define LOGE(fmt, args...) \
116 do \
117 { \
118 char *file_ptr_1001 = __FILE__; \
119 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
120 char line_1001[10] = {0}; \
121 sprintf(line_1001, "%d", __LINE__); \
122 while (ptr_1001 >= file_ptr_1001 && *ptr_1001) \
123 { \
124 if (*ptr_1001 == '/') \
125 break; \
126 ptr_1001--; \
127 } \
128 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: " GSW_UART "" fmt, ptr_1001 + 1, line_1001, ##args); \
129 } while (0)
130
131typedef void (*mbtk_log)(int level, const char *format, ...);
132static mbtk_log fun_ptr_log = NULL;
zw.wangbb7f28c2025-06-27 19:41:19 +0800133static void *dlHandle_wifi = NULL;
134static void (*mbtk_log_init)(char *path, char *tag);
135#define LIB_PATH "/lib/libmbtk_lib.so"
zw.wang00477802025-06-12 19:48:37 +0800136
137static int handle()
138{
139 if (dlHandle_wifi == NULL || fun_ptr_log == NULL)
140 {
zw.wangbb7f28c2025-06-27 19:41:19 +0800141 dlHandle_wifi = dlopen(LIB_PATH, RTLD_NOW);
142 if(dlHandle_wifi == NULL)
143 {
144 return GSW_HAL_NORMAL_FAIL;
145 }
146 mbtk_log_init = (void (*)(char *path, char *tag))dlsym(dlHandle_wifi, "mbtk_log_init");
147 mbtk_log_init("radio", "MBTK_RIL");
zw.wang00477802025-06-12 19:48:37 +0800148 fun_ptr_log = (mbtk_log)dlsym(dlHandle_wifi, "mbtk_log");
149 if (fun_ptr_log == NULL || dlHandle_wifi == NULL)
150 {
151 return GSW_HAL_NORMAL_FAIL;
152 }
153 }
154 return GSW_HAL_SUCCESS;
155}
156
157// 辅助函数:执行系统命令
158int execute_command(const char *cmd)
159{
160 int status = system(cmd);
161 if (status == -1)
162 {
163 LOGE("Failed to execute command");
164 return GSW_HAL_NORMAL_FAIL;
165 }
166 if (WIFEXITED(status))
167 {
168 return WEXITSTATUS(status);
169 }
170 else
171 {
172 // 子进程异常退出,比如被信号终止
173 return GSW_HAL_NORMAL_FAIL;
174 }
175}
176
177// 辅助函数:读取文件内容到缓冲区
178int read_file(const char *path, char *buffer, size_t buffer_len)
179{
180 FILE *file = fopen(path, "r");
181 if (!file)
182 return GSW_HAL_NORMAL_FAIL;
183 size_t length = fread(buffer, 1, buffer_len - 1, file);
184 if (length == 0)
185 {
186 fclose(file);
187 return GSW_HAL_NORMAL_FAIL;
188 }
189 buffer[length] = '\0';
190 fclose(file);
191 return (int)length;
192}
193
194// 新增:静态互斥锁用于保护文件写入操作
195static pthread_mutex_t write_file_mutex = PTHREAD_MUTEX_INITIALIZER;
196
197int write_file(const char *path, const char *buffer)
198{
199 // 加锁:确保同一时间只有一个线程执行文件写入
200 pthread_mutex_lock(&write_file_mutex);
201
202 FILE *file = fopen(path, "w");
203 if (!file)
204 {
205 // 解锁后返回错误
206 pthread_mutex_unlock(&write_file_mutex);
207 return GSW_HAL_NORMAL_FAIL;
208 }
209
210 fputs(buffer, file);
211 fclose(file);
212
213 // 解锁:释放锁资源
214 pthread_mutex_unlock(&write_file_mutex);
215 return GSW_HAL_SUCCESS;
216}
217
218// 辅助函数:检查 hostapd 是否正在运行
219int is_hostapd_running()
220{
221 char cmd[MAX_COMMAND_LEN];
222 snprintf(cmd, sizeof(cmd), "ps | grep 'hostapd' | grep -v -E 'grep|global'");
223 FILE *output = popen(cmd, "r");
224 if (!output)
225 {
226 return GSW_HAL_NORMAL_FAIL;
227 }
228 char buffer[1]; // 只需检查是否有输出,读取一个字符即可
229 int result = fread(buffer, 1, 1, output);
230 pclose(output);
231 if (result > 0)
232 {
233 return GSW_HAL_SUCCESS; // 找到指定配置的hostapd进程
234 }
235 return GSW_HAL_NORMAL_FAIL; // 未找到
236}
237
238int gsw_wifi_ap_start()
239{
240 if (handle())
241 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +0800242 LOGI("gsw_wifi_ap_start\n");
zw.wang00477802025-06-12 19:48:37 +0800243 // 强制终止所有hostapd进程(关键新增:避免残留进程占用资源)
244 execute_command("killall -9 hostapd >/dev/null 2>&1"); // 9信号强制终止
245 sleep(1); // 等待进程完全退出
246
247 // 清理网络桥接接口(关键新增:避免br-lan绑定冲突)
248 char brctl_cmd[MAX_COMMAND_LEN];
249 snprintf(brctl_cmd, sizeof(brctl_cmd), "brctl delif br-lan %s >/dev/null 2>&1", WLAN_AP_DEV);
250 execute_command(brctl_cmd);
251
252 // 检查并删除残留的控制接口文件(原有逻辑保留)
253 char ctrl_path[MAX_COMMAND_LEN];
254 snprintf(ctrl_path, sizeof(ctrl_path), "%s/%s", CTRL_INTERFACE, WLAN_AP_DEV);
255 if (access(ctrl_path, F_OK) == 0)
256 {
257 if (remove(ctrl_path) != 0)
258 {
259 LOGE("Failed to remove old hostapd control interface file");
260 return GSW_HAL_NORMAL_FAIL;
261 }
262 }
263
264 // 启动hostapd(原有逻辑保留)
265 char cmd[MAX_COMMAND_LEN];
266 snprintf(cmd, sizeof(cmd), "echo ap starting > %s ;hostapd -q %s >> %s &", HOSTAPD_LOG_PATH, HOSTAPD_CONF_PATH, HOSTAPD_LOG_PATH);
267 int status = execute_command(cmd);
268 sleep(8);
269
270 char log_buffer[1024] = {0};
271 if (read_file(HOSTAPD_LOG_PATH, log_buffer, sizeof(log_buffer)) != -1)
272 {
273 // 检查日志中是否包含关键错误信息(示例:"Failed"、"error")
274 if (strstr(log_buffer, "failed") || strstr(log_buffer, "error") || strstr(log_buffer, "wasn't started"))
275 {
276 LOGE("Hostapd start failed, check log: %s", log_buffer);
277 return GSW_HAL_NORMAL_FAIL;
278 }
279 if(is_hostapd_running() == GSW_HAL_SUCCESS)
280 {
281 LOGI("Hostapd start success");
282 }
283 else
284 {
285 LOGE("Hostapd start failed, check log: %s", log_buffer);
286 return GSW_HAL_NORMAL_FAIL;
287 }
288 }
289 else
290 {
291 if (is_hostapd_running() != GSW_HAL_SUCCESS)
292 {
293 LOGE("Failed to read hostapd log file: %s", HOSTAPD_LOG_PATH);
294 return GSW_HAL_NORMAL_FAIL;
295 }
296 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800297 LOGI("gsw_wifi_ap_start ret = %d\n", status);
zw.wang00477802025-06-12 19:48:37 +0800298 return status;
299}
300
301// 辅助函数:判断 wpa_supplicant 服务是否起来
302int is_wpa_supplicant_running()
303{
304 char cmd[MAX_COMMAND_LEN];
305 snprintf(cmd, sizeof(cmd), "ps | grep wpa_supplicant | grep -v grep");
306 FILE *output = popen(cmd, "r");
307 if (!output)
308 {
309 return GSW_HAL_NORMAL_FAIL;
310 }
311 char buffer[1]; // 只需检查是否有输出,读取一个字符即可
312 int result = fread(buffer, 1, 1, output);
313 pclose(output);
314 if (result > 0)
315 {
316 return GSW_HAL_SUCCESS; // wpa_supplicant 服务存在
317 }
318 return GSW_HAL_NORMAL_FAIL; // wpa_supplicant 服务不存在
319}
320
321typedef struct
322{
323 void *arg;
324 GSW_AP_CALLBACK_FUNC_PTR gsw_cb;
325 pthread_t thread_id;
326 int running;
327} AP_Event_Context;
328
329static AP_Event_Context ap_event_context;
330int gsw_wifi_ap_stop()
331{
332 if (handle())
333 return GSW_HAL_NORMAL_FAIL;
334 if (is_hostapd_running() != 0)
335 {
336 LOGI("Hostapd is not running, no need to stop.\n");
337 return GSW_HAL_SUCCESS;
338 }
339
zw.wangbb7f28c2025-06-27 19:41:19 +0800340 LOGI("Hostapd is running, stop it.\n");
zw.wang00477802025-06-12 19:48:37 +0800341 // 先停止事件监听线程
zw.wang41cd4162025-06-20 17:50:41 +0800342 /*if (ap_event_context.running)
zw.wang00477802025-06-12 19:48:37 +0800343 {
344 ap_event_context.running = 0;
345 if (ap_event_context.thread_id != 0)
346 {
347 pthread_join(ap_event_context.thread_id, NULL);
348 ap_event_context.thread_id = 0;
349 }
zw.wang41cd4162025-06-20 17:50:41 +0800350 }*/
zw.wang00477802025-06-12 19:48:37 +0800351
352 char cmd[MAX_COMMAND_LEN];
353 snprintf(cmd, sizeof(cmd), "killall hostapd");
354 int status = execute_command(cmd);
355
356 // 关闭对应的 hostapd 后,删除对应的文件
357 char path[MAX_COMMAND_LEN];
358 snprintf(path, sizeof(path), "%s/%s", CTRL_INTERFACE, WLAN_AP_DEV);
359 if (access(path, F_OK) == 0)
360 {
361 if (remove(path) != 0)
362 {
363 LOGE("Failed to remove hostapd control interface file");
364 }
365 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800366 LOGI("gsw_wifi_ap_stop ret = %d\n", status);
zw.wang00477802025-06-12 19:48:37 +0800367 return status;
368}
369
370int gsw_wifi_ap_restart(void)
371{
372 if (handle())
373 return GSW_HAL_NORMAL_FAIL;
374 int ret = 0;
375 char cmd[MAX_COMMAND_LEN];
376 snprintf(cmd, sizeof(cmd), "killall hostapd");
377 int status = execute_command(cmd);
378 LOGI("killall hostapd status = %d\n", status);
379 // 关闭对应的 hostapd 后,删除对应的文件
380 char path[MAX_COMMAND_LEN];
381 snprintf(path, sizeof(path), "%s/%s", CTRL_INTERFACE, WLAN_AP_DEV);
382 if (access(path, F_OK) == 0)
383 {
384 if (remove(path) != 0)
385 {
386 LOGE("Failed to remove hostapd control interface file");
387 }
388 }
389 ret = gsw_wifi_ap_start();
zw.wangbb7f28c2025-06-27 19:41:19 +0800390 LOGI("gsw_wifi_ap_restart ret = %d\n", ret);
zw.wang00477802025-06-12 19:48:37 +0800391 return ret;
392}
393
394int gsw_wifi_ap_ssid_set(char *ssid)
395{
396 if (handle())
397 return GSW_HAL_NORMAL_FAIL;
398 char buffer[4096] = {0};
399 char new_config[4096] = {0};
400 if (ssid == NULL) {
401 LOGE("Password cannot be NULL");
402 return GSW_HAL_NORMAL_FAIL;
403 }
404 size_t ssid_len = strlen(ssid);
zw.wanga8267052025-06-20 10:03:00 +0800405 if (ssid_len > MAX_SSID_LEN || ssid_len < MIN_SSID_LEN) {
406 LOGE("SSID length must be 6-32 characters, current length: %zu", ssid_len);
zw.wang00477802025-06-12 19:48:37 +0800407 return GSW_HAL_NORMAL_FAIL;
408 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800409 LOGI("AP set ssid: %s\n", ssid);
zw.wang00477802025-06-12 19:48:37 +0800410 // 读取现有配置
411 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
412 {
413 // 如果文件不存在,创建新配置(修改默认配置内容)
414 FILE *conf = fopen(HOSTAPD_CONF_PATH, "w");
415 if (!conf)
416 return GSW_HAL_NORMAL_FAIL;
417
418 // 写入用户指定的完整默认配置
419 fprintf(conf, "ctrl_interface=%s\n", CTRL_INTERFACE);
420 fprintf(conf, "ctrl_interface_group=0\n");
421 fprintf(conf, "interface=%s\n", WLAN_AP_DEV);
422 fprintf(conf, "driver=nl80211\n");
423 fprintf(conf, "bridge=br-lan\n");
424 fprintf(conf, "ssid=%s\n", ssid); // 使用传入的ssid
zw.wang3e022be2025-06-18 09:39:23 +0800425 fprintf(conf, "hw_mode=g\n");
zw.wang00477802025-06-12 19:48:37 +0800426 fprintf(conf, "ieee80211d=1\n");
zw.wang3e022be2025-06-18 09:39:23 +0800427 fprintf(conf, "channel=0\n");
zw.wang00477802025-06-12 19:48:37 +0800428 fprintf(conf, "auth_algs=1\n");
429 fprintf(conf, "wme_enabled=1\n");
430 fprintf(conf, "noscan=0\n");
431 fprintf(conf, "beacon_int=100\n");
zw.wang3e022be2025-06-18 09:39:23 +0800432 fprintf(conf, "wpa=3\n");
zw.wang00477802025-06-12 19:48:37 +0800433 fprintf(conf, "wpa_passphrase=12345678\n");
434 fprintf(conf, "ieee80211n=1\n");
435 fprintf(conf, "ieee80211ac=1\n");
436 fprintf(conf, "ieee80211ax=1\n");
zw.wang3e022be2025-06-18 09:39:23 +0800437 fprintf(conf, "vht_oper_chwidth=0\n");
438 fprintf(conf, "vht_oper_centr_freq_seg0_idx=0\n");
439 fprintf(conf, "he_oper_chwidth=0\n");
440 fprintf(conf, "he_oper_centr_freq_seg0_idx=0\n");
zw.wang00477802025-06-12 19:48:37 +0800441 fprintf(conf, "he_basic_mcs_nss_set=65534\n");
zw.wang3e022be2025-06-18 09:39:23 +0800442 fprintf(conf, "he_su_beamformee=0\n");
zw.wang00477802025-06-12 19:48:37 +0800443 fprintf(conf, "he_twt_required=0\n");
444 fprintf(conf, "vht_capab=[SHORT-GI-80][VHT40+][VHT40-][MAX-A-MPDU-LEN-EXP7][RX-STBC-1][RX-LDPC]\n");
445 fprintf(conf, "ht_capab=[SHORT-GI-20][SHORT-GI-40][HT40+][HT40-][LDPC][RX-STBC1]\n");
446 fprintf(conf, "wpa_key_mgmt=WPA-PSK\n");
zw.wang3e022be2025-06-18 09:39:23 +0800447 fprintf(conf, "wpa_pairwise=TKIP CCMP\n");
zw.wang00477802025-06-12 19:48:37 +0800448 fprintf(conf, "rsn_pairwise=CCMP\n");
zw.wang00477802025-06-12 19:48:37 +0800449 fprintf(conf, "ignore_broadcast_ssid=0\n");
450 fprintf(conf, "country_code=CN\n");
451 fprintf(conf, "max_num_sta=32\n");
452 fprintf(conf, "macaddr_acl=0\n");
453 fprintf(conf, "deny_mac_file=/etc/wifi/hostapd.deny\n");
454 fprintf(conf, "accept_mac_file=/etc/wifi/hostapd.accept\n");
455 fprintf(conf, "sae_pwe=2\n");
456
457 fclose(conf);
458 return GSW_HAL_SUCCESS;
459 }
460
461 // 处理每一行(新增ctrl_interface和ctrl_interface_group的检查)
462 char *line = strtok(buffer, "\n");
463 int ssid_processed = 0; // 标记是否已处理过ssid行
464 while (line)
465 {
466 if (!ssid_processed && strncmp(line, "ssid=", 5) == 0)
467 {
468 char ssid_line[64];
469 snprintf(ssid_line, sizeof(ssid_line), "ssid=%s", ssid);
470 strcat(new_config, ssid_line);
471 strcat(new_config, "\n");
472 ssid_processed = 1;
473 line = strtok(NULL, "\n");
474 continue;
475 }
476 else if (strncmp(line, "ssid=", 5) == 0)
477 {
478 line = strtok(NULL, "\n");
479 continue;
480 }
481 else if (strncmp(line, "ctrl_interface=", 15) == 0)
482 {
483 char ctrl_line[128];
484 snprintf(ctrl_line, sizeof(ctrl_line), "ctrl_interface=%s", CTRL_INTERFACE);
485 strcat(new_config, ctrl_line);
486 strcat(new_config, "\n");
487 }
488 else if (strncmp(line, "ctrl_interface_group=", 21) == 0)
489 {
490 char ctrl_group_line[64];
491 snprintf(ctrl_group_line, sizeof(ctrl_group_line), "ctrl_interface_group=0");
492 strcat(new_config, ctrl_group_line);
493 strcat(new_config, "\n");
494 }
495 else
496 {
497 strcat(new_config, line);
498 strcat(new_config, "\n");
499 }
500 line = strtok(NULL, "\n");
501 }
502
503 if (!ssid_processed)
504 {
505 char ssid_line[64];
506 snprintf(ssid_line, sizeof(ssid_line), "ssid=%s\n", ssid);
507 strcat(new_config, ssid_line);
508 }
509
510 return write_file(HOSTAPD_CONF_PATH, new_config);
511}
512
513int gsw_wifi_ap_ssid_get(char *ssid)
514{
515 if (handle())
516 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +0800517 if (ssid == NULL) {
518 LOGE("ssid cannot be NULL");
519 return GSW_HAL_NORMAL_FAIL;
520 }
zw.wang00477802025-06-12 19:48:37 +0800521 char buffer[1024] = {0};
522 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
523 {
524 return GSW_HAL_NORMAL_FAIL;
525 }
526 char *ssid_line = strstr(buffer, "ssid=");
527 if (ssid_line)
528 {
529 ssid_line += 5; // 跳过 "ssid="
530 char *end = strchr(ssid_line, '\n');
531 if (end)
532 *end = '\0';
533 strncpy(ssid, ssid_line, MAX_SSID_LEN);
534 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800535 LOGI("AP get ssid: %s\n", ssid);
zw.wang00477802025-06-12 19:48:37 +0800536 return GSW_HAL_SUCCESS;
537}
538
539int gsw_wifi_ap_frequency_set(int gsw_wifi_frequency)
540{
541 if (handle())
542 return GSW_HAL_NORMAL_FAIL;
543 char buffer[4096] = {0};
544 char new_config[4096] = {0};
zw.wangbb7f28c2025-06-27 19:41:19 +0800545 LOGI("AP set frequency: %d\n", gsw_wifi_frequency);
zw.wang00477802025-06-12 19:48:37 +0800546 gsw_wifi_bandwidth_type_e gsw_wifi_bandwidth;
547 gsw_wifi_ap_bandwidth_get(&gsw_wifi_bandwidth);
548 if (gsw_wifi_bandwidth == GSW_WIFI_BANDWIDTH_HT80 && gsw_wifi_frequency == 1)
549 {
550 LOGE("HT80 cannot be set to 2.4G");
551 return GSW_HAL_NORMAL_FAIL;
552 }
553 // 读取现有配置
554 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
555 {
556 return GSW_HAL_NORMAL_FAIL;
557 }
558
559 // 处理每一行
560 char *line = strtok(buffer, "\n");
561 while (line)
562 {
563 // 如果是hw_mode行,替换为新值
564 if (strstr(line, "hw_mode=") != NULL)
565 {
566 char mode_line[32];
567 snprintf(mode_line, sizeof(mode_line), "hw_mode=%c", gsw_wifi_frequency == 1 ? 'g' : 'a');
568 strcat(new_config, mode_line);
569 }
570 else
571 {
572 strcat(new_config, line);
573 }
574 strcat(new_config, "\n");
575 line = strtok(NULL, "\n");
576 }
577
578 // 如果没有找到hw_mode行,添加新的设置
579 if (strstr(new_config, "hw_mode=") == NULL)
580 {
581 char mode_line[32];
582 snprintf(mode_line, sizeof(mode_line), "hw_mode=%c\n", gsw_wifi_frequency == 1 ? 'g' : 'a');
583 strcat(new_config, mode_line);
584 }
585
586 // 写回文件
587 return write_file(HOSTAPD_CONF_PATH, new_config);
588}
589
590int gsw_wifi_ap_frequency_get(int *gsw_wifi_frequency)
591{
592 if (handle())
593 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +0800594 if (gsw_wifi_frequency == NULL) {
595 LOGE("gsw_wifi_frequency cannot be NULL");
596 return GSW_HAL_NORMAL_FAIL;
597 }
zw.wang00477802025-06-12 19:48:37 +0800598 char buffer[1024] = {0};
599 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
600 {
601 return GSW_HAL_NORMAL_FAIL;
602 }
603 char *mode_line = strstr(buffer, "hw_mode=");
604 if (mode_line)
605 {
606 mode_line += 8; // 跳过 "hw_mode="
607 *gsw_wifi_frequency = (mode_line[0] == 'g') ? 1 : 2;
608 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800609 LOGI("AP get frequency: %d\n", *gsw_wifi_frequency);
zw.wang00477802025-06-12 19:48:37 +0800610 return GSW_HAL_SUCCESS;
611}
612
613int gsw_wifi_ap_bandwidth_set(gsw_wifi_bandwidth_type_e bandwidth)
614{
615 if (handle())
616 return GSW_HAL_NORMAL_FAIL;
617 char buffer[4096] = {0};
618 char new_config[4096] = {0};
zw.wangbb7f28c2025-06-27 19:41:19 +0800619 LOGI("AP set bandwidth: %d\n", bandwidth);
zw.wang00477802025-06-12 19:48:37 +0800620 int current_freq;
621 if (gsw_wifi_ap_frequency_get(&current_freq) != 0)
622 {
623 LOGI("Failed to get current frequency\n");
624 return GSW_HAL_NORMAL_FAIL;
625 }
626 if (current_freq == 1 && bandwidth == GSW_WIFI_BANDWIDTH_HT80) // 1表示2.4GHz
627 {
628 LOGI("2.4GHz band does not support 80MHz bandwidth");
629 return GSW_HAL_NORMAL_FAIL;
630 }
631 // 读取现有配置
632 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
633 return GSW_HAL_NORMAL_FAIL;
634
635 // 定义各带宽类型对应的替换规则(新增三个参数)
636 const char *ht_capab = NULL;
637 const char *vht_capab = NULL;
638 const char *vht_oper_chwidth = NULL;
639 const char *he_oper_chwidth = NULL;
640 int vht_oper_centr_freq_seg0_idx_val = 0;
641 int he_oper_centr_freq_seg0_idx_val = 0;
642 int he_su_beamformee_val = 0;
643
644 // 根据带宽类型初始化替换值(补充新增参数逻辑)
645 switch (bandwidth)
646 {
647 case GSW_WIFI_BANDWIDTH_HT20:
648 ht_capab = "ht_capab=[HT20][SHORT-GI-20][LDPC][RX-STBC1]";
649 vht_capab = "vht_capab=[VHT20][SHORT-GI-20][MAX-A-MPDU-LEN-EXP7]";
650 vht_oper_chwidth = "vht_oper_chwidth=0";
651 he_oper_chwidth = "he_oper_chwidth=0";
652 vht_oper_centr_freq_seg0_idx_val = 0;
653 he_oper_centr_freq_seg0_idx_val = 0;
654 he_su_beamformee_val = 0;
655 break;
656 case GSW_WIFI_BANDWIDTH_HT40:
657 ht_capab = "ht_capab=[SHORT-GI-20][SHORT-GI-40][HT40+][HT40-][LDPC][RX-STBC1]";
658 vht_capab = "vht_capab=[SHORT-GI-80][VHT40+][VHT40-][MAX-A-MPDU-LEN-EXP7][RX-STBC-1][RX-LDPC]";
659 vht_oper_chwidth = "vht_oper_chwidth=0";
660 he_oper_chwidth = "he_oper_chwidth=0";
661 vht_oper_centr_freq_seg0_idx_val = 0;
662 he_oper_centr_freq_seg0_idx_val = 0;
663 he_su_beamformee_val = 0;
664 break;
665 case GSW_WIFI_BANDWIDTH_HT80:
666 ht_capab = "ht_capab=[HT20][HT40+][HT40-][SHORT-GI-40][LDPC][RX-STBC1]";
667 vht_capab = "vht_capab=[VHT40][VHT80][SHORT-GI-80][MAX-A-MPDU-LEN-EXP7]";
668 vht_oper_chwidth = "vht_oper_chwidth=1";
669 he_oper_chwidth = "he_oper_chwidth=1";
670 vht_oper_centr_freq_seg0_idx_val = 42;
671 he_oper_centr_freq_seg0_idx_val = 42;
672 he_su_beamformee_val = 1;
673 break;
674 default:
675 return GSW_HAL_NORMAL_FAIL;
676 }
677
678 // 新增标记:确保只处理第一个ht_capab行
679 int ht_capab_processed = 0;
680
681 // 逐行处理配置文件(增加新增参数的匹配)
682 char *line = strtok(buffer, "\n");
683 while (line)
684 {
685 // 处理ht_capab行(仅替换第一个以"ht_capab="开头的行)
686 if (!ht_capab_processed && strncmp(line, "ht_capab=", 9) == 0)
687 {
688 if (ht_capab)
689 {
690 strcat(new_config, ht_capab);
691 ht_capab_processed = 1; // 标记已处理
692 }
693 else
694 {
695 strcat(new_config, line);
696 }
697 strcat(new_config, "\n");
698 line = strtok(NULL, "\n");
699 continue;
700 }
701 else if (strncmp(line, "ht_capab=", 9) == 0)
702 {
703 line = strtok(NULL, "\n");
704 continue;
705 }
706 else if (strncmp(line, "vht_oper_centr_freq_seg0_idx=", 25) == 0)
707 {
708 char vht_centr_line[64];
709 snprintf(vht_centr_line, sizeof(vht_centr_line), "vht_oper_centr_freq_seg0_idx=%d", vht_oper_centr_freq_seg0_idx_val);
710 strcat(new_config, vht_centr_line);
711 strcat(new_config, "\n");
712 }
713 else if (strncmp(line, "he_oper_centr_freq_seg0_idx=", 25) == 0)
714 {
715 char he_centr_line[64];
716 snprintf(he_centr_line, sizeof(he_centr_line), "he_oper_centr_freq_seg0_idx=%d", he_oper_centr_freq_seg0_idx_val);
717 strcat(new_config, he_centr_line);
718 strcat(new_config, "\n");
719 }
720 else if (strncmp(line, "he_su_beamformee=", 17) == 0)
721 {
722 char he_beam_line[32];
723 snprintf(he_beam_line, sizeof(he_beam_line), "he_su_beamformee=%d", he_su_beamformee_val);
724 strcat(new_config, he_beam_line);
725 strcat(new_config, "\n");
726 }
727 else if (strncmp(line, "vht_capab=", 10) == 0)
728 {
729 if (vht_capab)
730 strcat(new_config, vht_capab);
731 else
732 strcat(new_config, line);
733 strcat(new_config, "\n");
734 }
735 else if (strncmp(line, "vht_oper_chwidth=", 17) == 0)
736 {
737 if (vht_oper_chwidth)
738 strcat(new_config, vht_oper_chwidth);
739 else
740 strcat(new_config, line);
741 strcat(new_config, "\n");
742 }
743 else if (strncmp(line, "he_oper_chwidth=", 16) == 0)
744 {
745 if (he_oper_chwidth)
746 strcat(new_config, he_oper_chwidth);
747 else
748 strcat(new_config, line);
749 strcat(new_config, "\n");
750 }
751 else
752 {
753 strcat(new_config, line);
754 strcat(new_config, "\n");
755 }
756 line = strtok(NULL, "\n");
757 }
758
759 // 如果原文件无ht_capab行,补充新行(保持原有逻辑)
760 if (!ht_capab_processed && ht_capab)
761 {
762 strcat(new_config, ht_capab);
763 strcat(new_config, "\n");
764 }
765
766 // 检查vht_oper_centr_freq_seg0_idx是否已处理
767 if (!strstr(new_config, "vht_oper_centr_freq_seg0_idx="))
768 {
769 char vht_centr_line[64];
770 snprintf(vht_centr_line, sizeof(vht_centr_line), "vht_oper_centr_freq_seg0_idx=%d\n", vht_oper_centr_freq_seg0_idx_val);
771 strcat(new_config, vht_centr_line);
772 }
773 // 检查he_oper_centr_freq_seg0_idx是否已处理
774 if (!strstr(new_config, "he_oper_centr_freq_seg0_idx="))
775 {
776 char he_centr_line[64];
777 snprintf(he_centr_line, sizeof(he_centr_line), "he_oper_centr_freq_seg0_idx=%d\n", he_oper_centr_freq_seg0_idx_val);
778 strcat(new_config, he_centr_line);
779 }
780 // 检查he_su_beamformee是否已处理
781 if (!strstr(new_config, "he_su_beamformee="))
782 {
783 char he_beam_line[32];
784 snprintf(he_beam_line, sizeof(he_beam_line), "he_su_beamformee=%d\n", he_su_beamformee_val);
785 strcat(new_config, he_beam_line);
786 }
787
788 return write_file(HOSTAPD_CONF_PATH, new_config);
789}
790
791
792int gsw_wifi_ap_bandwidth_get(gsw_wifi_bandwidth_type_e *bandwidth)
793{
794 if (handle())
795 return GSW_HAL_NORMAL_FAIL;
796 char buffer[1024] = {0};
797 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
798 {
799 return GSW_HAL_NORMAL_FAIL;
800 }
801
802 // 精确解析ht_capab参数
803 char *ht_line = strstr(buffer, "ht_capab=");
804 char *vht_line = strstr(buffer, "vht_capab=");
805 char *vht_width = strstr(buffer, "vht_oper_chwidth=1");
806
807 // 优先检查80MHz配置
808 if (vht_width && vht_line && strstr(vht_line, "VHT80"))
809 {
810 *bandwidth = GSW_WIFI_BANDWIDTH_HT80;
811 }
812 else if (ht_line && strstr(ht_line, "HT40+"))
813 {
814 *bandwidth = GSW_WIFI_BANDWIDTH_HT40;
815 }
816 else
817 {
818 *bandwidth = GSW_WIFI_BANDWIDTH_HT20;
819 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800820 LOGI("AP get bandwidth: %d\n", *bandwidth);
zw.wang00477802025-06-12 19:48:37 +0800821 return GSW_HAL_SUCCESS;
822}
823
824int gsw_wifi_ap_channel_set(int channel)
825{
826 if (handle())
827 return GSW_HAL_NORMAL_FAIL;
828 // 新增频率和信道校验
zw.wangbb7f28c2025-06-27 19:41:19 +0800829 LOGI("AP set channel: %d\n", channel);
zw.wang00477802025-06-12 19:48:37 +0800830 int current_freq;
831 if (gsw_wifi_ap_frequency_get(&current_freq) != 0)
832 {
833 LOGE("Failed to get current frequency\n");
834 return GSW_HAL_NORMAL_FAIL;
835 }
836 // 定义各频段支持的信道范围
837 const int valid_2g_channels[] = VALID_2G_CHANNELS;
838 const int valid_5g_channels[] = VALID_5G_CHANNELS;
839
840 int valid = 0;
841 if (current_freq == 1)
842 { // 2.4GHz
843 for (int i = 0; i < sizeof(valid_2g_channels) / sizeof(int); i++)
844 {
845 if (channel == valid_2g_channels[i])
846 {
847 valid = 1;
848 break;
849 }
850 }
851 }
852 else
853 { // 5GHz
854 for (int i = 0; i < sizeof(valid_5g_channels) / sizeof(int); i++)
855 {
856 if (channel == valid_5g_channels[i])
857 {
858 valid = 1;
859 break;
860 }
861 }
862 }
863
864 if (!valid && channel != 0)
865 { // 允许0表示自动选择
866 LOGI("Invalid channel %d for %s band\n",
867 channel, (current_freq == 1) ? "2.4GHz" : "5GHz");
868 return GSW_HAL_NORMAL_FAIL;
869 }
870
871 // 修改为读取整个文件并替换channel行
872 char buffer[4096] = {0};
873 char new_config[4096] = {0};
874 int noscan_set = 0; // 新增:标记是否已处理noscan行
875
876 // 读取现有配置
877 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
878 {
879 return GSW_HAL_NORMAL_FAIL;
880 }
881
882 // 处理每一行
883 char *line = strtok(buffer, "\n");
884 while (line)
885 {
886 // 新增:处理noscan行
887 if (strstr(line, "noscan=") != NULL)
888 {
889 char noscan_line[32];
890 snprintf(noscan_line, sizeof(noscan_line), "noscan=%d", (channel == 0) ? 0 : 1);
891 strcat(new_config, noscan_line);
892 strcat(new_config, "\n");
893 noscan_set = 1;
894 }
895 // 如果是channel行,替换为新值
896 else if (strstr(line, "channel=") != NULL)
897 {
898 char channel_line[32];
899 snprintf(channel_line, sizeof(channel_line), "channel=%d", channel);
900 strcat(new_config, channel_line);
901 strcat(new_config, "\n");
902 }
903 // 其他行保持不变
904 else
905 {
906 strcat(new_config, line);
907 strcat(new_config, "\n");
908 }
909 line = strtok(NULL, "\n");
910 }
911
912 // 如果没有找到channel行,添加新的channel设置
913 if (strstr(new_config, "channel=") == NULL)
914 {
915 char channel_line[32];
916 snprintf(channel_line, sizeof(channel_line), "channel=%d\n", channel);
917 strcat(new_config, channel_line);
918 }
919
920 // 新增:如果没有找到noscan行,根据channel值补充
921 if (!noscan_set)
922 {
923 char noscan_line[32];
924 snprintf(noscan_line, sizeof(noscan_line), "noscan=%d\n", (channel == 0) ? 0 : 1);
925 strcat(new_config, noscan_line);
926 }
927
928 // 写回文件
929 return write_file(HOSTAPD_CONF_PATH, new_config);
930}
931
932
933int gsw_wifi_ap_channel_get(int *channel)
934{
935 if (handle())
936 return GSW_HAL_NORMAL_FAIL;
937 if (channel == NULL)
938 {
939 LOGI("channel is NULL\n");
940 return GSW_HAL_NORMAL_FAIL;
941 }
942 char buffer[1024] = {0};
943 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
944 {
945 return GSW_HAL_NORMAL_FAIL;
946 }
947 char *channel_line = strstr(buffer, "channel=");
948 if (channel_line)
949 {
950 channel_line += 8; // 跳过 "channel="
951 *channel = atoi(channel_line);
952 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800953 LOGI("AP get channel: %d\n", *channel);
zw.wang00477802025-06-12 19:48:37 +0800954 return GSW_HAL_SUCCESS;
955}
956
957int gsw_wifi_ap_auth_set(gsw_wifi_auth_e auth)
958{
959 if (handle())
960 return GSW_HAL_NORMAL_FAIL;
961 char buffer[4096] = {0};
962 char new_config[4096] = {0};
963 int wpa_set = 0, key_mgmt_set = 0, wpa_pairwise_set = 0, rsn_pairwise_set = 0, ieee80211w_set = 0, auth_algs_set = 0;
964
965 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
966 {
967 return GSW_HAL_NORMAL_FAIL;
968 }
zw.wangbb7f28c2025-06-27 19:41:19 +0800969 LOGI("AP set auth: %d\n", auth);
zw.wang00477802025-06-12 19:48:37 +0800970 char *line = strtok(buffer, "\n");
971 while (line)
972 {
973 // 匹配行首为"wpa="的行(长度4)
974 if (strncmp(line, "wpa=", 4) == 0)
975 {
976 char wpa_line[32];
977 if (auth == GSW_WIFI_AUTH_OPEN || auth == GSW_WIFI_AUTH_WEP)
978 snprintf(wpa_line, sizeof(wpa_line), "wpa=%d", 0);
979 else if (auth == GSW_WIFI_AUTH_WPA_PSK)
980 snprintf(wpa_line, sizeof(wpa_line), "wpa=%d", 1);
981 else if (auth == GSW_WIFI_AUTH_WPA2_PSK)
982 {
983 snprintf(wpa_line, sizeof(wpa_line), "wpa=%d", 3);
984 }
985 else if (auth == GSW_WIFI_AUTH_WPA3_PSK)
986 snprintf(wpa_line, sizeof(wpa_line), "wpa=%d", 2);
987 else
988 snprintf(wpa_line, sizeof(wpa_line), "wpa=%d", 2);
989 strcat(new_config, wpa_line);
990 strcat(new_config, "\n");
991 wpa_set = 1;
992 }
993 else if (strncmp(line, "wpa_key_mgmt=", 13) == 0)
994 {
995 const char *key_mgmt = (auth == GSW_WIFI_AUTH_WPA3_PSK) ? "SAE WPA-PSK" : "WPA-PSK";
996 char key_mgmt_line[64];
997 snprintf(key_mgmt_line, sizeof(key_mgmt_line), "wpa_key_mgmt=%s", key_mgmt);
998 strcat(new_config, key_mgmt_line);
999 strcat(new_config, "\n");
1000 key_mgmt_set = 1;
1001 }
1002 else if (strncmp(line, "auth_algs=", 9) == 0)
1003 {
1004 char auth_algs_line[32];
1005 snprintf(auth_algs_line, sizeof(auth_algs_line), "auth_algs=%d", (auth == GSW_WIFI_AUTH_WEP) ? 3 : 1);
1006 strcat(new_config, auth_algs_line);
1007 strcat(new_config, "\n");
1008 auth_algs_set = 1;
1009 }
1010 else if (strncmp(line, "wpa_pairwise=", 13) == 0)
1011 {
1012 const char *pairwise = NULL;
1013 if (auth == GSW_WIFI_AUTH_WPA_PSK)
1014 pairwise = "TKIP";
1015 else if (auth == GSW_WIFI_AUTH_WPA2_PSK)
1016 pairwise = "TKIP CCMP";
1017 else if (auth == GSW_WIFI_AUTH_WPA3_PSK)
1018 pairwise = "CCMP";
1019 else
1020 pairwise = "TKIP CCMP";
1021 char pairwise_line[64];
1022 snprintf(pairwise_line, sizeof(pairwise_line), "wpa_pairwise=%s", pairwise);
1023 strcat(new_config, pairwise_line);
1024 strcat(new_config, "\n");
1025 wpa_pairwise_set = 1;
1026 }
1027 else if (strncmp(line, "rsn_pairwise=", 13) == 0)
1028 {
1029 if (auth == GSW_WIFI_AUTH_WPA2_PSK || auth == GSW_WIFI_AUTH_WPA3_PSK)
1030 {
1031 strcat(new_config, "rsn_pairwise=CCMP\n");
1032 }
1033 rsn_pairwise_set = 1;
1034 }
1035 else if (strncmp(line, "ieee80211w=", 11) == 0)
1036 {
1037 if (auth == GSW_WIFI_AUTH_WPA3_PSK)
1038 {
1039 strcat(new_config, "ieee80211w=2\n"); // WPA3 强制 MFP
1040 ieee80211w_set = 1;
1041 }
1042 else if (auth == GSW_WIFI_AUTH_WPA2_PSK)
1043 {
1044 strcat(new_config, "ieee80211w=1\n"); // WPA2 可选 MFP
1045 ieee80211w_set = 1;
1046 }
1047 // 其他模式不添加该行(直接跳过)
1048 }
1049 else
1050 {
1051 strcat(new_config, line);
1052 strcat(new_config, "\n");
1053 }
1054 line = strtok(NULL, "\n");
1055 }
1056
1057 // 补全未匹配的配置项
1058 if (!wpa_set)
1059 {
1060 if (auth == GSW_WIFI_AUTH_OPEN || auth == GSW_WIFI_AUTH_WEP)
1061 strcat(new_config, "wpa=0");
1062 else if (auth == GSW_WIFI_AUTH_WPA_PSK)
1063 strcat(new_config, "wpa=1");
1064 else if (auth == GSW_WIFI_AUTH_WPA2_PSK)
1065 {
1066 strcat(new_config, "wpa=3");
1067 }
1068 else if (auth == GSW_WIFI_AUTH_WPA3_PSK)
1069 strcat(new_config, "wpa=2");
1070 else
1071 strcat(new_config, "wpa=2");
1072 strcat(new_config, "\n");
1073 }
1074 if (!key_mgmt_set)
1075 {
1076 const char *key_mgmt = (auth == GSW_WIFI_AUTH_WPA3_PSK) ? "WPA-PSK SAE" : "WPA-PSK";
1077 strcat(new_config, "wpa_key_mgmt=");
1078 strcat(new_config, key_mgmt);
1079 strcat(new_config, "\n");
1080 }
1081 if (!auth_algs_set)
1082 {
1083 char auth_algs_line[32];
1084 snprintf(auth_algs_line, sizeof(auth_algs_line), "auth_algs=%d\n", (auth == GSW_WIFI_AUTH_WEP) ? 3 : 1);
1085 strcat(new_config, auth_algs_line);
1086 }
1087 if (!wpa_pairwise_set)
1088 {
1089 const char *pairwise = NULL;
1090 if (auth == GSW_WIFI_AUTH_WPA_PSK)
1091 pairwise = "TKIP";
1092 else if (auth == GSW_WIFI_AUTH_WPA2_PSK)
1093 pairwise = "TKIP CCMP";
1094 else if (auth == GSW_WIFI_AUTH_WPA3_PSK)
1095 pairwise = "CCMP";
1096 else
1097 pairwise = "TKIP CCMP";
1098 strcat(new_config, "wpa_pairwise=");
1099 strcat(new_config, pairwise);
1100 strcat(new_config, "\n");
1101 }
1102 if (!rsn_pairwise_set)
1103 {
1104 if (auth == GSW_WIFI_AUTH_WPA2_PSK || auth == GSW_WIFI_AUTH_WPA3_PSK)
1105 {
1106 strcat(new_config, "rsn_pairwise=CCMP\n");
1107 }
1108 }
1109 if (!ieee80211w_set && (auth == GSW_WIFI_AUTH_WPA3_PSK || auth == GSW_WIFI_AUTH_WPA2_PSK))
1110 {
1111 // 仅当需要时补全 ieee80211w 行(其他模式不添加)
1112 strcat(new_config, (auth == GSW_WIFI_AUTH_WPA3_PSK) ? "ieee80211w=2\n" : "ieee80211w=1\n");
1113 }
1114
1115 return write_file(HOSTAPD_CONF_PATH, new_config);
1116}
1117
1118int gsw_wifi_ap_auth_get(gsw_wifi_auth_e *auth)
1119{
1120 if (handle())
1121 return GSW_HAL_NORMAL_FAIL;
1122 char buffer[1024] = {0};
1123 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
1124 {
1125 return GSW_HAL_NORMAL_FAIL;
1126 }
1127
1128 char *auth_algs_line = strstr(buffer, "auth_algs=");
1129 if (auth_algs_line)
1130 {
1131 auth_algs_line += 10; // 跳过 "auth_algs="
1132 int auth_algs_val = atoi(auth_algs_line);
1133 if (auth_algs_val == 3)
1134 {
1135 *auth = GSW_WIFI_AUTH_WEP;
1136 return GSW_HAL_SUCCESS;
1137 }
1138 }
1139 // 优先通过 wpa_key_mgmt 判断 WPA3(包含 SAE 关键字)
1140 char *key_mgmt_line = strstr(buffer, "wpa_key_mgmt=");
1141 if (key_mgmt_line)
1142 {
1143 key_mgmt_line += 12; // 跳过 "wpa_key_mgmt="
1144 if (strstr(key_mgmt_line, "SAE"))
1145 {
1146 *auth = GSW_WIFI_AUTH_WPA3_PSK;
1147 return GSW_HAL_SUCCESS;
1148 }
1149 }
1150
1151 // 若未找到 SAE,再通过 wpa= 判断 WPA2 或开放模式
1152 char *wpa_line = strstr(buffer, "wpa=");
1153 if (wpa_line)
1154 {
1155 wpa_line += 4;
1156 int wpa_val = atoi(wpa_line);
1157 if(wpa_val > 1)
1158 {
1159 *auth = GSW_WIFI_AUTH_WPA2_PSK;
1160 }
1161 else if (wpa_val == 1)
1162 {
1163 *auth = GSW_WIFI_AUTH_WPA_PSK;
1164 }
1165 else
1166 {
1167 *auth = GSW_WIFI_AUTH_OPEN;
1168 }
1169 }
1170 else
1171 {
1172 *auth = GSW_WIFI_AUTH_OPEN; // 默认开放模式
1173 }
zw.wangbb7f28c2025-06-27 19:41:19 +08001174 LOGI("AP get auth: %d\n", *auth);
zw.wang00477802025-06-12 19:48:37 +08001175 return GSW_HAL_SUCCESS;
1176}
1177
1178int gsw_wifi_ap_password_set(char *password)
1179{
1180 if (handle())
1181 return GSW_HAL_NORMAL_FAIL;
1182 char buffer[4096] = {0};
1183 char new_config[4096] = {0};
1184 int has_passphrase = 0; // 标记是否已处理过密码行
1185 if (password == NULL) {
1186 LOGE("Password cannot be NULL");
1187 return GSW_HAL_NORMAL_FAIL;
1188 }
zw.wangbb7f28c2025-06-27 19:41:19 +08001189 LOGI("AP set password\n");
zw.wang00477802025-06-12 19:48:37 +08001190 size_t pass_len = strlen(password);
1191 if (pass_len < MIN_PASSWORD_LEN || pass_len > MAX_PASSWORD_LEN) {
1192 LOGE("Password length must be 8-63 characters, current length: %zu", pass_len);
1193 return GSW_HAL_NORMAL_FAIL;
1194 }
1195 // 读取现有配置文件内容
1196 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
1197 {
1198 return GSW_HAL_NORMAL_FAIL;
1199 }
1200
1201 // 逐行处理配置文件(修改:增加密码行存在标记)
1202 char *line = strtok(buffer, "\n");
1203 while (line)
1204 {
1205 // 匹配到原密码行时替换为新密码,并标记已处理
1206 if (strstr(line, "wpa_passphrase=") != NULL)
1207 {
1208 char new_pass_line[128];
1209 snprintf(new_pass_line, sizeof(new_pass_line), "wpa_passphrase=%s", password);
1210 strcat(new_config, new_pass_line);
1211 has_passphrase = 1; // 标记存在密码行
1212 }
1213 else
1214 {
1215 strcat(new_config, line);
1216 }
1217 strcat(new_config, "\n"); // 保留换行符
1218 line = strtok(NULL, "\n");
1219 }
1220
1221 // 若原文件无密码行,添加新密码行到末尾
1222 if (!has_passphrase)
1223 {
1224 char new_pass_line[128];
1225 snprintf(new_pass_line, sizeof(new_pass_line), "wpa_passphrase=%s\n", password);
1226 strcat(new_config, new_pass_line);
1227 }
1228
1229 // 写回配置文件
1230 return write_file(HOSTAPD_CONF_PATH, new_config);
1231}
1232
1233int gsw_wifi_ap_password_get(char *password)
1234{
1235 if (handle())
1236 return GSW_HAL_NORMAL_FAIL;
1237 char buffer[4096] = {0}; // 使用更大的缓冲区
1238 if (read_file(HOSTAPD_CONF_PATH, buffer, sizeof(buffer)) == -1)
1239 {
1240 LOGI("Failed to read hostapd config file\n");
1241 return GSW_HAL_NORMAL_FAIL;
1242 }
1243
1244 // 查找密码行
1245 char *passphrase_line = strstr(buffer, "wpa_passphrase=");
1246 if (!passphrase_line)
1247 {
1248 LOGI("No password line found in config\n");
1249 return GSW_HAL_NORMAL_FAIL;
1250 }
1251
1252 passphrase_line += 15; // 跳过 "wpa_passphrase="
1253
1254 // 查找行结束位置
1255 char *end = strchr(passphrase_line, '\n');
1256 if (end)
1257 {
1258 *end = '\0'; // 确保字符串正确终止
1259 }
1260
1261 // 检查密码长度是否合法
1262 size_t pass_len = strlen(passphrase_line);
1263 if (pass_len == 0 || pass_len >= MAX_PASSWORD_LEN)
1264 {
1265 LOGI("Invalid password length: %zu\n", pass_len);
1266 return GSW_HAL_NORMAL_FAIL;
1267 }
1268
1269 // 复制密码
1270 strncpy(password, passphrase_line, MAX_PASSWORD_LEN);
1271 password[MAX_PASSWORD_LEN] = '\0'; // 确保终止
zw.wangbb7f28c2025-06-27 19:41:19 +08001272 LOGI("AP get password\n");
zw.wang00477802025-06-12 19:48:37 +08001273 return GSW_HAL_SUCCESS;
1274}
1275
1276/**
1277 * @brief 获取 AP 模式的运行状态
1278 * @param [out] ap_status 用于存储 AP 模式运行状态的指针
1279 * @retval 0 表示函数执行成功
1280 */
1281int gsw_wifi_get_ap_status(gsw_wifi_ap_run_status_e *ap_status)
1282{
1283 if (handle())
1284 return GSW_HAL_NORMAL_FAIL;
1285 int result = is_hostapd_running();
1286 if (result == 0)
1287 {
1288 *ap_status = GSW_WIFI_AP_STATUS_ENABLE;
1289 }
1290 else
1291 {
1292 *ap_status = GSW_WIFI_AP_STATUS_DISABLE;
1293 }
1294 return GSW_HAL_SUCCESS;
1295}
1296
1297/* STA 模式相关函数实现 */
1298
1299// 辅助函数:更新 wpa_supplicant 配置文件
1300int update_wpa_supplicant_conf()
1301{
1302 char new_config[4096] = {0};
1303
1304 // 直接写入必需配置项(覆盖原有文件),新增WPA3支持的关键配置
1305 const char *required_configs[] = {
1306 "ctrl_interface=/var/run/wpa_supplicant", // 接口路径
1307 "ctrl_interface_group=root", // 组设置
1308 "update_config=1", // 允许自动更新配置
1309 "ap_scan=1", // 主动扫描AP
1310 // 网络块配置调整:使用数值19表示SAE组(替代SUITE_B_192文本标识)
1311 "network={\n key_mgmt=SAE\n pairwise=CCMP\n ieee80211w=2\n }"
1312 };
1313 int config_count = sizeof(required_configs) / sizeof(required_configs[0]);
1314
1315 // 添加所有必需的配置项(确保顺序)
1316 for (int i = 0; i < config_count; i++)
1317 {
1318 strcat(new_config, required_configs[i]);
1319 strcat(new_config, "\n");
1320 }
1321
1322 // 写回文件(完全覆盖)
1323 return write_file(WPA_SUPPLICANT_CONF_PATH, new_config);
1324}
1325
1326int gsw_wifi_sta_start()
1327{
1328 if (handle())
1329 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +08001330 LOGI("Starting wpa_supplicant...\n");
zw.wang00477802025-06-12 19:48:37 +08001331 // 更新 wpa_supplicant 配置文件
1332 if (update_wpa_supplicant_conf() != 0)
1333 {
1334 LOGI("Failed to update wpa_supplicant configuration file.\n");
1335 return GSW_HAL_NORMAL_FAIL;
1336 }
1337
1338 char cmd[MAX_COMMAND_LEN];
1339 snprintf(cmd, sizeof(cmd), "wpa_supplicant -Dnl80211 -i%s -c%s -B", WLAN_STA_DEV, WPA_SUPPLICANT_CONF_PATH);
1340 int status = execute_command(cmd);
1341 sleep(5);
1342 memset(cmd, 0, sizeof(cmd));
1343 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan > /dev/null", WLAN_STA_DEV);
1344 execute_command(cmd);
1345 memset(cmd, 0, sizeof(cmd));
1346 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan_results > /dev/null", WLAN_STA_DEV);
1347 execute_command(cmd);
zw.wangbb7f28c2025-06-27 19:41:19 +08001348 LOGI("wpa_supplicant starting success\n");
zw.wang00477802025-06-12 19:48:37 +08001349 return status;
1350}
1351
1352int gsw_wifi_sta_stop()
1353{
1354 if (handle())
1355 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +08001356 LOGI("Stopping wpa_supplicant...\n");
zw.wang00477802025-06-12 19:48:37 +08001357 if (is_wpa_supplicant_running() != 0)
1358 {
1359 LOGI("wpa_supplicant is not running, no need to stop.\n");
1360 return GSW_HAL_SUCCESS;
1361 }
1362
1363 char cmd[MAX_COMMAND_LEN];
1364 snprintf(cmd, sizeof(cmd), "killall wpa_supplicant");
zw.wangbb7f28c2025-06-27 19:41:19 +08001365 LOGI("Stoping success\n");
zw.wang00477802025-06-12 19:48:37 +08001366 return execute_command(cmd);
1367}
1368
1369int gsw_wifi_get_sta_status(gsw_wifi_sta_run_status_e *sta_status)
1370{
1371 if (handle())
1372 return GSW_HAL_NORMAL_FAIL;
1373 if (is_wpa_supplicant_running() == 0)
1374 {
1375 *sta_status = GSW_WIFI_STA_STATUS_ENABLE;
1376 }
1377 else
1378 {
1379 *sta_status = GSW_WIFI_STA_STATUS_DISABLE;
1380 }
1381 return GSW_HAL_SUCCESS;
1382}
1383
1384// 修改涉及 wpa_cli 命令的函数
1385int gsw_wifi_get_sta_ssid(char *sta_ssid)
1386{
1387 if (handle())
1388 return GSW_HAL_NORMAL_FAIL;
1389 if (is_wpa_supplicant_running() != 0)
1390 {
1391 return GSW_HAL_NORMAL_FAIL;
1392 }
1393 char cmd[MAX_COMMAND_LEN];
1394 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s status | grep 'ssid=' | cut -d '=' -f 2", WLAN_STA_DEV);
1395 FILE *output = popen(cmd, "r");
1396 if (!output)
1397 return GSW_HAL_NORMAL_FAIL;
1398 char buffer[MAX_SSID_LEN + 1];
1399 if (fgets(buffer, sizeof(buffer), output) == NULL)
1400 {
1401 pclose(output);
1402 return GSW_HAL_NORMAL_FAIL;
1403 }
1404 pclose(output);
1405 buffer[strcspn(buffer, "\n")] = '\0';
1406 strncpy(sta_ssid, buffer, MAX_SSID_LEN);
zw.wangbb7f28c2025-06-27 19:41:19 +08001407 LOGI("SSID: %s\n", sta_ssid);
zw.wang00477802025-06-12 19:48:37 +08001408 return GSW_HAL_SUCCESS;
1409}
1410
1411int gsw_wifi_get_sta_auth(gsw_wifi_auth_e *auth)
1412{
1413 if (handle())
1414 return GSW_HAL_NORMAL_FAIL;
1415 if (is_wpa_supplicant_running() != 0)
1416 {
1417 LOGI("wpa_supplicant is not running.\n");
1418 return GSW_HAL_NORMAL_FAIL;
1419 }
1420 char cmd[MAX_COMMAND_LEN];
1421 // 修改命令,获取 key_mgmt 字段
1422 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s status | grep 'key_mgmt=' | cut -d '=' -f 2", WLAN_STA_DEV);
1423 LOGI("Executing command: %s\n", cmd);
1424 FILE *output = popen(cmd, "r");
1425 if (!output)
1426 {
1427 LOGI("Failed to execute command: %s\n", cmd);
1428 return GSW_HAL_NORMAL_FAIL;
1429 }
1430 char buffer[32];
1431 if (fgets(buffer, sizeof(buffer), output) == NULL)
1432 {
1433 LOGI("No output from command: %s\n", cmd);
1434 pclose(output);
1435 return GSW_HAL_NORMAL_FAIL;
1436 }
1437 pclose(output);
1438 buffer[strcspn(buffer, "\n")] = '\0';
1439 LOGI("Command output: %s\n", buffer);
1440
1441 if (strstr(buffer, "WPA2-PSK"))
1442 {
1443 *auth = GSW_WIFI_AUTH_WPA2_PSK;
1444 }
1445 else if (strstr(buffer, "WPA-PSK"))
1446 {
1447 *auth = GSW_WIFI_AUTH_WPA_PSK;
1448 }
1449 else if (strstr(buffer, "SAE"))
1450 {
1451 *auth = GSW_WIFI_AUTH_WPA3_PSK;
1452 }
1453 else if (strstr(buffer, "NONE"))
1454 {
1455 *auth = GSW_WIFI_AUTH_OPEN;
1456 }
1457 else
1458 {
1459 LOGI("Unknown authentication type: %s. Assuming WPA2-PSK.\n", buffer);
1460 *auth = GSW_WIFI_AUTH_WPA2_PSK;
1461 }
zw.wangbb7f28c2025-06-27 19:41:19 +08001462 LOGI("Authentication type: %s\n", buffer);
zw.wang00477802025-06-12 19:48:37 +08001463 return GSW_HAL_SUCCESS;
1464}
1465
1466int gsw_wifi_sta_connect(char *ssid, gsw_wifi_auth_e auth, char *password)
1467{
1468 if (handle())
1469 return GSW_HAL_NORMAL_FAIL;
1470 if (is_wpa_supplicant_running() != 0)
1471 {
1472 return GSW_HAL_NORMAL_FAIL;
1473 }
1474
1475 char quoted_ssid[MAX_SSID_LEN + 3]; // 为引号和字符串结尾留空间
1476 char quoted_password[MAX_PASSWORD_LEN + 3];
1477
1478 // 添加引号
1479 snprintf(quoted_ssid, sizeof(quoted_ssid), "\\\"%s\\\"", ssid);
1480 if (auth != GSW_WIFI_AUTH_OPEN)
1481 {
1482 snprintf(quoted_password, sizeof(quoted_password), "\\\"%s\\\"", password);
1483 }
1484
1485 LOGI("SSID = %s\n", quoted_ssid);
1486
1487 char cmd[MAX_COMMAND_LEN];
1488 int status;
1489
1490 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1491 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s remove_network 0", WLAN_STA_DEV);
1492 LOGI("Executing command type: Remove network\n");
1493 status = execute_command(cmd);
1494 if (status != 0)
1495 {
1496 return status;
1497 }
1498
1499 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1500 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s ap_scan 1", WLAN_STA_DEV);
1501 LOGI("Executing command type: Set AP scan\n");
1502 status = execute_command(cmd);
1503 if (status != 0)
1504 {
1505 return status;
1506 }
1507
1508 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1509 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s add_network", WLAN_STA_DEV);
1510 LOGI("Executing command type: Add network\n");
1511 status = execute_command(cmd);
1512 if (status != 0)
1513 {
1514 return status;
1515 }
1516
1517 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1518 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 ssid %s", WLAN_STA_DEV, quoted_ssid);
1519 LOGI("Executing command type: Set SSID\n");
1520 status = execute_command(cmd);
1521 if (status != 0)
1522 {
1523 return status;
1524 }
1525
1526 if (auth != GSW_WIFI_AUTH_OPEN)
1527 {
1528 const char *key_mgmt;
1529 switch (auth)
1530 {
1531 case GSW_WIFI_AUTH_WEP:
1532 key_mgmt = "NONE";
1533 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1534 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 wep_key0 %s", WLAN_STA_DEV, quoted_password);
1535 LOGI("Executing command type: Set WEP key\n");
1536 status = execute_command(cmd);
1537 if (status != 0)
1538 return status;
1539
1540 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV(注意原代码中可能存在拼写错误 "weep_tx_keyidx" 应为 "wep_tx_keyidx")
1541 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 wep_tx_keyidx 0", WLAN_STA_DEV);
1542 LOGI("Executing command type: Set WEP TX key index\n");
1543 status = execute_command(cmd);
1544 if (status != 0)
1545 return status;
1546 break;
1547
1548 case GSW_WIFI_AUTH_WPA_PSK:
1549 key_mgmt = "WPA-PSK";
1550 break;
1551 case GSW_WIFI_AUTH_WPA2_PSK:
1552 key_mgmt = "WPA-PSK";
1553 break;
1554 case GSW_WIFI_AUTH_WPA3_PSK:
1555 key_mgmt = "SAE";
1556 break;
1557 default:
1558 key_mgmt = "WPA-PSK";
1559 break;
1560 }
1561
1562 if (auth != GSW_WIFI_AUTH_WEP)
1563 {
1564 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1565 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 key_mgmt %s", WLAN_STA_DEV, key_mgmt);
1566 LOGI("Executing command type: Set key management\n");
1567 status = execute_command(cmd);
1568 if (status != 0)
1569 return status;
1570
1571 if (auth == GSW_WIFI_AUTH_WPA3_PSK)
1572 {
1573 // WPA3 特有配置:确保在设置key_mgmt后配置SAE参数
1574 // 设置椭圆曲线组(使用NIST P-256,组号19)
1575 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 sae_groups 19", WLAN_STA_DEV);
1576 status = execute_command(cmd);
1577 if (status != 0)
1578 return status;
1579
1580 // 强制MFP保护(WPA3要求必须启用)
1581 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 sae_require_mfp 1", WLAN_STA_DEV);
1582 status = execute_command(cmd);
1583 if (status != 0)
1584 return status;
1585
1586 // 使用SAE+CCMP加密组合(确保与AP端匹配)
1587 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 pairwise CCMP", WLAN_STA_DEV);
1588 status = execute_command(cmd);
1589 if (status != 0)
1590 return status;
1591 }
1592
1593 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1594 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 psk %s", WLAN_STA_DEV, quoted_password);
1595 LOGI("Executing command type: Set PSK\n");
1596 status = execute_command(cmd);
1597 if (status != 0)
1598 return status;
1599 }
1600 }
1601 else
1602 {
1603 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1604 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s set_network 0 key_mgmt NONE", WLAN_STA_DEV);
1605 LOGI("Executing command type: Set key management for open network\n");
1606 status = execute_command(cmd);
1607 if (status != 0)
1608 return status;
1609 }
1610
1611 // 修改:-p 改为 -i 并使用 WLAN_STA_DEV
1612 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s select_network 0", WLAN_STA_DEV);
1613 LOGI("Executing command type: Select network\n");
1614 status = execute_command(cmd);
1615 if (status != 0)
1616 {
1617 return status;
1618 }
1619
1620 // udhcpc 命令无需修改(已使用 WLAN_STA_DEV)
1621 snprintf(cmd, sizeof(cmd), "udhcpc -i %s -n", WLAN_STA_DEV);
1622 LOGI("Executing command type: Request DHCP IP\n");
1623 status = execute_command(cmd);
1624 return status;
1625}
1626
1627int gsw_wifi_sta_forget_ap(char *ssid, gsw_wifi_auth_e auth)
1628{
1629 if (handle())
1630 return GSW_HAL_NORMAL_FAIL;
1631 if (is_wpa_supplicant_running() != 0)
1632 {
1633 return GSW_HAL_NORMAL_FAIL;
1634 }
1635 char cmd[MAX_COMMAND_LEN];
1636 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s remove_network $(wpa_cli -i %s list_networks | grep '%s' | awk '{print $1}')", WLAN_STA_DEV, WLAN_STA_DEV, ssid);
1637 return execute_command(cmd);
1638}
1639
1640int gsw_wifi_sta_start_scan(void)
1641{
1642 if (handle())
1643 return GSW_HAL_NORMAL_FAIL;
1644 if (is_wpa_supplicant_running() != 0)
1645 {
1646 return GSW_HAL_NORMAL_FAIL;
1647 }
1648 char cmd[MAX_COMMAND_LEN];
1649 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan", WLAN_STA_DEV);
1650 return execute_command(cmd);
1651}
1652
1653int gsw_wifi_get_interface_ip(gsw_wifi_index_e idx, char *ip)
1654{
1655 if (handle())
1656 return GSW_HAL_NORMAL_FAIL;
1657 char cmd[MAX_COMMAND_LEN];
1658 snprintf(cmd, sizeof(cmd), "ip addr show dev %s | grep 'inet ' | awk '{print $2}' | cut -d '/' -f 1", idx == GSW_WIFI_INTERFACE_0 ? WLAN_STA_DEV : WLAN_AP_DEV);
1659 FILE *output = popen(cmd, "r");
1660 if (!output)
1661 return GSW_HAL_NORMAL_FAIL;
1662 char buffer[MAX_IP_LEN + 1];
1663 if (fgets(buffer, sizeof(buffer), output) == NULL)
1664 {
1665 pclose(output);
1666 return GSW_HAL_NORMAL_FAIL;
1667 }
1668 pclose(output);
1669 buffer[strcspn(buffer, "\n")] = '\0';
1670 strncpy(ip, buffer, MAX_IP_LEN);
1671 return GSW_HAL_SUCCESS;
1672}
1673
1674int gsw_wifi_get_interface_mac(gsw_wifi_index_e idx, char *mac)
1675{
1676 if (handle())
1677 return GSW_HAL_NORMAL_FAIL;
1678 char cmd[MAX_COMMAND_LEN];
1679 snprintf(cmd, sizeof(cmd), "ip link show dev %s | grep 'link/ether' | awk '{print $2}'", idx == GSW_WIFI_INTERFACE_0 ? WLAN_STA_DEV : WLAN_AP_DEV);
1680 FILE *output = popen(cmd, "r");
1681 if (!output)
1682 return GSW_HAL_NORMAL_FAIL;
1683 char buffer[MAX_MAC_LEN + 1];
1684 if (fgets(buffer, sizeof(buffer), output) == NULL)
1685 {
1686 pclose(output);
1687 return GSW_HAL_NORMAL_FAIL;
1688 }
1689 pclose(output);
zw.wangbb7f28c2025-06-27 19:41:19 +08001690 buffer[strcspn(buffer, "\n")] = '\0'; // 移除换行符
1691
1692 // 关键修改:确保MAC地址仅保留17位有效字符(标准MAC格式为xx:xx:xx:xx:xx:xx,共17字符)
1693 strncpy(mac, buffer, 17); // 限制复制17个字符
1694 mac[17] = '\0'; // 显式添加字符串结束符
1695
zw.wang00477802025-06-12 19:48:37 +08001696 return GSW_HAL_SUCCESS;
1697}
1698
1699int gsw_wifi_get_connect_ap_mac(char *mac)
1700{
1701 if (handle())
1702 return GSW_HAL_NORMAL_FAIL;
1703 char cmd[MAX_COMMAND_LEN];
1704 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s status | grep 'bssid=' | cut -d '=' -f 2", WLAN_STA_DEV);
1705 FILE *output = popen(cmd, "r");
1706 if (!output)
1707 return GSW_HAL_NORMAL_FAIL;
1708 char buffer[MAX_MAC_LEN + 1];
1709 if (fgets(buffer, sizeof(buffer), output) == NULL)
1710 {
1711 pclose(output);
1712 return GSW_HAL_NORMAL_FAIL;
1713 }
1714 pclose(output);
1715 buffer[strcspn(buffer, "\n")] = '\0';
1716 strncpy(mac, buffer, MAX_MAC_LEN);
1717 return GSW_HAL_SUCCESS;
1718}
1719
1720int gsw_wifi_get_connect_ap_rssi(int *rssi)
1721{
1722 if (handle())
1723 return GSW_HAL_NORMAL_FAIL;
1724 char cmd[MAX_COMMAND_LEN];
1725 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s status | grep 'signal=' | cut -d '=' -f 2", WLAN_STA_DEV);
1726 FILE *output = popen(cmd, "r");
1727 if (!output)
1728 return GSW_HAL_NORMAL_FAIL;
1729 char buffer[16];
1730 if (fgets(buffer, sizeof(buffer), output) == NULL)
1731 {
1732 pclose(output);
1733 return GSW_HAL_NORMAL_FAIL;
1734 }
1735 pclose(output);
1736 buffer[strcspn(buffer, "\n")] = '\0';
1737 *rssi = atoi(buffer);
1738 return GSW_HAL_SUCCESS;
1739}
1740
1741int gsw_wifi_get_connect_ap_band(gsw_wifi_band_e *band)
1742{
1743 if (handle())
1744 return GSW_HAL_NORMAL_FAIL;
1745 char cmd[MAX_COMMAND_LEN];
1746 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s status | grep 'frequency=' | cut -d '=' -f 2", WLAN_STA_DEV);
1747 FILE *output = popen(cmd, "r");
1748 if (!output)
1749 return GSW_HAL_NORMAL_FAIL;
1750 char buffer[32];
1751 if (fgets(buffer, sizeof(buffer), output) == NULL)
1752 {
1753 pclose(output);
1754 return GSW_HAL_NORMAL_FAIL;
1755 }
1756 pclose(output);
1757 buffer[strcspn(buffer, "\n")] = '\0';
1758 int freq = atoi(buffer);
1759 if (freq < 2500)
1760 {
1761 *band = GSW_WIFI_2G_band;
1762 }
1763 else
1764 {
1765 *band = GSW_WIFI_5G_band;
1766 }
1767 return GSW_HAL_SUCCESS;
1768}
1769
1770int gsw_wifi_get_connect_ap_ip(char *ip)
1771{
1772 if (handle())
1773 return GSW_HAL_NORMAL_FAIL;
1774 char cmd[MAX_COMMAND_LEN];
1775 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s status | grep 'ip_address=' | cut -d '=' -f 2", WLAN_STA_DEV);
1776 FILE *output = popen(cmd, "r");
1777 if (!output)
1778 return GSW_HAL_NORMAL_FAIL;
1779 char buffer[MAX_IP_LEN + 1];
1780 if (fgets(buffer, sizeof(buffer), output) == NULL)
1781 {
1782 pclose(output);
1783 return GSW_HAL_NORMAL_FAIL;
1784 }
1785 pclose(output);
1786 buffer[strcspn(buffer, "\n")] = '\0';
1787 strncpy(ip, buffer, MAX_IP_LEN);
1788 return GSW_HAL_SUCCESS;
1789}
1790
1791int gsw_wifi_get_sta_available_ap(gsw_ap_detail_info_s *info)
1792{
1793 if (handle())
1794 return GSW_HAL_NORMAL_FAIL;
1795 if (is_wpa_supplicant_running() != 0)
1796 {
1797 return GSW_HAL_NORMAL_FAIL;
1798 }
1799 char cmd[MAX_COMMAND_LEN];
1800 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan > /dev/null", WLAN_STA_DEV);
1801 execute_command(cmd);
1802 sleep(1);
1803 memset(cmd, 0, sizeof(cmd));
1804 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan_results | awk '{print $1,$2,$3,$4,$5}' | sort -k3 -nr | head -n 1", WLAN_STA_DEV);
1805 FILE *output = popen(cmd, "r");
1806 if (!output)
1807 return GSW_HAL_NORMAL_FAIL;
1808 char buffer[256];
1809 if (fgets(buffer, sizeof(buffer), output) == NULL)
1810 {
1811 pclose(output);
1812 return GSW_HAL_NORMAL_FAIL;
1813 }
1814 pclose(output);
1815 buffer[strcspn(buffer, "\n")] = '\0';
hong.liud2417072025-06-27 07:10:37 -07001816 sscanf(buffer, "%x %d %31s %31s %31s", (int*)&info->base_info.auth, &info->rssi, info->base_info.ap_ssid, info->base_info.ap_ip, info->base_info.ap_mac);
zw.wang00477802025-06-12 19:48:37 +08001817 info->status = GSW_WIFI_AP_STATUS_ENABLE;
1818 return GSW_HAL_SUCCESS;
1819}
1820
1821int gsw_wifi_get_ap_device_list(gsw_ap_info_s *ap_info, gsw_device_info_s *device_list, int len, int *dev_len)
1822{
1823 if (handle())
1824 return GSW_HAL_NORMAL_FAIL;
1825 char cmd[MAX_COMMAND_LEN];
1826 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s all_sta", WLAN_AP_DEV);
1827 FILE *output = popen(cmd, "r");
1828 if (!output)
1829 return GSW_HAL_NORMAL_FAIL;
1830 char buffer[4096];
1831 size_t length = fread(buffer, 1, sizeof(buffer) - 1, output);
1832 if (length == 0)
1833 {
1834 pclose(output);
1835 return GSW_HAL_NORMAL_FAIL;
1836 }
1837 buffer[length] = '\0';
1838 pclose(output);
1839 // 解析 hostapd_cli 输出,填充 device_list
1840 *dev_len = 0;
1841 return GSW_HAL_SUCCESS;
1842}
1843
1844int gsw_wifi_get_sta_saved_ap(gsw_saved_ap_info_s *list, int len, int *list_len)
1845{
1846 if (handle())
1847 return GSW_HAL_NORMAL_FAIL;
1848 if (is_wpa_supplicant_running() != 0)
1849 {
1850 return GSW_HAL_NORMAL_FAIL;
1851 }
1852 char cmd[MAX_COMMAND_LEN];
1853 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s list_networks", WLAN_STA_DEV);
1854 FILE *output = popen(cmd, "r");
1855 if (!output)
1856 return GSW_HAL_NORMAL_FAIL;
1857 char buffer[4096];
1858 size_t length = fread(buffer, 1, sizeof(buffer) - 1, output);
1859 if (length == 0)
1860 {
1861 pclose(output);
1862 return GSW_HAL_NORMAL_FAIL;
1863 }
1864 buffer[length] = '\0';
1865 pclose(output);
1866 // 解析 wpa_cli 输出,填充 list
1867 *list_len = 0;
1868 return GSW_HAL_SUCCESS;
1869}
1870
1871int gsw_wifi_get_scan_list(gsw_scan_info_s *list, int len, int *list_len)
1872{
1873 if (handle())
1874 return GSW_HAL_NORMAL_FAIL;
1875 if (is_wpa_supplicant_running() != 0)
1876 {
1877 return GSW_HAL_NORMAL_FAIL;
1878 }
1879 char cmd[MAX_COMMAND_LEN];
1880 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan > /dev/null", WLAN_STA_DEV);
1881 execute_command(cmd);
1882 sleep(1);
1883 memset(cmd, 0, sizeof(cmd));
1884 snprintf(cmd, sizeof(cmd), "wpa_cli -i %s scan_results", WLAN_STA_DEV);
1885 FILE *output = popen(cmd, "r");
1886 if (!output)
1887 return GSW_HAL_NORMAL_FAIL;
1888 char buffer[4096];
1889 size_t length = fread(buffer, 1, sizeof(buffer) - 1, output);
1890 if (length == 0)
1891 {
1892 pclose(output);
1893 return GSW_HAL_NORMAL_FAIL;
1894 }
1895 buffer[length] = '\0';
1896 pclose(output);
1897
1898 // 解析 wpa_cli 输出,填充 list
1899 *list_len = 0;
1900 char *line = strtok(buffer, "\n");
1901 // 跳过标题行
1902 if (line)
1903 line = strtok(NULL, "\n");
1904
1905 while (line && *list_len < len)
1906 {
1907 gsw_scan_info_s *info = &list[*list_len];
1908 int freq; // 临时变量用于存储频率,以判断频段
1909 char flags[256]; // 临时变量用于存储认证标志
1910
1911 // 假设输出格式为:bssid freq signal flags ssid
1912 // 解析每一行数据
1913 sscanf(line, "%31s %d %d %255s %32[^\n]", info->mac, &freq, &info->rssi, flags, info->ssid);
1914
1915 // 根据频率判断频段
1916 if (freq < 2500)
1917 {
1918 info->band = GSW_WIFI_2G_band;
1919 }
1920 else
1921 {
1922 info->band = GSW_WIFI_5G_band;
1923 }
1924
1925 // 根据 flags 判断认证方式
1926 if (strstr(flags, "SAE") != NULL || strstr(flags, "WPA3") != NULL)
1927 {
1928 info->auth = GSW_WIFI_AUTH_WPA3_PSK;
1929 }
1930 else if (strstr(flags, "WPA2") != NULL)
1931 {
1932 info->auth = GSW_WIFI_AUTH_WPA2_PSK;
1933 }
1934 else if (strstr(flags, "WPA") != NULL)
1935 {
1936 info->auth = GSW_WIFI_AUTH_WPA_PSK;
1937 }
1938 else
1939 {
1940 info->auth = GSW_WIFI_AUTH_OPEN;
1941 }
1942
1943 (*list_len)++;
1944 line = strtok(NULL, "\n");
1945 }
1946 return GSW_HAL_SUCCESS;
1947}
1948
1949void *ap_event_listener(void *arg)
1950{
1951 char list_cmd[MAX_COMMAND_LEN];
1952 snprintf(list_cmd, sizeof(list_cmd), "hostapd_cli -i %s all_sta | grep -E '^[0-9a-f:]{17}$|connected_time=' | \
1953 awk '/^[0-9a-f:]{17}$/ { mac=$0; getline; if ($0 ~ /connected_time=/) print mac }'",
1954 WLAN_AP_DEV);
1955
1956 // 保存上一次的设备MAC地址列表
1957 char prev_macs[GSW_WIFI_AP_DEVICE_NUM][32] = {0};
1958 int prev_count = 0;
zw.wangbb7f28c2025-06-27 19:41:19 +08001959 while (ap_event_context.running && ap_event_context.gsw_cb)
zw.wang00477802025-06-12 19:48:37 +08001960 {
1961 if (is_hostapd_running() != 0)
1962 {
1963 sleep(5);
1964 continue;
1965 }
1966
1967 // 使用list_cmd获取当前设备MAC列表
1968 char curr_macs[GSW_WIFI_AP_DEVICE_NUM][32] = {0};
1969 int curr_count = 0;
1970 FILE *list_output = popen(list_cmd, "r");
1971 if (list_output)
1972 {
1973 char buffer[1024];
1974 if (fread(buffer, 1, sizeof(buffer) - 1, list_output) > 0)
1975 {
1976 buffer[sizeof(buffer) - 1] = '\0';
1977 char *line = strtok(buffer, "\n");
1978 while (line && curr_count < GSW_WIFI_AP_DEVICE_NUM)
1979 {
1980 if (strchr(line, ':'))
1981 {
1982 strncpy(curr_macs[curr_count], line, 17); // 复制MAC地址
1983 curr_count++;
1984 }
1985 line = strtok(NULL, "\n");
1986 }
1987 }
1988 pclose(list_output);
1989 }
1990
1991 // 数量变化时直接触发事件(保持原有逻辑)
1992 if (curr_count > prev_count && ap_event_context.gsw_cb)
1993 {
1994 ap_event_context.gsw_cb(ap_event_context.arg, GSW_WIFI_STATUS_CONNECT);
1995 }
1996 else if (curr_count < prev_count && ap_event_context.gsw_cb)
1997 {
1998 ap_event_context.gsw_cb(ap_event_context.arg, GSW_WIFI_STATUS_DISCONNECT);
1999 }
2000 else if (curr_count == prev_count && ap_event_context.gsw_cb)
2001 {
2002 int mac_updated = 0;
2003 // 遍历检查是否有MAC地址变化
2004 for (int i = 0; i < curr_count; i++)
2005 {
2006 int found = 0;
2007 for (int j = 0; j < prev_count; j++)
2008 {
2009 if (strcasecmp(curr_macs[i], prev_macs[j]) == 0)
2010 {
2011 found = 1;
2012 break;
2013 }
2014 }
2015 // 发现新MAC地址(当前存在但之前不存在)
2016 if (!found)
2017 {
2018 LOGI("New device connected: %s\n", curr_macs[i]);
2019 mac_updated++;
2020 break;
2021 }
2022 }
2023 // 若有更新则触发连接事件(可根据需求扩展为断开事件)
2024 if (mac_updated)
2025 {
2026 ap_event_context.gsw_cb(ap_event_context.arg, GSW_WIFI_STATUS_DISCONNECT);
2027 ap_event_context.gsw_cb(ap_event_context.arg, GSW_WIFI_STATUS_CONNECT);
2028 }
2029 }
2030
2031 memcpy(prev_macs, curr_macs, sizeof(prev_macs));
2032 prev_count = curr_count;
2033
2034 sleep(2); // 定期轮询
2035 }
2036 return NULL;
2037}
2038
2039/**
2040 * @brief register ap event notification function
2041 * @param [in] arg as gsw_cb function parameter, can be NULL
2042 * @param [in] gsw_cb callback
2043 * @retval 0: success
2044 * @retval other: fail
2045 */
2046int gsw_wifi_reg_ap_event_callback(void *arg, GSW_AP_CALLBACK_FUNC_PTR gsw_cb)
2047{
2048 if (handle())
2049 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +08002050 LOGI("%s - start.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002051 if (ap_event_context.running)
2052 {
2053 return GSW_HAL_NORMAL_FAIL; // 已经注册了回调
2054 }
zw.wangbb7f28c2025-06-27 19:41:19 +08002055 if (arg == NULL)
2056 {
2057 LOGE("%s - arg is NULL.\n",__func__);
2058 }
2059 if (gsw_cb == NULL)
2060 {
2061 LOGE("%s - gsw_cb is NULL.\n",__func__);
2062 return GSW_HAL_NORMAL_FAIL; // 回调函数不能为空
2063 }
zw.wang00477802025-06-12 19:48:37 +08002064 ap_event_context.arg = arg;
2065 ap_event_context.gsw_cb = gsw_cb;
2066 ap_event_context.running = 1;
2067 if (pthread_create(&ap_event_context.thread_id, NULL, ap_event_listener, NULL) != 0)
2068 {
2069 ap_event_context.running = 0;
2070 return GSW_HAL_NORMAL_FAIL;
2071 }
zw.wangbb7f28c2025-06-27 19:41:19 +08002072 LOGI("%s - end.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002073 return GSW_HAL_SUCCESS;
2074}
2075
2076/**
2077 * @brief unregister ap callback function
2078 * @param [in] arg reserved parameter, can be NULL
2079 * @retval 0: success
2080 * @retval other: fail
2081 */
2082int gsw_wifi_unreg_ap_event_callback(void *arg)
2083{
2084 if (handle())
2085 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +08002086 LOGI("%s - start.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002087 ap_event_context.running = 0;
2088
2089 // 检查线程是否存在
2090 if (ap_event_context.thread_id != 0)
2091 {
2092 if (pthread_join(ap_event_context.thread_id, NULL) != 0)
2093 {
2094 return GSW_HAL_NORMAL_FAIL;
2095 }
2096 ap_event_context.thread_id = 0; // 重置线程ID
2097 }
2098
2099 ap_event_context.arg = NULL;
2100 ap_event_context.gsw_cb = NULL;
zw.wangbb7f28c2025-06-27 19:41:19 +08002101 LOGI("%s - end.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002102 return GSW_HAL_SUCCESS;
2103}
2104
2105int gsw_wifi_reg_sta_event_callback(void *arg, GSW_STA_CALLBACK_FUNC_PTR gsw_cb)
2106{
2107 if (handle())
2108 return GSW_HAL_NORMAL_FAIL;
2109 return GSW_HAL_SUCCESS;
2110}
2111
2112int gsw_wifi_unreg_sta_event_callback(void *arg)
2113{
2114 if (handle())
2115 return GSW_HAL_NORMAL_FAIL;
2116 return GSW_HAL_SUCCESS;
2117}
2118
2119int gsw_wifi_sdk_interface_init()
2120{
2121 if (handle())
2122 return GSW_HAL_NORMAL_FAIL;
2123 return GSW_HAL_SUCCESS;
2124}
2125
2126int is_module_loaded(const char *module_name)
2127{
2128 if (handle())
2129 return GSW_HAL_NORMAL_FAIL;
2130 char cmd[MAX_COMMAND_LEN];
2131 snprintf(cmd, sizeof(cmd), "lsmod | grep %s", module_name);
2132 FILE *output = popen(cmd, "r");
2133 if (!output)
2134 return GSW_HAL_NORMAL_FAIL;
2135 char buffer[256];
2136 if (fgets(buffer, sizeof(buffer), output) == NULL)
2137 {
2138 pclose(output);
2139 return GSW_HAL_SUCCESS;
2140 }
2141 pclose(output);
2142 return 1;
2143}
2144/**
2145 * @brief load wifi driver
2146 * @retval 0: success
2147 * @retval other: fail
2148 */
2149int gsw_wifi_enable(void)
2150{
2151 if (handle())
2152 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +08002153 LOGI("%s - start.\n",__func__);
zw.wang89c18242025-06-24 19:07:10 +08002154 if (execute_command("echo 1 > /sys/devices/platform/mbtk-sdh/pwr_ctrl") != 0)
2155 {
2156 return GSW_HAL_NORMAL_FAIL;
2157 }
2158 sleep(1);
zw.wang00477802025-06-12 19:48:37 +08002159 if (!is_module_loaded("cfg80211"))
2160 {
2161 if (execute_command("modprobe cfg80211") != 0)
2162 {
2163 return GSW_HAL_NORMAL_FAIL;
2164 }
2165 }
2166 else
2167 {
2168 LOGI("cfg80211 has insmod.\n");
2169 }
2170
2171 if (!is_module_loaded("aic8800_bsp"))
2172 {
2173 char cmd[MAX_COMMAND_LEN];
2174 snprintf(cmd, sizeof(cmd), "modprobe %s", AIC8800_BSP_DRIVER_PATH);
2175 if (execute_command(cmd) != 0)
2176 {
2177 return GSW_HAL_NORMAL_FAIL;
2178 }
2179 }
2180 else
2181 {
2182 LOGI("aic8800_bsp has insmod.\n");
2183 }
2184
2185 if (!is_module_loaded("aic8800_fdrv"))
2186 {
2187 char cmd[MAX_COMMAND_LEN];
2188 snprintf(cmd, sizeof(cmd), "modprobe %s", AIC8800_FDRV_DRIVER_PATH);
2189 if (execute_command(cmd) != 0)
2190 {
2191 return GSW_HAL_NORMAL_FAIL;
2192 }
2193 }
2194 else
2195 {
2196 LOGI("aic8800_fdrv has insmod.\n");
2197 }
zw.wangbb7f28c2025-06-27 19:41:19 +08002198 LOGI("%s - end.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002199 return GSW_HAL_SUCCESS;
2200}
2201
2202/**
2203 * @brief uninstall wifi driver
2204 * @retval 0: success
2205 * @retval other: fail
2206 */
2207int gsw_wifi_disable(void)
2208{
2209 if (handle())
2210 return GSW_HAL_NORMAL_FAIL;
zw.wangbb7f28c2025-06-27 19:41:19 +08002211 LOGI("%s - start.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002212 if (is_module_loaded("aic8800_fdrv"))
2213 {
2214 if (execute_command("rmmod aic8800_fdrv") != 0)
2215 {
2216 return GSW_HAL_NORMAL_FAIL;
2217 }
2218 }
2219 else
2220 {
2221 LOGI("aic8800_fdrv not insmod.\n");
2222 }
2223
2224 if (is_module_loaded("aic8800_bsp"))
2225 {
2226 if (execute_command("rmmod aic8800_bsp") != 0)
2227 {
2228 return GSW_HAL_NORMAL_FAIL;
2229 }
2230 }
2231 else
2232 {
2233 LOGI("aic8800_bsp not insmod.\n");
2234 }
2235
2236 if (is_module_loaded("cfg80211"))
2237 {
2238 if (execute_command("rmmod cfg80211") != 0)
2239 {
2240 return GSW_HAL_NORMAL_FAIL;
2241 }
2242 }
2243 else
2244 {
2245 LOGI("cfg80211 not insmod.\n");
2246 }
zw.wang89c18242025-06-24 19:07:10 +08002247 if (execute_command("echo 0 > /sys/devices/platform/mbtk-sdh/pwr_ctrl") != 0)
2248 {
2249 return GSW_HAL_NORMAL_FAIL;
2250 }
2251 sleep(1);
zw.wangbb7f28c2025-06-27 19:41:19 +08002252 LOGI("%s - end.\n",__func__);
zw.wang00477802025-06-12 19:48:37 +08002253 return GSW_HAL_SUCCESS;
hong.liud2417072025-06-27 07:10:37 -07002254}
2255
2256int gsw_wifi_sta_disconnect(char *ssid)
2257{
2258 return GSW_HAL_SUCCESS;
zw.wang00477802025-06-12 19:48:37 +08002259}