blob: 8207ed27e3d5b994a7948472ead43f0d0d48b072 [file] [log] [blame]
developer06a01d92022-09-07 16:32:39 +08001/*
2 * If not stated otherwise in this file or this component's LICENSE file the
3 * following copyright and licenses apply:
4 *
5 * Copyright 2019 RDK Management
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18*/
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <string.h>
23#include <fcntl.h>
24#include <stdbool.h>
25#include "wifi_hal.h"
26#include "client_wifi_hal.h"
27
28#include <ev.h>
29#include <wpa_ctrl.h>
30#include <errno.h>
31#include <net/if.h>
developerc2ca2c32022-11-16 10:40:59 +080032#define CTRL_INTERFACE "/var/run/wpa_supplicant"
developer06a01d92022-09-07 16:32:39 +080033
34/* Helper wpa_supplicant events */
35#ifndef container_of
36#define offsetof(st, m) ((size_t)&(((st *)0)->m))
37#define container_of(ptr, type, member) \
38 ((type *)((char *)ptr - offsetof(type, member)))
39#endif /* container_of */
40static int _syscmd(char *cmd, char *retBuf, int retBufSize)
41{
42 FILE *f;
43 char *ptr = retBuf;
44 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
45
46 if((f = popen(cmd, "r")) == NULL) {
47 fprintf(stderr,"\npopen %s error\n", cmd);
48 return RETURN_ERR;
49 }
50
51 while(!feof(f))
52 {
53 *ptr = 0;
54 if(bufSize>=128) {
55 bufbytes=128;
56 } else {
57 bufbytes=bufSize-1;
58 }
59
60 fgets(ptr,bufbytes,f);
61 readbytes=strlen(ptr);
62
63 if(!readbytes)
64 break;
65
66 bufSize-=readbytes;
67 ptr += readbytes;
68 }
69 cmd_ret = pclose(f);
70 retBuf[retBufSize-1]=0;
71
72 return cmd_ret >> 8;
73}
74
75struct ctrl {
76 char sockpath[128];
77 char sockdir[128];
78 char bss[IFNAMSIZ];
79 int ssid_index;
80 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
81 void (*overrun)(struct ctrl *ctrl);
82 void (*closed)(struct ctrl *ctrl);
83 struct wpa_ctrl *wpa;
84 unsigned int ovfl;
85 int initialized;
86 ev_timer retry;
87 ev_stat stat;
88 ev_io io;
89 char reply[4096];
90 size_t reply_len;
91 ev_timer watchdog;
92};
93static wifi_client_event_callback clients_connect_cb;
94static struct ctrl wpa_ctrl[2];
95static int client_initialized;
96
97static void ctrl_close(struct ctrl *ctrl)
98{
99 if (ctrl->io.cb)
100 ev_io_stop(EV_DEFAULT_ &ctrl->io);
101 if (ctrl->retry.cb)
102 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
103 if (ctrl->watchdog.cb)
104 ev_timer_stop(EV_DEFAULT_ &ctrl->watchdog);
105 if (!ctrl->wpa)
106 return;
107
108 wpa_ctrl_detach(ctrl->wpa);
109 wpa_ctrl_close(ctrl->wpa);
110 ctrl->wpa = NULL;
111
112 if (ctrl->closed)
113 ctrl->closed(ctrl);
114}
115
116static void ctrl_process(struct ctrl *ctrl)
117{
118 char *str;
119 size_t len;
120 char buf[1024];
121 int drops;
122 int level;
123 int err;
124 char * k;
125 char * v;
126 char *kv;
127 wifi_client_associated_dev_t ap;
128 memset(&ap, 0, sizeof(ap));
129
130 /* Example events:
131 *
132 * CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
133 * CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
134 */
135 if (!(str = index(ctrl->reply, '>')))
136 return;
137 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
138 return;
139
140 str++;
141
142 if (strncmp("CTRL-EVENT-CONNECTED ", str, 21) == 0) {
143 strsep(&str, " "); /* "-" */
144 strsep(&str, " "); /* "Connection" */
145 strsep(&str, " "); /* "to" */
146
147 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
148 &ap.MACAddress[0], &ap.MACAddress[1], &ap.MACAddress[2],
149 &ap.MACAddress[3], &ap.MACAddress[4], &ap.MACAddress[5]);
150 strsep(&str, " [id="); // completed
151 ap.NetworkID = atoi(str);
152
153 ap.connected = true;
154
155 (clients_connect_cb)(ctrl->ssid_index, &ap);
156 goto handled;
157 }
158 if (strncmp("CTRL-EVENT-DISCONNECTED ", str, 24) == 0) {
159 while ((kv = strsep(&str, " "))) {
160 if ((k = strsep(&kv, "=")) &&
161 (v = strsep(&kv, ""))) {
162 if (!strcmp(k, "bssid"))
163 sscanf(v, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
164 &ap.MACAddress[0], &ap.MACAddress[1], &ap.MACAddress[2],
165 &ap.MACAddress[3], &ap.MACAddress[4], &ap.MACAddress[5]);
166
167 else if (!strcmp(k, "reason"))
168 ap.reason = atoi(v);
169 else if (!strcmp(k, "locally_generated"))
170 ap.locally_generated = atoi(v);
171 }
172 }
173 ap.connected = false;
174 (clients_connect_cb)(ctrl->ssid_index, &ap);
175 goto handled;
176 }
177
178handled:
179
180 return;
181
182}
183
184static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events) {
185 struct ctrl *ctrl = container_of(io, struct ctrl, io);
186 int err;
187
188 ctrl->reply_len = sizeof(ctrl->reply) - 1;
189 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
190 ctrl->reply[ctrl->reply_len] = 0;
191 if (err < 0) {
192 if (errno == EAGAIN || errno == EWOULDBLOCK)
193 return;
194 ctrl_close(ctrl);
195 ev_timer_again(EV_A_ &ctrl->retry);
196 return;
197 }
198
199 ctrl_process(ctrl);
200}
201
202static int ctrl_open(struct ctrl *ctrl)
203{
204 int fd;
205
206 if (ctrl->wpa)
207 return 0;
208
209 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
210 if (!ctrl->wpa)
211 goto err;
212
213 if (wpa_ctrl_attach(ctrl->wpa) < 0)
214 goto err_close;
215
216 fd = wpa_ctrl_get_fd(ctrl->wpa);
217 if (fd < 0)
218 goto err_detach;
219 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
220 ev_io_start(EV_DEFAULT_ &ctrl->io);
221
222 ev_timer_again(EV_DEFAULT_ &ctrl->watchdog);
223
224 return 0;
225
226err_detach:
227 wpa_ctrl_detach(ctrl->wpa);
228err_close:
229 wpa_ctrl_close(ctrl->wpa);
230err:
231 ctrl->wpa = NULL;
232 return -1;
233}
234
235static void ctrl_msg_cb(char *buf, size_t len)
236{
237 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
238 ctrl_process(ctrl);
239}
240
241static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
242{
243 int err;
244
245 if (!ctrl->wpa)
246 return -1;
247 if (*reply_len < 2)
248 return -1;
249
250 (*reply_len)--;
251 ctrl->reply_len = sizeof(ctrl->reply);
252 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
253 if (err < 0)
254 return err;
255
256 if (ctrl->reply_len > *reply_len)
257 ctrl->reply_len = *reply_len;
258
259 *reply_len = ctrl->reply_len;
260 memcpy(reply, ctrl->reply, *reply_len);
261 reply[*reply_len] = 0;
262 return 0;
263}
264
265static void
266ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
267{
268 struct ctrl *ctrl = container_of(timer, struct ctrl, watchdog);
269 const char *pong = "PONG";
270 const char *ping = "PING";
271 char reply[1024];
272 size_t len = sizeof(reply);
273 int err;
274 err = ctrl_request(ctrl, ping, strlen(ping), reply, &len);
275 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong))) {
276 return;
277 }
278 ctrl_close(ctrl);
279 ev_timer_again(EV_A_ &ctrl->retry);
280}
281
282
283static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
284{
285 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
286
287 printf("%s: file state changed", ctrl->bss);
288 ctrl_open(ctrl);
289}
290
291static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
292{
293 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
294
295 printf("CTRL %s: retrying", ctrl->bss);
296 if (ctrl_open(ctrl) < 0)
297 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
298}
299
300static int ctrl_enable(struct ctrl *ctrl)
301{
302 if (ctrl->wpa)
303 return 0;
304
305 if (!ctrl->stat.cb) {
306 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
307 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
308 }
309
310 if (!ctrl->retry.cb)
311 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
312
313 if (!ctrl->watchdog.cb)
314 ev_timer_init(&ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
315
316
317 return ctrl_open(ctrl);
318}
319
320/* client API */
321INT wifi_getSTANumberOfEntries(ULONG *output) //Tr181
322{
developerc2ca2c32022-11-16 10:40:59 +0800323 char cmd[128] = {0};
324 char buf[16] = {0};
325
developer06a01d92022-09-07 16:32:39 +0800326 if (NULL == output)
327 return RETURN_ERR;
328
developerc2ca2c32022-11-16 10:40:59 +0800329 snprintf(cmd, sizeof(cmd), "wpa_cli -g%s-global status | grep ^ifname | wc -l", CTRL_INTERFACE);
330 _syscmd(cmd, buf, sizeof(buf));
331 // *output = 2;
332 *output = strtoll(buf, NULL, 10);
developer06a01d92022-09-07 16:32:39 +0800333 return RETURN_OK;
334}
335
336INT wifi_getSTAName(INT apIndex, CHAR *output_string)
337{
developerc2ca2c32022-11-16 10:40:59 +0800338 int radioIndex = 0;
339 int staIndex = 0;
340
341 if (NULL == output_string || apIndex < 0)
developer06a01d92022-09-07 16:32:39 +0800342 return RETURN_ERR;
developerc2ca2c32022-11-16 10:40:59 +0800343
344 wifi_getSTARadioIndex(apIndex, &radioIndex);
345 staIndex = apIndex % radioIndex;
346 snprintf(output_string, 33, "radio%d-sta%d", radioIndex, staIndex);
developer06a01d92022-09-07 16:32:39 +0800347
348 return RETURN_OK;
349}
350
351INT wifi_getSTARadioIndex(INT ssidIndex, INT *radioIndex)
352{
353 if (NULL == radioIndex)
354 return RETURN_ERR;
developerc2ca2c32022-11-16 10:40:59 +0800355 *radioIndex = ssidIndex%MAX_NUM_RADIOS;
developer06a01d92022-09-07 16:32:39 +0800356 return RETURN_OK;
357}
358
359INT wifi_getSTAMAC(INT ssidIndex, CHAR *output_string)
360{
361 char cmd[128] = {0};
362 int ret = 0;
363 char ssid_ifname[128];
364
365 if (NULL == output_string)
366 return RETURN_ERR;
367
368 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
369 if (ret != RETURN_OK)
370 {
371 return RETURN_ERR;
372 }
373
374 sprintf(cmd, "wpa_cli -i%s status |grep '^address' | cut -f 2 -d =", ssid_ifname);
375 _syscmd(cmd, output_string, 64);
376
377 return RETURN_OK;
378}
379
380INT wifi_getSTABSSID(INT ssidIndex, CHAR *output_string)
381{
382 char cmd[128] = {0};
383 int ret = 0;
384 char ssid_ifname[128];
385
386 if (NULL == output_string)
387 return RETURN_ERR;
388
389 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
390 if (ret != RETURN_OK)
391 {
392 return RETURN_ERR;
393 }
394
395 sprintf(cmd, "wpa_cli -i%s status |grep bssid | cut -f 2 -d =", ssid_ifname);
396 _syscmd(cmd, output_string, 64);
397
398 return RETURN_OK;
399}
400
developerc2ca2c32022-11-16 10:40:59 +0800401INT wifi_setSTABSSID(INT ssidIndex, CHAR *input_string)
402{
403 char cmd[128] = {0};
404 int ret = 0;
405 char ssid_ifname[128];
406 char buf[128] = {0};
407
408 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
409 if (ret != RETURN_OK)
410 return RETURN_ERR;
411
412 snprintf(cmd, sizeof(cmd), "ip link set dev %s address %s", ssid_ifname, input_string);
413 _syscmd(cmd, buf, sizeof(buf));
414
415 return RETURN_OK;
416}
417
developer06a01d92022-09-07 16:32:39 +0800418INT wifi_getSTASSID(INT ssidIndex, CHAR *output_string)
419{
420 char cmd[128] = {0};
421 int ret = 0;
422 char ssid_ifname[128];
423
424 if (NULL == output_string)
425 return RETURN_ERR;
426
427 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
428 if (ret != RETURN_OK)
429 {
430 return RETURN_ERR;
431 }
432
433 sprintf(cmd, "wpa_cli -i%s status |grep ^ssid | cut -f 2 -d = | tr -d '\n'", ssid_ifname);
434 _syscmd(cmd, output_string, 64);
435
436 return RETURN_OK;
437}
438
439INT wifi_getSTACredentials(INT ssidIndex, CHAR *output_string)
440{
441 char cmd[128] = {0};
442 int ret = 0;
443 char ssid_ifname[128];
444
445 if (NULL == output_string)
446 return RETURN_ERR;
447
448 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
449 if (ret != RETURN_OK)
450 {
451 return RETURN_ERR;
452 }
453
454 sprintf(cmd, "wpa_cli -i%s status |grep ssid | cut -f 2 -d =", ssid_ifname);
455 _syscmd(cmd, output_string, 64);
456
457 return RETURN_OK;
458}
459
460static int init_client_wpa()
461{
462 int ret = 0, i = 0;
463 ULONG s, snum;
464 char * sock_path;
465 char ssid_ifname[128];
466
467 ret = wifi_getSTANumberOfEntries(&snum);
468 if (ret != RETURN_OK) {
469 printf("%s: failed to get SSID count", __func__);
470 return RETURN_ERR;
471 }
472
473 for (s = 0; s < snum; s++) {
474 ret = wifi_getSTAName(s, ssid_ifname);
475 if (ret != RETURN_OK)
476 {
477 return RETURN_ERR;
478 }
developerc2ca2c32022-11-16 10:40:59 +0800479 sprintf(wpa_ctrl[s].sockpath, "%s/%s", CTRL_INTERFACE, ssid_ifname);
developer06a01d92022-09-07 16:32:39 +0800480 wpa_ctrl[s].ssid_index = s;
481 printf("Opening ctrl for %s\n", ssid_ifname);
482 if (ctrl_enable(&wpa_ctrl[s]))
483 {
484 return RETURN_ERR;
485 }
486 }
487
488 client_initialized = 1;
489
490 return RETURN_OK;
491}
492
493void wifi_client_event_callback_register(wifi_client_event_callback callback_proc)
494{
495 clients_connect_cb = callback_proc;
496 printf("Registering callback STA\n");
497 if (!client_initialized)
498 init_client_wpa();
499}
500
501INT wifi_getSTANetworks(INT apIndex, wifi_sta_network_t **out_staNetworks_array, INT out_array_size, BOOL *out_scan_cur_freq)
502{
503 FILE *fd = NULL;
504 char fname[100];
505 char * line = NULL;
506 char * pos = NULL;
507 size_t len = 0;
508 ssize_t read = 0;
509 int id = 0;
510 int ret = 0;
511 char * k;
512 char * v;
513 char *kv;
514 wifi_sta_network_t * staNetwork;
515
developerc2ca2c32022-11-16 10:40:59 +0800516 if(out_array_size <= 0 )
517 return RETURN_ERR;
developer06a01d92022-09-07 16:32:39 +0800518
519 char ssid_ifname[128];
520
521 ret = wifi_getSTAName(apIndex, ssid_ifname);
developerc2ca2c32022-11-16 10:40:59 +0800522 if (ret != RETURN_OK)
developer06a01d92022-09-07 16:32:39 +0800523 return RETURN_ERR;
developer06a01d92022-09-07 16:32:39 +0800524
developerc2ca2c32022-11-16 10:40:59 +0800525 snprintf(fname, sizeof(fname), "/nvram/%s.conf", ssid_ifname);
developer06a01d92022-09-07 16:32:39 +0800526 fd = fopen(fname, "r");
developerc2ca2c32022-11-16 10:40:59 +0800527 if (!fd)
developer06a01d92022-09-07 16:32:39 +0800528 return RETURN_ERR;
developerc2ca2c32022-11-16 10:40:59 +0800529
developer06a01d92022-09-07 16:32:39 +0800530 staNetwork= *out_staNetworks_array;
531 while ((read = getline(&line, &len, fd)) != -1) {
532 if(!strncmp(line, "network={",strlen("network={"))) {
533 read = getline(&line, &len, fd) ;
534 staNetwork->id = id;
535 while (strncmp(line,"}",1)) {
536 if ((k = strsep(&line, "=")) &&
537 (v = strsep(&line, ""))) {
538 if (!strcmp(k, "\tssid"))
539 {
540 v++; //skip quote
541 v = strsep(&v, "\"");
542 strncpy(staNetwork->ssid, v,32);
543 }
544 else if (!strcmp(k, "\tpsk"))
545 {
546 v++; //skip quote
547 v = strsep(&v, "\"");
548 strncpy(staNetwork->psk, v,128);
549 }
550 else if (!strcmp(k, "\tpairwise"))
551 strncpy(staNetwork->pairwise, v,64);
552 else if (!strcmp(k, "\tkey_mgmt"))
553 strncpy(staNetwork->key_mgmt, v,64);
554 else if (!strcmp(k, "\tproto"))
555 {
556 v = strsep(&v, "\n");
557 strncpy(staNetwork->proto, v,64);
558 }
559 else if (!strcmp(k, "\tbssid"))
560 sscanf(v, "%02x:%02x:%02x:%02x:%02x:%02x",
561 (unsigned int *)&staNetwork->bssid[0],
562 (unsigned int *)&staNetwork->bssid[1],
563 (unsigned int *)&staNetwork->bssid[2],
564 (unsigned int *)&staNetwork->bssid[3],
565 (unsigned int *)&staNetwork->bssid[4],
566 (unsigned int *)&staNetwork->bssid[5]);
567 else if (!strcmp(k, "multi_ap_backhaul_sta"))
568 staNetwork->multi_ap = atoi(v);
569 }
570 if((read = getline(&line, &len, fd)) == -1)
571 break;
572 }
573 id++;
574 if(id >= out_array_size)
575 goto close;
576 staNetwork++;
developer30423732022-12-01 16:17:49 +0800577 }
developer06a01d92022-09-07 16:32:39 +0800578 }
579close:
580 fclose(fd);
581 return RETURN_OK;
582
583
584}
585
586INT wifi_setSTANetworks(INT apIndex, wifi_sta_network_t **staNetworks_array, INT array_size, BOOL scan_cur_freq)
587{
588 FILE *fd = NULL;
developerc2ca2c32022-11-16 10:40:59 +0800589 char fname[100] = {0};
developer06a01d92022-09-07 16:32:39 +0800590 char cmd[128] = {0};
591 char out[64] = {0};
592 int ret = 0;
developerc2ca2c32022-11-16 10:40:59 +0800593 char zero[8] = {0};
594 bool enable_current = FALSE;
developer06a01d92022-09-07 16:32:39 +0800595
developerc2ca2c32022-11-16 10:40:59 +0800596 wifi_sta_network_t *sta = NULL;
developer06a01d92022-09-07 16:32:39 +0800597 if(array_size < 0)
598 return RETURN_ERR;
599 char ssid_ifname[128];
600
601 ret = wifi_getSTAName(apIndex, ssid_ifname);
602 if (ret != RETURN_OK)
developer06a01d92022-09-07 16:32:39 +0800603 return RETURN_ERR;
developerc2ca2c32022-11-16 10:40:59 +0800604 snprintf(fname, sizeof(fname), "/nvram/%s.conf", ssid_ifname);
developer30423732022-12-01 16:17:49 +0800605 sprintf(cmd, "touch %s && cp %s /nvram/%s.old", fname, fname, ssid_ifname);
developer06a01d92022-09-07 16:32:39 +0800606 _syscmd(cmd, out, 64);
607
developer06a01d92022-09-07 16:32:39 +0800608 fd = fopen(fname, "w");
609 if (!fd) {
610 return RETURN_ERR;
611 }
developerc2ca2c32022-11-16 10:40:59 +0800612 fprintf(fd, "ctrl_interface=%s\n", CTRL_INTERFACE);
developer06a01d92022-09-07 16:32:39 +0800613 fprintf(fd, "scan_cur_freq=%d\n", scan_cur_freq ? 1 : 0);
614
developerc2ca2c32022-11-16 10:40:59 +0800615 sta = *staNetworks_array;
developer06a01d92022-09-07 16:32:39 +0800616 for(int i=0; i<array_size; ++i, sta++) {
617 fprintf(fd, "network={\n");
618 fprintf(fd, "\tscan_ssid=1\n");
619 fprintf(fd, "\tbgscan=\"\"\n");
620 fprintf(fd, "\tssid=\"%s\"\n", sta->ssid);
developerc2ca2c32022-11-16 10:40:59 +0800621 if (sta->psk_len > 7 && sta->psk_len < 128)
622 fprintf(fd, "\tpsk=\"%s\"\n", sta->psk);
developer06a01d92022-09-07 16:32:39 +0800623 fprintf(fd, "\tkey_mgmt=%s\n", sta->key_mgmt);
developer5c9fee82023-01-13 14:44:16 +0800624 if (!strncmp(sta->key_mgmt, "SAE", 3) || !strncmp(sta->key_mgmt, "OWE", 3)) { // wpa3-personal must use with ieee80211w
developerc2ca2c32022-11-16 10:40:59 +0800625 fprintf(fd, "\tieee80211w=2\n");
developer06a01d92022-09-07 16:32:39 +0800626 }
developerc2ca2c32022-11-16 10:40:59 +0800627 fprintf(fd, "\tpairwise=%s\n", sta->pairwise);
628 if (memcmp(sta->bssid, zero, sizeof(sta->bssid)) != 0) // Not 00:00:00:00:00:00 means need to specify ap mac address.
629 fprintf(fd, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", sta->bssid[0],sta->bssid[1],sta->bssid[2],sta->bssid[3],sta->bssid[4],sta->bssid[5]);
developer06a01d92022-09-07 16:32:39 +0800630 fprintf(fd, "}\n");
631 }
632 fclose(fd);
633
developerc2ca2c32022-11-16 10:40:59 +0800634 wifi_getSTAEnabled(apIndex, &enable_current);
635 sprintf(cmd, "diff -q /nvram/%s.conf /nvram/%s.old", ssid_ifname, ssid_ifname);
636 if (enable_current && _syscmd(cmd, out, 64))
developer06a01d92022-09-07 16:32:39 +0800637 {
638 sprintf(cmd, "wpa_cli -B -i%s reconfigure", ssid_ifname);
639 _syscmd(cmd, out, 64);
developer06a01d92022-09-07 16:32:39 +0800640 }
developerc2ca2c32022-11-16 10:40:59 +0800641 sprintf(cmd, "rm /nvram/%s.old", ssid_ifname);
developer06a01d92022-09-07 16:32:39 +0800642 _syscmd(cmd, out, 64);
643
644 return RETURN_OK;
645
646}
647
648INT wifi_getSTAEnabled(INT ssidIndex, BOOL *enabled)
649{
650 char ssid_ifname[128];
651 char cmd[128] = {0};
652 char out[64] = {0};
653 int ret = 0;
654
655 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
656 if (ret != RETURN_OK)
657 {
658 return RETURN_ERR;
659 }
660
661 sprintf(cmd, "wpa_cli -g/var/run/wpa_supplicant-global -i global status | grep %s", ssid_ifname);
662 ret = _syscmd(cmd, out, 64);
663 *enabled = ret == 0 ? true : false;
664
665 return RETURN_OK;
666}
667
668INT wifi_setSTAEnabled(INT ssidIndex, BOOL enable)
669{
670 char ssid_ifname[128];
developerc2ca2c32022-11-16 10:40:59 +0800671 char cmd[256] = {0};
developer06a01d92022-09-07 16:32:39 +0800672 char out[64] = {0};
673 int ret = 0;
developerc2ca2c32022-11-16 10:40:59 +0800674 int radioIndex = 0;
developer06a01d92022-09-07 16:32:39 +0800675
676 BOOL en;
677 wifi_getSTAEnabled(ssidIndex,&en);
678 if (enable == en)
679 return RETURN_OK;
680
681 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
developerc2ca2c32022-11-16 10:40:59 +0800682 if (ret != RETURN_OK)
developer06a01d92022-09-07 16:32:39 +0800683 return RETURN_ERR;
developer06a01d92022-09-07 16:32:39 +0800684
developerc2ca2c32022-11-16 10:40:59 +0800685 if (enable) {
686 snprintf(cmd, sizeof(cmd), "wpa_cli -g/var/run/wpa_supplicant-global interface_add %s /nvram/%s.conf nl80211 /var/run/wpa_supplicant", ssid_ifname, ssid_ifname);
687 ret = _syscmd(cmd, out, 64);
688 } else {
689 snprintf(cmd, sizeof(cmd), "wpa_cli -g/var/run/wpa_supplicant-global -i global interface_remove %s", ssid_ifname);
690 ret = _syscmd(cmd, out, 64);
developer06a01d92022-09-07 16:32:39 +0800691 }
692
693 return ret == 0 ? RETURN_OK : RETURN_ERR;
694}
developerc2ca2c32022-11-16 10:40:59 +0800695
developer1e125222022-12-29 09:35:25 +0800696INT wifi_createSTAInterface(INT ssidIndex, char *bssid, BOOL wds_flag)
developerc2ca2c32022-11-16 10:40:59 +0800697{
698 char cmd[128] = {0};
699 char buf[128] = {0};
700 char ssid_ifname[128] = {0};
701 int radioIndex = 0;
702 int phyIndex = 0;
703 int ret = 0;
704
705 ret = wifi_getSTAName(ssidIndex, ssid_ifname);
706 if (ret != RETURN_OK)
707 return RETURN_ERR;
708
709 wifi_getSTARadioIndex(ssidIndex, &radioIndex);
710 phyIndex = radio_index_to_phy(radioIndex);
711 if (phyIndex == -1) {
developer30423732022-12-01 16:17:49 +0800712 fprintf(stderr, "%s: Invalid radio index %d.\n", __func__, radioIndex);
developerc2ca2c32022-11-16 10:40:59 +0800713 return RETURN_ERR;
714 }
developer1e125222022-12-29 09:35:25 +0800715 snprintf(cmd, sizeof(cmd), "iw phy phy%d interface add %s type managed %s", phyIndex, ssid_ifname, wds_flag?"4addr on":"");
developerc2ca2c32022-11-16 10:40:59 +0800716 _syscmd(cmd, buf, sizeof(buf));
717 snprintf(cmd, sizeof(cmd), "ip link set dev %s address %s && ip link set dev %s up", ssid_ifname, bssid, ssid_ifname);
718 _syscmd(cmd, buf, sizeof(buf));
719
720 return RETURN_OK;
721}