blob: aa586ed3d55a66118ae6d2e0538f3e58467abf62 [file] [log] [blame]
developer72fb0bb2023-01-11 09:46:29 +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
20/*
21* Material from the TR181 data model is Copyright (c) 2010-2017, Broadband Forum
22* Licensed under the BSD-3 license
23*/
24
25/*
26* This file includes material that is Copyright (c) 2020, Plume Design Inc.
27* Licensed under the BSD-3 license
28*/
29
30/* Code in rxStatsInfo_callback and other callbacks is credited as follows:
31Copyright (c) 2007, 2008 Johannes Berg
32Copyright (c) 2007 Andy Lutomirski
33Copyright (c) 2007 Mike Kershaw
34Copyright (c) 2008-2009 Luis R. Rodriguez
35Licensed under the ISC license
36*/
37#define MTK_IMPL
38#define HAL_NETLINK_IMPL
39#define _GNU_SOURCE /* needed for strcasestr */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44#include <string.h>
45#include <fcntl.h>
46#include <stdbool.h>
47#include "wifi_hal.h"
48
49#ifdef HAL_NETLINK_IMPL
50#include <errno.h>
51#include <netlink/attr.h>
52#include <netlink/netlink.h>
53#include <netlink/genl/genl.h>
54#include <netlink/genl/family.h>
55#include <netlink/genl/ctrl.h>
56#include <linux/nl80211.h>
57#include<net/if.h>
58#endif
59
60#include <ev.h>
61#include <wpa_ctrl.h>
62#include <errno.h>
63#include <time.h>
64#define MAC_ALEN 6
65
66#define MAX_BUF_SIZE 256
67#define MAX_CMD_SIZE 256
68#define IF_NAME_SIZE 16
69#define CONFIG_PREFIX "/nvram/hostapd"
70#define ACL_PREFIX "/nvram/hostapd-acl"
71#define DENY_PREFIX "/nvram/hostapd-deny"
72//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
73#define SOCK_PREFIX "/var/run/hostapd/wifi"
74#define VAP_STATUS_FILE "/nvram/vap-status"
75#define ESSID_FILE "/tmp/essid"
76#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
77#define CHANNEL_STATS_FILE "/tmp/channel_stats"
78#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
79#define VLAN_FILE "/nvram/hostapd.vlan"
80#define PSK_FILE "/nvram/hostapd"
81#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080082#define POWER_PERCENTAGE "/tmp/POWER"
83#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
84/*LOGAN_DAT_FILE: may be different on customer's platform.*/
85#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
86
developer72fb0bb2023-01-11 09:46:29 +080087#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerf6a87542023-05-16 15:47:28 +080088
developer72fb0bb2023-01-11 09:46:29 +080089#define BRIDGE_NAME "brlan0"
90
91/*
92 MAX_APS - Number of all AP available in system
93 2x Home AP
94 2x Backhaul AP
95 2x Guest AP
96 2x Secure Onboard AP
97 2x Service AP
98
99*/
100
101
102#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800103
104#define PREFIX_WIFI2G "ra"
105#define PREFIX_WIFI5G "rai"
106#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800107
108#ifndef RADIO_PREFIX
109#define RADIO_PREFIX "wlan"
110#endif
111
112#define MAX_ASSOCIATED_STA_NUM 2007
113
114//Uncomment to enable debug logs
115//#define WIFI_DEBUG
116
117#ifdef WIFI_DEBUG
118#define wifi_dbg_printf printf
119#define WIFI_ENTRY_EXIT_DEBUG printf
120#else
121#define wifi_dbg_printf(format, args...) printf("")
122#define WIFI_ENTRY_EXIT_DEBUG(format, args...) printf("")
123#endif
124
125#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
126#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
127#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
128#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
129#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
130#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
131#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
132#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
133#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
134#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
135
136#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
137
138#define BW_FNAME "/nvram/bw_file.txt"
139
140#define PS_MAX_TID 16
141
developer96b38512023-02-22 11:17:45 +0800142#define MAX_CARD_INDEX 3
143
developer72fb0bb2023-01-11 09:46:29 +0800144static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
145 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
146 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
147 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
148 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
149 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
150 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
151 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
152 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
153 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
154 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
155 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
156 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
157 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
158 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
159 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
160 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
161};
162
163typedef unsigned long long u64;
164
165/* Enum to define WiFi Bands */
166typedef enum
167{
168 band_invalid = -1,
169 band_2_4 = 0,
170 band_5 = 1,
171 band_6 = 2,
172} wifi_band;
173
developer17038e62023-03-02 14:43:43 +0800174char* wifi_band_str[] = {
175 "2G",
176 "5G",
177 "6G",
178};
179
developer72fb0bb2023-01-11 09:46:29 +0800180typedef enum {
181 WIFI_MODE_A = 0x01,
182 WIFI_MODE_B = 0x02,
183 WIFI_MODE_G = 0x04,
184 WIFI_MODE_N = 0x08,
185 WIFI_MODE_AC = 0x10,
186 WIFI_MODE_AX = 0x20,
developera1255e42023-05-13 17:45:02 +0800187 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800188} wifi_ieee80211_Mode;
189
190#ifdef WIFI_HAL_VERSION_3
191
192// Return number of elements in array
193#ifndef ARRAY_SIZE
194#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
195#endif /* ARRAY_SIZE */
196
197#ifndef ARRAY_AND_SIZE
198#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
199#endif /* ARRAY_AND_SIZE */
200
201#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
202
203typedef struct {
204 int32_t value;
205 int32_t param;
206 intptr_t key;
207 intptr_t data;
208} wifi_secur_list;
209
210static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
211static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
212wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
213wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
214char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
215static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
216
217static wifi_secur_list map_security[] =
218{
219 WIFI_ITEM_STR(wifi_security_mode_none, "None"),
220 WIFI_ITEM_STR(wifi_security_mode_wep_64, "WEP-64"),
221 WIFI_ITEM_STR(wifi_security_mode_wep_128, "WEP-128"),
222 WIFI_ITEM_STR(wifi_security_mode_wpa_personal, "WPA-Personal"),
223 WIFI_ITEM_STR(wifi_security_mode_wpa_enterprise, "WPA-Enterprise"),
224 WIFI_ITEM_STR(wifi_security_mode_wpa2_personal, "WPA2-Personal"),
225 WIFI_ITEM_STR(wifi_security_mode_wpa2_enterprise, "WPA2-Enterprise"),
226 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_personal, "WPA-WPA2-Personal"),
227 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_enterprise, "WPA-WPA2-Enterprise"),
228 WIFI_ITEM_STR(wifi_security_mode_wpa3_personal, "WPA3-Personal"),
229 WIFI_ITEM_STR(wifi_security_mode_wpa3_transition, "WPA3-Personal-Transition"),
230 WIFI_ITEM_STR(wifi_security_mode_wpa3_enterprise, "WPA3-Enterprise")
231};
232
233wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
234{
235 wifi_secur_list *item;
236 int i;
237
238 for (item = list,i = 0;i < list_sz; item++, i++) {
239 if ((int)(item->key) == key) {
240 return item;
241 }
242 }
243
244 return NULL;
245}
246
247char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
248{
249 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
250
251 if (!item) {
252 return "";
253 }
254
255 return (char *)(item->data);
256}
257
258wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
259{
260 wifi_secur_list *item;
261 int i;
262
263 for (item = list,i = 0;i < list_sz; item++, i++) {
264 if (strcmp((char *)(item->data), str) == 0) {
265 return item;
266 }
267 }
268
269 return NULL;
270}
271#endif /* WIFI_HAL_VERSION_3 */
272
developer96b38512023-02-22 11:17:45 +0800273
274static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800275char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
276char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
277#define MAX_SSID_LEN 64
278char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800279int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800280
281static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
282static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
283
developer96b38512023-02-22 11:17:45 +0800284
285static int
286get_value(const char *conf_file, const char *param, char *value, int len)
287{
288 FILE *fp;
289 int ret = -1;
290 int param_len = strlen(param);
291 int buf_len;
292 char buf[256];
293
294 fp = fopen(conf_file, "r");
295 if (!fp) {
296 return -1;
297 }
298
299 while (fgets(buf, sizeof(buf), fp)) {
300 buf_len = strlen(buf);
301 if (buf[buf_len - 1] == '\n') {
302 buf_len--;
303 buf[buf_len] = '\0';
304 }
305 if ((buf_len > param_len) &&
306 (strncmp(buf, param, param_len) == 0) &&
307 (buf[param_len] == '=')) {
308
309 if (buf_len == (param_len + 1)) {
310 value[0] = '\0';
311 ret = 0;
312 } else {
313 ret = snprintf(value, len, "%s", buf + (param_len + 1));
314 }
315 fclose(fp);
316 return ret;
317 }
318 }
319 fclose(fp);
320 return -1;
321}
322
323static int
324get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
325{
326 char buf[256];
327 int ret;
328 char *save_ptr = NULL;
329 char *tok = NULL;
330
331 ret = get_value(conf_file, param, buf, sizeof(buf));
332 if (ret < 0)
333 return ret;
334
335 tok = strtok_r(buf, ";", &save_ptr);
336 do {
337 if (idx == 0 || tok == NULL)
338 break;
339 else
340 idx--;
341
342 tok = strtok_r(NULL, ";", &save_ptr);
343 } while (tok != NULL);
344
345 if (tok) {
346 ret = snprintf(value, len, "%s", tok);
347 } else {
348 ret = 0;
349 value[0] = '\0';
350 }
351
352 return ret;
353}
354
355
developer72fb0bb2023-01-11 09:46:29 +0800356#ifdef HAL_NETLINK_IMPL
357typedef struct {
358 int id;
359 struct nl_sock* socket;
360 struct nl_cb* cb;
361} Netlink;
362
363static int mac_addr_aton(unsigned char *mac_addr, char *arg)
364{
365 unsigned int mac_addr_int[6]={};
366 sscanf(arg, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int+0, mac_addr_int+1, mac_addr_int+2, mac_addr_int+3, mac_addr_int+4, mac_addr_int+5);
367 mac_addr[0] = mac_addr_int[0];
368 mac_addr[1] = mac_addr_int[1];
369 mac_addr[2] = mac_addr_int[2];
370 mac_addr[3] = mac_addr_int[3];
371 mac_addr[4] = mac_addr_int[4];
372 mac_addr[5] = mac_addr_int[5];
373 return 0;
374}
375
376static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
377{
378 unsigned int mac_addr_int[6]={};
379 mac_addr_int[0] = arg[0];
380 mac_addr_int[1] = arg[1];
381 mac_addr_int[2] = arg[2];
382 mac_addr_int[3] = arg[3];
383 mac_addr_int[4] = arg[4];
384 mac_addr_int[5] = arg[5];
385 snprintf(mac_addr, 20, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int[0], mac_addr_int[1],mac_addr_int[2],mac_addr_int[3],mac_addr_int[4],mac_addr_int[5]);
386 return;
387}
388
389static int ieee80211_frequency_to_channel(int freq)
390{
391 /* see 802.11-2007 17.3.8.3.2 and Annex J */
392 if (freq == 2484)
393 return 14;
394 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
395 else if (freq == 5935)
396 return 2;
397 else if (freq < 2484)
398 return (freq - 2407) / 5;
399 else if (freq >= 4910 && freq <= 4980)
400 return (freq - 4000) / 5;
401 else if (freq < 5950)
402 return (freq - 5000) / 5;
403 else if (freq <= 45000) /* DMG band lower limit */
404 /* see 802.11ax D6.1 27.3.23.2 */
405 return (freq - 5950) / 5;
406 else if (freq >= 58320 && freq <= 70200)
407 return (freq - 56160) / 2160;
408 else
409 return 0;
410}
411
412static int initSock80211(Netlink* nl) {
413 nl->socket = nl_socket_alloc();
414 if (!nl->socket) {
415 fprintf(stderr, "Failing to allocate the sock\n");
416 return -ENOMEM;
417 }
418
419 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
420
421 if (genl_connect(nl->socket)) {
422 fprintf(stderr, "Failed to connect\n");
423 nl_close(nl->socket);
424 nl_socket_free(nl->socket);
425 return -ENOLINK;
426 }
427
428 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
429 if (nl->id< 0) {
430 fprintf(stderr, "interface not found.\n");
431 nl_close(nl->socket);
432 nl_socket_free(nl->socket);
433 return -ENOENT;
434 }
435
436 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
437 if ((!nl->cb)) {
438 fprintf(stderr, "Failed to allocate netlink callback.\n");
439 nl_close(nl->socket);
440 nl_socket_free(nl->socket);
441 return ENOMEM;
442 }
443
444 return nl->id;
445}
446
447static int nlfree(Netlink *nl)
448{
449 nl_cb_put(nl->cb);
450 nl_close(nl->socket);
451 nl_socket_free(nl->socket);
452 return 0;
453}
454
455static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
456 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
457 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
458 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
459};
460
461static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
462};
463
464static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
465};
466
467typedef struct _wifi_channelStats_loc {
468 INT array_size;
469 INT ch_number;
470 BOOL ch_in_pool;
471 INT ch_noise;
472 BOOL ch_radar_noise;
473 INT ch_max_80211_rssi;
474 INT ch_non_80211_noise;
475 INT ch_utilization;
476 ULLONG ch_utilization_total;
477 ULLONG ch_utilization_busy;
478 ULLONG ch_utilization_busy_tx;
479 ULLONG ch_utilization_busy_rx;
480 ULLONG ch_utilization_busy_self;
481 ULLONG ch_utilization_busy_ext;
482} wifi_channelStats_t_loc;
483
484typedef struct wifi_device_info {
485 INT wifi_devIndex;
486 UCHAR wifi_devMacAddress[6];
487 CHAR wifi_devIPAddress[64];
488 BOOL wifi_devAssociatedDeviceAuthentiationState;
489 INT wifi_devSignalStrength;
490 INT wifi_devTxRate;
491 INT wifi_devRxRate;
492} wifi_device_info_t;
493
494#endif
495
496//For 5g Alias Interfaces
497static BOOL priv_flag = TRUE;
498static BOOL pub_flag = TRUE;
499static BOOL Radio_flag = TRUE;
500//wifi_setApBeaconRate(1, beaconRate);
501
502BOOL multiple_set = FALSE;
503
504struct params
505{
506 char * name;
507 char * value;
508};
509
510static int _syscmd(char *cmd, char *retBuf, int retBufSize)
511{
512 FILE *f;
513 char *ptr = retBuf;
514 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
515
516 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
517 if((f = popen(cmd, "r")) == NULL) {
518 fprintf(stderr,"\npopen %s error\n", cmd);
519 return RETURN_ERR;
520 }
521
522 while(!feof(f))
523 {
524 *ptr = 0;
525 if(bufSize>=128) {
526 bufbytes=128;
527 } else {
528 bufbytes=bufSize-1;
529 }
530
531 fgets(ptr,bufbytes,f);
532 readbytes=strlen(ptr);
533
534 if(!readbytes)
535 break;
536
537 bufSize-=readbytes;
538 ptr += readbytes;
539 }
540 cmd_ret = pclose(f);
541 retBuf[retBufSize-1]=0;
542 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
543
544 return cmd_ret >> 8;
545}
546
547INT radio_index_to_phy(int radioIndex)
548{
developer17038e62023-03-02 14:43:43 +0800549 /* TODO */
550 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800551}
552
553INT wifi_getMaxRadioNumber(INT *max_radio_num)
554{
555 char cmd[64] = {0};
556 char buf[4] = {0};
557
558 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
559
560 snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
561 _syscmd(cmd, buf, sizeof(buf));
562 *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10);
563
564 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
565
566 return RETURN_OK;
567}
568
developer17038e62023-03-02 14:43:43 +0800569wifi_band radio_index_to_band(int radioIndex)
570{
developer745f0bd2023-03-06 14:32:53 +0800571 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800572}
573
developer72fb0bb2023-01-11 09:46:29 +0800574wifi_band wifi_index_to_band(int apIndex)
575{
576 char cmd[128] = {0};
577 char buf[64] = {0};
578 int nl80211_band = 0;
579 int i = 0;
580 int phyIndex = 0;
581 int radioIndex = 0;
582 int max_radio_num = 0;
583 wifi_band band = band_invalid;
584
585 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
586
587 wifi_getMaxRadioNumber(&max_radio_num);
588 radioIndex = apIndex % max_radio_num;
589 phyIndex = radio_index_to_phy(radioIndex);
590 while(i < 10){
591 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
592 _syscmd(cmd, buf, sizeof(buf));
593 nl80211_band = strtol(buf, NULL, 10);
594 if (nl80211_band == 1)
595 band = band_2_4;
596 else if (nl80211_band == 2)
597 band = band_5;
598 else if (nl80211_band == 4) // band == 3 is 60GHz
599 band = band_6;
600
601 if(band != band_invalid)
602 break;
developer69b61b02023-03-07 17:17:44 +0800603
developer72fb0bb2023-01-11 09:46:29 +0800604 i++;
605 sleep(1);
606 }
607
608 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
609 return band;
610}
611
612static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
613{
developer7e4a2a62023-04-06 19:56:03 +0800614 char cmd[MAX_CMD_SIZE] = {0};
615 char buf[MAX_BUF_SIZE] = {0};
616 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +0800617
developer7e4a2a62023-04-06 19:56:03 +0800618 ret = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
619 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800620
developer7e4a2a62023-04-06 19:56:03 +0800621 if (ret < 0) {
622 printf("%s: snprintf error!", __func__);
623 return -1;
624 }
625
626 ret = _syscmd(cmd, buf, sizeof(buf));
627 if ((ret != 0) && (strlen(buf) == 0)) {
628 printf("%s: _syscmd error!", __func__);
629 return -1;
630 }
631
632 snprintf(output, output_size, "%s", buf);
633
634 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800635}
636
637static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
638{
developer7e4a2a62023-04-06 19:56:03 +0800639 char cmd[MAX_CMD_SIZE] = {0};
640 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +0800641
developer7e4a2a62023-04-06 19:56:03 +0800642 for (int i = 0; i < item_count; i++) {
developer72fb0bb2023-01-11 09:46:29 +0800643 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +0800644 if (strlen(buf) == 0) /*no such item, insert it*/
developera1255e42023-05-13 17:45:02 +0800645 snprintf(cmd, sizeof(cmd), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file);
developer7e4a2a62023-04-06 19:56:03 +0800646 else /*find the item, update it*/
developer72fb0bb2023-01-11 09:46:29 +0800647 snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file);
developera1255e42023-05-13 17:45:02 +0800648
developer72fb0bb2023-01-11 09:46:29 +0800649 if(_syscmd(cmd, buf, sizeof(buf)))
650 return -1;
651 }
652
developera1255e42023-05-13 17:45:02 +0800653 return 0;
654}
655static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
656{
657 char cmd[MAX_CMD_SIZE] = {0};
658 char buf[MAX_BUF_SIZE] = {0};
659 int ret = 0;
660
661 ret = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
662 conf_file, param);
663
664 if (ret < 0) {
665 printf("%s: snprintf error!", __func__);
666 return -1;
667 }
668
669 ret = _syscmd(cmd, buf, sizeof(buf));
670 if ((ret != 0) && (strlen(buf) == 0)) {
671 printf("%s: _syscmd error!", __func__);
672 return -1;
673 }
674
675 snprintf(output, output_size, "%s", buf);
676
developer72fb0bb2023-01-11 09:46:29 +0800677 return 0;
678}
679
developera1255e42023-05-13 17:45:02 +0800680static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
681{
682 char cmd[MAX_CMD_SIZE] = {0};
683 char buf[MAX_BUF_SIZE] = {0};
684
685 for (int i = 0; i < item_count; i++) {
686 wifi_datfileRead(conf_file, list[i].name, buf, sizeof(buf));
687 if (strlen(buf) == 0) /*no such item, insert it*/
688 snprintf(cmd, sizeof(cmd), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file);
689 else /*find the item, update it*/
690 snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file);
691
692 if(_syscmd(cmd, buf, sizeof(buf)))
693 return -1;
694 }
695
696 return 0;
697}
698
developer72fb0bb2023-01-11 09:46:29 +0800699//For Getting Current Interface Name from corresponding hostapd configuration
700static int wifi_GetInterfaceName(int apIndex, char *interface_name)
701{
702 char config_file[128] = {0};
703
704 if (interface_name == NULL)
705 return RETURN_ERR;
706
707 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
708
709 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
710 wifi_hostapdRead(config_file, "interface", interface_name, 16);
711 if (strlen(interface_name) == 0)
712 return RETURN_ERR;
713
714 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
715 return RETURN_OK;
716}
717
developera1255e42023-05-13 17:45:02 +0800718static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
719{
720 char interface_name[IF_NAME_SIZE] = {0};
721 char cmd[MAX_BUF_SIZE]={'\0'};
722 char buf[MAX_CMD_SIZE]={'\0'};
723 UCHAR channel = 0;
724
725 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
726 return RETURN_ERR;
727 /*interface name to channel number*/
728 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
729 _syscmd(cmd, buf, sizeof(buf));
730 channel = atoi(buf);
731 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
732 /*count dev number with the same channel*/
733 snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
734 _syscmd(cmd, buf, sizeof(buf));
735 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
736 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
737 return RETURN_OK;
738}
developer72fb0bb2023-01-11 09:46:29 +0800739
740static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
741{
742 char interface_name[16] = {0};
743 if (multiple_set == TRUE)
744 return RETURN_OK;
745 char cmd[MAX_CMD_SIZE]="", output[32]="";
746 FILE *fp;
747 int i;
748 //NOTE RELOAD should be done in ApplySSIDSettings
749 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
750 return RETURN_ERR;
751 for(i=0; i<item_count; i++, list++)
752 {
developerf6a87542023-05-16 15:47:28 +0800753 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
developer72fb0bb2023-01-11 09:46:29 +0800754 if((fp = popen(cmd, "r"))==NULL)
755 {
756 perror("popen failed");
757 return -1;
758 }
759 if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2))
760 {
761 pclose(fp);
762 perror("fgets failed");
763 return -1;
764 }
765 pclose(fp);
766 }
767 return 0;
768}
769
developer7e4a2a62023-04-06 19:56:03 +0800770static int wifi_quick_reload_ap(int apIndex)
771{
772 char interface_name[IF_NAME_SIZE] = {0};
773 char cmd[MAX_CMD_SIZE] = {0};
774 char buf[MAX_BUF_SIZE] = {0};
775
776 if (multiple_set == TRUE)
777 return RETURN_OK;
778
779 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
780 return RETURN_ERR;
781
782 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
783 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
784 return RETURN_ERR;
785
786 return RETURN_OK;
787}
788
developer72fb0bb2023-01-11 09:46:29 +0800789static int wifi_reloadAp(int apIndex)
790{
791 char interface_name[16] = {0};
792 if (multiple_set == TRUE)
793 return RETURN_OK;
794 char cmd[MAX_CMD_SIZE]="";
795 char buf[MAX_BUF_SIZE]="";
796
797 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
798 return RETURN_ERR;
799 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
800 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
801 return RETURN_ERR;
802
803 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
804 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
805 return RETURN_ERR;
806
807 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
808 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
809 return RETURN_ERR;
810
811 return RETURN_OK;
812}
813
814INT File_Reading(CHAR *file, char *Value)
815{
816 FILE *fp = NULL;
817 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
818 int count = 0;
819
820 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
821 fp = popen(file,"r");
822 if(fp == NULL)
823 return RETURN_ERR;
824
825 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
826 {
827 for(count=0;buf[count]!='\n';count++)
828 copy_buf[count]=buf[count];
829 copy_buf[count]='\0';
830 }
831 strcpy(Value,copy_buf);
832 pclose(fp);
833 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
834
835 return RETURN_OK;
836}
837
838void wifi_RestartHostapd_2G()
839{
840 int Public2GApIndex = 4;
841
842 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
843 wifi_setApEnable(Public2GApIndex, FALSE);
844 wifi_setApEnable(Public2GApIndex, TRUE);
845 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
846}
847
848void wifi_RestartHostapd_5G()
849{
850 int Public5GApIndex = 5;
851
852 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
853 wifi_setApEnable(Public5GApIndex, FALSE);
854 wifi_setApEnable(Public5GApIndex, TRUE);
855 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
856}
857
858void wifi_RestartPrivateWifi_2G()
859{
860 int PrivateApIndex = 0;
861
862 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
863 wifi_setApEnable(PrivateApIndex, FALSE);
864 wifi_setApEnable(PrivateApIndex, TRUE);
865 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
866}
867
868void wifi_RestartPrivateWifi_5G()
869{
870 int Private5GApIndex = 1;
871
872 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
873 wifi_setApEnable(Private5GApIndex, FALSE);
874 wifi_setApEnable(Private5GApIndex, TRUE);
875 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
876}
877
878static int writeBandWidth(int radioIndex,char *bw_value)
879{
880 char buf[MAX_BUF_SIZE];
881 char cmd[MAX_CMD_SIZE];
882
883 snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
884 if(_syscmd(cmd, buf, sizeof(buf)))
885 {
886 snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
887 _syscmd(cmd, buf, sizeof(buf));
888 return RETURN_OK;
889 }
890
891 sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
892 _syscmd(cmd,buf,sizeof(buf));
893 return RETURN_OK;
894}
895
896static int readBandWidth(int radioIndex,char *bw_value)
897{
898 char buf[MAX_BUF_SIZE] = {0};
899 char cmd[MAX_CMD_SIZE] = {0};
900 sprintf(cmd,"grep 'SET_BW%d=' %s | sed 's/^.*=//'",radioIndex,BW_FNAME);
901 _syscmd(cmd,buf,sizeof(buf));
902 if(NULL!=strstr(buf,"20MHz"))
903 {
904 strcpy(bw_value,"20MHz");
905 }
906 else if(NULL!=strstr(buf,"40MHz"))
907 {
908 strcpy(bw_value,"40MHz");
909 }
910 else if(NULL!=strstr(buf,"80MHz"))
911 {
912 strcpy(bw_value,"80MHz");
913 }
914 else
915 {
916 return RETURN_ERR;
917 }
918 return RETURN_OK;
919}
920
921// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
922INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
923{
924 struct params params={'\0'};
925 char config_file[MAX_BUF_SIZE] = {0};
926 char buf[MAX_BUF_SIZE] = {'\0'};
927
928 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
929 // Copy the numeric value
930 if (strlen (beaconRate) >= 5) {
931 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
932 buf[strlen(beaconRate) - 4] = '\0';
933 } else if (strlen(beaconRate) > 0)
934 strcpy(buf, beaconRate);
935 else
936 return RETURN_ERR;
937
938 params.name = "beacon_rate";
939 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
940 if (strncmp(buf, "5.5", 3) == 0) {
941 snprintf(buf, sizeof(buf), "55");
942 params.value = buf;
943 } else {
944 strcat(buf, "0");
945 params.value = buf;
946 }
947
948 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
949 wifi_hostapdWrite(config_file, &params, 1);
950 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
951 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
952
953 return RETURN_OK;
954}
955
956INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
957{
958 char config_file[128] = {'\0'};
959 char temp_output[128] = {'\0'};
960 char buf[128] = {'\0'};
961 char cmd[128] = {'\0'};
962 int rate = 0;
963 int phyId = 0;
964
965 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
966 if (NULL == beaconRate)
967 return RETURN_ERR;
968
969 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
970 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
971 phyId = radio_index_to_phy(radioIndex);
972 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
973 if(strlen(buf) > 0) {
974 if (strncmp(buf, "55", 2) == 0)
975 snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
976 else {
977 rate = strtol(buf, NULL, 10)/10;
978 snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
979 }
980 } else {
981 // config not set, so we would use lowest rate as default
982 sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
983 _syscmd(cmd, buf, sizeof(buf));
984 snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
985 }
986 strncpy(beaconRate, temp_output, sizeof(temp_output));
987 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
988
989 return RETURN_OK;
990}
991
992INT wifi_setLED(INT radioIndex, BOOL enable)
993{
994 return 0;
995}
996INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
997{
998 return RETURN_OK;
999}
1000/**********************************************************************************
1001 *
developer69b61b02023-03-07 17:17:44 +08001002 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001003 *
1004**********************************************************************************/
1005//---------------------------------------------------------------------------------------------------
1006//Wifi system api
1007//Get the wifi hal version in string, eg "2.0.0". WIFI_HAL_MAJOR_VERSION.WIFI_HAL_MINOR_VERSION.WIFI_HAL_MAINTENANCE_VERSION
developer69b61b02023-03-07 17:17:44 +08001008INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001009{
1010 if(!output_string)
1011 return RETURN_ERR;
1012 snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1013
1014 return RETURN_OK;
1015}
1016
1017
1018/* wifi_factoryReset() function */
1019/**
developer69b61b02023-03-07 17:17:44 +08001020* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001021* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1022*
1023* @param None
1024*
1025* @return The status of the operation.
1026* @retval RETURN_OK if successful.
1027* @retval RETURN_ERR if any error is detected
1028*
1029* @execution Synchronous
1030* @sideeffect None
1031*
1032* @note This function must not suspend and must not invoke any blocking system
1033* calls. It should probably just send a message to a driver event handler task.
1034*
1035*/
1036INT wifi_factoryReset()
1037{
1038 char cmd[128];
1039
1040 /*delete running hostapd conf files*/
1041 wifi_dbg_printf("\n[%s]: deleting hostapd conf file %s and %s",__func__,HOSTAPD_CONF_0,HOSTAPD_CONF_1);
1042 sprintf(cmd, "rm -rf %s %s",HOSTAPD_CONF_0,HOSTAPD_CONF_1);
1043 system(cmd);
1044 system("systemctl restart hostapd.service");
1045
1046 return RETURN_OK;
1047}
1048
1049/* wifi_factoryResetRadios() function */
1050/**
1051* @description Restore all radio parameters without touching access point parameters. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1052*
1053* @param None
1054* @return The status of the operation
1055* @retval RETURN_OK if successful
1056* @retval RETURN_ERR if any error is detected
1057*
1058* @execution Synchronous
1059*
1060* @sideeffect None
1061*
1062* @note This function must not suspend and must not invoke any blocking system
1063* calls. It should probably just send a message to a driver event handler task.
1064*
1065*/
1066INT wifi_factoryResetRadios()
1067{
1068 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1069 return RETURN_OK;
1070
1071 return RETURN_ERR;
1072}
1073
1074
1075/* wifi_factoryResetRadio() function */
1076/**
1077* @description Restore selected radio parameters without touching access point parameters
1078*
1079* @param radioIndex - Index of Wi-Fi Radio channel
1080*
1081* @return The status of the operation.
1082* @retval RETURN_OK if successful.
1083* @retval RETURN_ERR if any error is detected
1084*
1085* @execution Synchronous.
1086* @sideeffect None.
1087*
1088* @note This function must not suspend and must not invoke any blocking system
1089* calls. It should probably just send a message to a driver event handler task.
1090*
1091*/
1092INT wifi_factoryResetRadio(int radioIndex) //RDKB
1093{
1094 system("systemctl stop hostapd.service");
1095
1096 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1097 if(radioIndex == 0)
1098 system("rm /nvram/hostapd0.conf");
1099 else if(radioIndex == 1)
1100 system("rm /nvram/hostapd1.conf");
1101 else
1102 return RETURN_ERR;
1103
1104 system("systemctl start hostapd.service");
1105 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1106 return RETURN_OK;
1107}
1108
1109/* wifi_initRadio() function */
1110/**
1111* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001112* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001113* different hardware implementations may have different initilization requirements.
1114* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1115*
1116* @return The status of the operation.
1117* @retval RETURN_OK if successful.
1118* @retval RETURN_ERR if any error is detected
1119*
1120* @execution Synchronous.
1121* @sideeffect None.
1122*
1123* @note This function must not suspend and must not invoke any blocking system
1124* calls. It should probably just send a message to a driver event handler task.
1125*
1126*/
1127INT wifi_initRadio(INT radioIndex)
1128{
1129 //TODO: Initializes the wifi subsystem (for specified radio)
1130 return RETURN_OK;
1131}
1132void macfilter_init()
1133{
1134 char count[4]={'\0'};
1135 char buf[253]={'\0'};
1136 char tmp[19]={'\0'};
1137 int dev_count,block,mac_entry=0;
1138 char res[4]={'\0'};
1139 char acl_file_path[64] = {'\0'};
1140 FILE *fp = NULL;
1141 int index=0;
1142 char iface[10]={'\0'};
1143 char config_file[MAX_BUF_SIZE] = {0};
1144
1145
1146 sprintf(acl_file_path,"/tmp/mac_filter.sh");
1147
1148 fp=fopen(acl_file_path,"w+");
1149 if (fp == NULL) {
1150 fprintf(stderr, "%s: failed to open file %s.\n", __func__, acl_file_path);
developer17038e62023-03-02 14:43:43 +08001151 return;
developer72fb0bb2023-01-11 09:46:29 +08001152 }
1153 sprintf(buf,"#!/bin/sh \n");
1154 fprintf(fp,"%s\n",buf);
1155
1156 system("chmod 0777 /tmp/mac_filter.sh");
1157
1158 for(index=0;index<=1;index++)
1159 {
1160 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index);
1161 wifi_hostapdRead(config_file, "interface", iface, sizeof(iface));
1162 sprintf(buf,"syscfg get %dcountfilter",index);
1163 _syscmd(buf,count,sizeof(count));
1164 mac_entry=atoi(count);
1165
1166 sprintf(buf,"syscfg get %dblockall",index);
1167 _syscmd(buf,res,sizeof(res));
1168 block = atoi(res);
1169
1170 //Allow only those macs mentioned in ACL
1171 if(block==1)
1172 {
1173 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1174 fprintf(fp,"%s\n",buf);
1175 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1176 {
1177 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1178 _syscmd(buf,tmp,sizeof(tmp));
1179 fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp);
1180 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp);
1181 fprintf(fp,"%s\n",buf);
1182 }
1183 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp);
1184 fprintf(fp,"%s\n",buf);
1185 }
1186
1187 //Block all the macs mentioned in ACL
1188 else if(block==2)
1189 {
1190 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1191 fprintf(fp,"%s\n",buf);
1192
1193 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1194 {
1195 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1196 _syscmd(buf,tmp,sizeof(tmp));
1197 fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp);
1198 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp);
1199 fprintf(fp,"%s\n",buf);
1200 }
1201 }
1202 }
1203 fclose(fp);
1204}
1205
developer17038e62023-03-02 14:43:43 +08001206
1207static void
1208wifi_ParseProfile(void)
1209{
1210 int i;
1211 int max_radio_num = 0;
1212 int card_idx;
1213 int band_idx;
1214 int phy_idx = 0;
developer745f0bd2023-03-06 14:32:53 +08001215 int wireless_mode = 0;
developer17038e62023-03-02 14:43:43 +08001216 char buf[MAX_BUF_SIZE] = {0};
1217 char chip_name[12];
1218 char card_profile[MAX_BUF_SIZE] = {0};
1219 char band_profile[MAX_BUF_SIZE] = {0};
1220 FILE* fp;
1221
1222 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1223
1224 memset(main_prefix, 0, sizeof(main_prefix));
1225 memset(ext_prefix, 0, sizeof(ext_prefix));
1226 memset(default_ssid, 0, sizeof(default_ssid));
developer745f0bd2023-03-06 14:32:53 +08001227 for (i = 0; i < MAX_NUM_RADIOS; i++)
1228 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001229
1230 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1231 /* LOG */
1232 return;
1233 }
1234
1235 for (card_idx = 0; card_idx < 3; card_idx++) {
1236 snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1237 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1238 break;
1239 }
1240 snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1241 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1242 break;
1243 }
1244 for (band_idx = 0; band_idx < 3; band_idx++) {
1245 snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1246 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1247 /* LOG */
1248 break;
1249 }
1250
1251 snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1252 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1253 /* LOG */
1254 }
1255
1256 snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1257 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1258 /* LOG */
1259 }
1260
1261 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1262 /* LOG */
1263 }
developer745f0bd2023-03-06 14:32:53 +08001264 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1265 /* LOG */
1266 }
1267
1268 wireless_mode = atoi(buf);
1269 switch (wireless_mode) {
1270 case 22:
1271 case 16:
1272 case 6:
1273 case 4:
1274 case 1:
1275 radio_band[phy_idx] = band_2_4;
1276 break;
1277 case 23:
1278 case 17:
1279 case 14:
1280 case 11:
1281 case 2:
1282 radio_band[phy_idx] = band_5;
1283 break;
1284 case 24:
1285 case 18:
1286 radio_band[phy_idx] = band_6;
1287 break;
1288 }
developer17038e62023-03-02 14:43:43 +08001289 phy_idx++;
1290 }
1291 }
1292
1293 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1294}
1295
1296static void
1297wifi_PrepareDefaultHostapdConfigs(void)
1298{
developer0132ed92023-03-21 13:48:53 +08001299 int radio_idx;
1300 int bss_idx;
1301 int ap_idx;
1302 int band_idx;
1303 char buf[MAX_BUF_SIZE] = {0};
1304 char config_file[MAX_BUF_SIZE] = {0};
1305 char ssid[MAX_BUF_SIZE] = {0};
1306 char interface[32] = {0};
1307 char ret_buf[MAX_BUF_SIZE] = {0};
1308 char psk_file[64] = {0};
1309 struct params params[3];
developer17038e62023-03-02 14:43:43 +08001310
developer0132ed92023-03-21 13:48:53 +08001311 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1312 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1313 band_idx = radio_index_to_band(radio_idx);
1314 if (band_idx < 0) {
1315 break;
1316 }
1317 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
1318 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
1319
1320 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1321 snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
1322 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001323
developer0132ed92023-03-21 13:48:53 +08001324 if (bss_idx == 0) {
1325 snprintf(ssid, sizeof(ssid), "%s", default_ssid[radio_idx]);
1326 snprintf(interface, sizeof(interface), "%s", main_prefix[radio_idx]);
1327 } else {
1328 snprintf(ssid, sizeof(ssid), "%s_%d", default_ssid[radio_idx], bss_idx);
1329 snprintf(interface, sizeof(interface), "%s%d", ext_prefix[radio_idx], bss_idx);
1330 }
developer17038e62023-03-02 14:43:43 +08001331
developer0132ed92023-03-21 13:48:53 +08001332 /* fix wpa_psk_file path */
1333 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
developer17038e62023-03-02 14:43:43 +08001334
developer0132ed92023-03-21 13:48:53 +08001335 params[0].name = "ssid";
1336 params[0].value = ssid;
1337 params[1].name = "interface";
1338 params[1].value = interface;
1339 params[2].name = "wpa_psk_file";
1340 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001341
developer0132ed92023-03-21 13:48:53 +08001342 wifi_hostapdWrite(config_file, params, 3);
1343 }
1344 }
1345 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001346}
1347
1348static void
1349wifiBringUpInterfacesForRadio(int radio_idx)
1350{
developer0132ed92023-03-21 13:48:53 +08001351 int bss_idx;
1352 int ap_idx;
1353 int band_idx;
1354 char cmd[MAX_CMD_SIZE] = {0};
1355 char config_file[MAX_BUF_SIZE] = {0};
1356 char ret_buf[MAX_BUF_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08001357 char inf_name[IF_NAME_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001358
1359 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer8a3bbbf2023-03-15 17:47:23 +08001360
developered997d32023-04-18 22:45:39 +08001361 bss_idx = 0;
1362 /*TBD: we need refine setup flow and mbss flow*/
1363// for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer0132ed92023-03-21 13:48:53 +08001364 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
1365
1366 snprintf(cmd, sizeof(cmd), "touch %s%d.psk", PSK_FILE, ap_idx);
1367 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1368
1369 memset(cmd, 0, MAX_CMD_SIZE);
1370 memset(ret_buf, 0, MAX_BUF_SIZE);
developer17038e62023-03-02 14:43:43 +08001371
developer0132ed92023-03-21 13:48:53 +08001372 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1373 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radio_idx, config_file);
1374 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer8a3bbbf2023-03-15 17:47:23 +08001375
1376 wifi_GetInterfaceName(ap_idx, inf_name);
1377
1378 memset(cmd, 0, MAX_CMD_SIZE);
1379 memset(ret_buf, 0, MAX_BUF_SIZE);
1380
1381 /* fix vap-status file */
1382 snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=1/\" %s", inf_name, inf_name, VAP_STATUS_FILE);
1383 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developered997d32023-04-18 22:45:39 +08001384// }
1385
1386 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001387}
1388
1389static void
1390wifi_BringUpInterfaces(void)
1391{
1392 int radio_idx;
1393 int bss_idx;
1394 int ap_idx;
1395 int band_idx;
1396 char cmd[MAX_BUF_SIZE] = {0};
1397 char config_file[MAX_BUF_SIZE] = {0};
1398 char ret_buf[MAX_BUF_SIZE]={'\0'};
1399
1400 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1401 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1402 band_idx = radio_index_to_band(radio_idx);
1403 if (band_idx < 0) {
1404 break;
1405 }
1406 wifiBringUpInterfacesForRadio(radio_idx);
1407 }
1408 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1409}
1410
1411static void
1412wifi_BringDownInterfacesForRadio(int radio_idx)
1413{
1414 int bss_idx;
1415 int ap_idx;
1416 int band_idx;
1417 char cmd[MAX_BUF_SIZE] = {0};
1418 char config_file[MAX_BUF_SIZE] = {0};
1419 char ret_buf[MAX_BUF_SIZE]={'\0'};
1420
1421 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001422
developer8a3bbbf2023-03-15 17:47:23 +08001423 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1424 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1425
1426
developer17038e62023-03-02 14:43:43 +08001427 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1428}
1429
1430
1431static void
1432wifi_BringDownInterfaces(void)
1433{
1434 int radio_idx;
1435 int bss_idx;
1436 int ap_idx;
1437 int band_idx;
1438 char cmd[MAX_BUF_SIZE] = {0};
1439 char config_file[MAX_BUF_SIZE] = {0};
1440 char ret_buf[MAX_BUF_SIZE]={'\0'};
1441
1442 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1443 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1444 band_idx = radio_index_to_band(radio_idx);
1445 if (band_idx < 0) {
1446 break;
1447 }
1448 wifi_BringDownInterfacesForRadio(radio_idx);
1449 }
1450 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1451}
1452
developer8a3bbbf2023-03-15 17:47:23 +08001453static void wifi_vap_status_reset()
1454{
1455 char cmd[MAX_CMD_SIZE] = {0};
1456 char ret_buf[MAX_BUF_SIZE] = {0};
1457 char radio_idx = 0;
1458 char bss_idx = 0;
developer8666b312023-03-24 14:05:31 +08001459
developer8a3bbbf2023-03-15 17:47:23 +08001460 if (access(VAP_STATUS_FILE, F_OK) != 0) {
1461 snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
1462 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1463 } else {
1464 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
1465 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1466 }
1467
1468 memset(cmd, 0, MAX_CMD_SIZE);
1469 memset(ret_buf, 0, MAX_BUF_SIZE);
1470
1471 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
1472 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
1473 snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
1474 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1475 }
1476
1477}
developer17038e62023-03-02 14:43:43 +08001478
developer72fb0bb2023-01-11 09:46:29 +08001479// Initializes the wifi subsystem (all radios)
1480INT wifi_init() //RDKB
1481{
developer96b38512023-02-22 11:17:45 +08001482 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1483 //Not intitializing macfilter for Turris-Omnia Platform for now
1484 //macfilter_init();
developer17038e62023-03-02 14:43:43 +08001485 wifi_ParseProfile();
1486 wifi_PrepareDefaultHostapdConfigs();
1487 //system("/usr/sbin/iw reg set US");
1488 system("systemctl start hostapd.service");
1489 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08001490
1491 wifi_vap_status_reset();
1492
developer17038e62023-03-02 14:43:43 +08001493 wifi_BringUpInterfaces();
developer96b38512023-02-22 11:17:45 +08001494
developer96b38512023-02-22 11:17:45 +08001495
1496 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001497
1498 return RETURN_OK;
1499}
1500
1501/* wifi_reset() function */
1502/**
1503* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08001504* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08001505* different hardware implementations may have different requirements.
1506* Parameters : None
1507*
1508* @return The status of the operation.
1509* @retval RETURN_OK if successful.
1510* @retval RETURN_ERR if any error is detected
1511*
1512* @execution Synchronous.
1513* @sideeffect None.
1514*
1515* @note This function must not suspend and must not invoke any blocking system
1516* calls. It should probably just send a message to a driver event handler task.
1517*
1518*/
1519INT wifi_reset()
1520{
developer17038e62023-03-02 14:43:43 +08001521
1522 wifi_BringDownInterfaces();
1523 sleep(2);
1524
developer96b38512023-02-22 11:17:45 +08001525 //TODO: resets the wifi subsystem, deletes all APs
1526 system("systemctl stop hostapd.service");
1527 sleep(2);
developer17038e62023-03-02 14:43:43 +08001528
developer96b38512023-02-22 11:17:45 +08001529 system("systemctl start hostapd.service");
1530 sleep(5);
developer17038e62023-03-02 14:43:43 +08001531
1532 wifi_PrepareDefaultHostapdConfigs();
1533 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08001534
1535 wifi_vap_status_reset();
1536
developer17038e62023-03-02 14:43:43 +08001537 wifi_BringUpInterfaces();
1538
developer72fb0bb2023-01-11 09:46:29 +08001539 return RETURN_OK;
1540}
1541
1542/* wifi_down() function */
1543/**
1544* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08001545* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08001546* different hardware implementations may have different requirements.
1547*
1548* @param None
1549*
1550* @return The status of the operation
1551* @retval RETURN_OK if successful
1552* @retval RETURN_ERR if any error is detected
1553*
1554* @execution Synchronous
1555* @sideeffect None
1556*
1557* @note This function must not suspend and must not invoke any blocking system
1558* calls. It should probably just send a message to a driver event handler task.
1559*
1560*/
1561INT wifi_down()
1562{
developer96b38512023-02-22 11:17:45 +08001563 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
developer17038e62023-03-02 14:43:43 +08001564 wifi_BringDownInterfaces();
1565 sleep(2);
1566
developer96b38512023-02-22 11:17:45 +08001567 system("systemctl stop hostapd.service");
1568 sleep(2);
developer72fb0bb2023-01-11 09:46:29 +08001569 return RETURN_OK;
1570}
1571
1572
1573/* wifi_createInitialConfigFiles() function */
1574/**
1575* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08001576* and content of these files are implementation dependent. This function call is
1577* used to trigger this task if necessary. Some implementations may not need this
1578* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08001579* do nothing and return RETURN_OK.
1580*
1581* @param None
1582*
1583* @return The status of the operation
1584* @retval RETURN_OK if successful
1585* @retval RETURN_ERR if any error is detected
1586*
1587* @execution Synchronous
1588* @sideeffect None
1589*
1590* @note This function must not suspend and must not invoke any blocking system
1591* calls. It should probably just send a message to a driver event handler task.
1592*
1593*/
1594INT wifi_createInitialConfigFiles()
1595{
1596 //TODO: creates initial implementation dependent configuration files that are later used for variable storage. Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
1597 return RETURN_OK;
1598}
1599
developer7e4a2a62023-04-06 19:56:03 +08001600/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08001601INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
1602{
developer7e4a2a62023-04-06 19:56:03 +08001603 char interface_name[IF_NAME_SIZE] = {0};
1604 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
developer72fb0bb2023-01-11 09:46:29 +08001605
developer7e4a2a62023-04-06 19:56:03 +08001606 if (!output_string || (radioIndex >= MAX_NUM_RADIOS)) {
1607 printf("%s: input para error!!!\n", __func__);
1608 return RETURN_ERR;
1609 }
developer72fb0bb2023-01-11 09:46:29 +08001610
developer7e4a2a62023-04-06 19:56:03 +08001611 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
1612 printf("%s: get inf_name error!!!\n", __func__);
1613 return RETURN_ERR;
1614 }
1615
1616 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i %s status driver | grep country | cut -d '=' -f2 | tr -d '\\n'",
1617 interface_name);
1618 _syscmd(cmd, buf, sizeof(buf));
1619
1620 if(strlen(buf))
1621 snprintf(output_string, 64, "%s", buf);
1622 else
1623 return RETURN_ERR;
1624
1625 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001626}
1627
1628INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
1629{
developer7e4a2a62023-04-06 19:56:03 +08001630 /*Set wifi config. Wait for wifi reset to apply*/
1631 char str[MAX_BUF_SIZE] = {0};
1632 char cmd[MAX_CMD_SIZE] = {0};
1633 struct params params;
1634 char config_file[MAX_BUF_SIZE] = {0};
1635 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08001636
developer7e4a2a62023-04-06 19:56:03 +08001637 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001638
developer7e4a2a62023-04-06 19:56:03 +08001639 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
1640 printf("%s: input para error!!!\n", __func__);
1641 return RETURN_ERR;
1642 }
developer72fb0bb2023-01-11 09:46:29 +08001643
developer7e4a2a62023-04-06 19:56:03 +08001644 if (!strlen(CountryCode))
1645 strncpy(CountryCode, "US", sizeof("US")); /*default set the code to US*/
developer72fb0bb2023-01-11 09:46:29 +08001646
developer7e4a2a62023-04-06 19:56:03 +08001647 params.name = "country_code";
1648 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08001649
developer7e4a2a62023-04-06 19:56:03 +08001650 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1651 ret = wifi_hostapdWrite(config_file, &params, 1);
1652
1653 if (ret) {
1654 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
1655 __func__, ret);
1656 }
1657
1658 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1659
1660 if (ret) {
1661 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
1662 __func__, ret);
1663 }
1664
1665 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1666
1667 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001668}
1669
1670INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
1671{
1672 char interface_name[16] = {0};
1673 char channel_util_file[64] = {0};
1674 char cmd[128] = {0};
1675 char buf[128] = {0};
1676 char line[128] = {0};
1677 char *param = NULL, *value = NULL;
1678 int read = 0;
1679 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
1680 unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
1681 size_t len = 0;
1682 FILE *f = NULL;
1683
1684 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1685
1686 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
1687 return RETURN_ERR;
1688 snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
1689 _syscmd(cmd, buf, sizeof(buf));
1690 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
1691
1692 memset(cmd, 0, sizeof(cmd));
1693 memset(buf, 0, sizeof(buf));
1694 snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
1695 if ((f = popen(cmd, "r")) == NULL) {
1696 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
1697 return RETURN_ERR;
1698 }
1699
1700 read = getline(&line, &len, f);
1701 while (read != -1) {
1702 param = strtok(line, ":\t");
1703 value = strtok(NULL, " ");
1704 if(strstr(param, "frequency") != NULL) {
1705 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
1706 }
1707 if(strstr(param, "noise") != NULL) {
1708 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
1709 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
1710 }
1711 if(strstr(param, "channel active time") != NULL) {
1712 ActiveTime = strtol(value, NULL, 10);
1713 }
1714 if(strstr(param, "channel busy time") != NULL) {
1715 BusyTime = strtol(value, NULL, 10);
1716 }
1717 if(strstr(param, "channel transmit time") != NULL) {
1718 TransmitTime = strtol(value, NULL, 10);
1719 }
1720 read = getline(&line, &len, f);
1721 }
1722 pclose(f);
1723
1724 // The file should store the last active, busy and transmit time
1725 snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
1726 f = fopen(channel_util_file, "r");
1727 if (f != NULL) {
1728 read = getline(&line, &len, f);
1729 preActiveTime = strtol(line, NULL, 10);
1730 read = getline(&line, &len, f);
1731 preBusyTime = strtol(line, NULL, 10);
1732 read = getline(&line, &len, f);
1733 preTransmitTime = strtol(line, NULL, 10);
1734 fclose(f);
1735 }
1736
1737 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
1738 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
1739
1740 f = fopen(channel_util_file, "w");
1741 if (f != NULL) {
1742 fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime);
1743 fclose(f);
1744 }
1745 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1746 return RETURN_OK;
1747}
1748
1749/**********************************************************************************
1750 *
1751 * Wifi radio level function prototypes
1752 *
1753**********************************************************************************/
1754
1755//Get the total number of radios in this wifi subsystem
1756INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
1757{
1758 if (NULL == output)
1759 return RETURN_ERR;
1760 *output = MAX_NUM_RADIOS;
1761
1762 return RETURN_OK;
1763}
1764
developer69b61b02023-03-07 17:17:44 +08001765//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08001766INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
1767{
1768 if (NULL == output)
1769 return RETURN_ERR;
1770 *output = MAX_APS;
1771
1772 return RETURN_OK;
1773}
1774
1775//Get the Radio enable config parameter
1776INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
1777{
1778 char interface_name[16] = {0};
1779 char buf[128] = {0}, cmd[128] = {0};
1780
1781 if (NULL == output_bool)
1782 return RETURN_ERR;
1783
1784 *output_bool = FALSE;
1785 if (radioIndex >= MAX_NUM_RADIOS)// Target has two wifi radios
1786 return RETURN_ERR;
1787
1788 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
1789 return RETURN_ERR;
1790 sprintf(cmd, "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
1791 _syscmd(cmd, buf, sizeof(buf));
1792
1793 if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 || strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0)
1794 *output_bool = TRUE;
1795 return RETURN_OK;
1796}
1797
developere82c0ca2023-05-10 16:25:35 +08001798typedef long time_t;
1799static time_t radio_up_time[MAX_NUM_RADIOS];
1800
developer72fb0bb2023-01-11 09:46:29 +08001801INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
1802{
1803 char interface_name[16] = {0};
1804 char cmd[MAX_CMD_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08001805 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08001806 int apIndex, ret;
developer69b61b02023-03-07 17:17:44 +08001807 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +08001808 int phyId = 0;
1809
1810 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1811
1812 phyId = radio_index_to_phy(radioIndex);
1813
1814 wifi_getMaxRadioNumber(&max_radio_num);
1815
developer8a3bbbf2023-03-15 17:47:23 +08001816 if(enable == FALSE) {
developere82c0ca2023-05-10 16:25:35 +08001817 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radioIndex]);
developer8a3bbbf2023-03-15 17:47:23 +08001818 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08001819 if(strncmp(buf, "OK", 2))
1820 fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08001821 } else {
developere82c0ca2023-05-10 16:25:35 +08001822 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developer72fb0bb2023-01-11 09:46:29 +08001823 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1824 return RETURN_ERR;
1825
developer8a3bbbf2023-03-15 17:47:23 +08001826 memset(cmd, 0, MAX_CMD_SIZE);
1827 memset(buf, 0, MAX_BUF_SIZE);
1828
developer72fb0bb2023-01-11 09:46:29 +08001829 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
1830 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08001831
1832 if(*buf == '1') {
1833
1834 memset(cmd, 0, MAX_CMD_SIZE);
1835 memset(buf, 0, MAX_BUF_SIZE);
1836
developer72fb0bb2023-01-11 09:46:29 +08001837 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
1838 phyId, apIndex);
1839 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08001840
developer72fb0bb2023-01-11 09:46:29 +08001841 }
1842 }
developere82c0ca2023-05-10 16:25:35 +08001843 time(&radio_up_time[radioIndex]);
developer72fb0bb2023-01-11 09:46:29 +08001844 }
1845
1846 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1847 return RETURN_OK;
1848}
1849
1850//Get the Radio enable status
1851INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
1852{
1853 if (NULL == output_bool)
1854 return RETURN_ERR;
1855
1856 return wifi_getRadioEnable(radioIndex, output_bool);
1857}
1858
1859//Get the Radio Interface name from platform, eg "wlan0"
1860INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
1861{
1862 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
1863 return RETURN_ERR;
1864 return wifi_GetInterfaceName(radioIndex, output_string);
1865}
1866
1867//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
1868//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
1869INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
1870{
1871 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
1872 // For max bit rate, we should always choose the best MCS
1873 char mode[64] = {0};
1874 char channel_bandwidth_str[64] = {0};
1875 char *tmp = NULL;
1876 UINT mode_map = 0;
1877 UINT num_subcarrier = 0;
1878 UINT code_bits = 0;
1879 float code_rate = 0; // use max code rate
1880 int NSS = 0;
1881 UINT Symbol_duration = 0;
developer69b61b02023-03-07 17:17:44 +08001882 UINT GI_duration = 0;
developer72fb0bb2023-01-11 09:46:29 +08001883 wifi_band band = band_invalid;
1884 wifi_guard_interval_t gi = wifi_guard_interval_auto;
1885 BOOL enable = FALSE;
1886 float bit_rate = 0;
developera1255e42023-05-13 17:45:02 +08001887 int ant_bitmap = 0;
developer72fb0bb2023-01-11 09:46:29 +08001888
1889 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1890 if (NULL == output_string)
1891 return RETURN_ERR;
1892
1893 wifi_getRadioEnable(radioIndex, &enable);
1894 if (enable == FALSE) {
1895 snprintf(output_string, 64, "0 Mb/s");
1896 return RETURN_OK;
1897 }
1898
1899 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
1900 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
1901 return RETURN_ERR;
1902 }
1903
1904 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
1905 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
1906 return RETURN_ERR;
1907 }
1908
1909 if (gi == wifi_guard_interval_3200)
1910 GI_duration = 32;
1911 else if (gi == wifi_guard_interval_1600)
1912 GI_duration = 16;
1913 else if (gi == wifi_guard_interval_800)
1914 GI_duration = 8;
1915 else // auto, 400
1916 GI_duration = 4;
1917
1918 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
1919 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
1920 return RETURN_ERR;
1921 }
1922
1923 if (strstr(channel_bandwidth_str, "80+80") != NULL)
1924 strcpy(channel_bandwidth_str, "160");
1925
1926 if (mode_map & WIFI_MODE_AX) {
1927 if (strstr(channel_bandwidth_str, "160") != NULL)
1928 num_subcarrier = 1960;
1929 else if (strstr(channel_bandwidth_str, "80") != NULL)
1930 num_subcarrier = 980;
1931 else if (strstr(channel_bandwidth_str, "40") != NULL)
1932 num_subcarrier = 468;
1933 else if (strstr(channel_bandwidth_str, "20") != NULL)
1934 num_subcarrier = 234;
1935 code_bits = 10;
1936 code_rate = (float)5/6;
1937 Symbol_duration = 128;
developera1255e42023-05-13 17:45:02 +08001938 GI_duration = 8;/*HE no GI 400ns*/
developer72fb0bb2023-01-11 09:46:29 +08001939 } else if (mode_map & WIFI_MODE_AC) {
1940 if (strstr(channel_bandwidth_str, "160") != NULL)
1941 num_subcarrier = 468;
1942 else if (strstr(channel_bandwidth_str, "80") != NULL)
1943 num_subcarrier = 234;
1944 else if (strstr(channel_bandwidth_str, "40") != NULL)
1945 num_subcarrier = 108;
1946 else if (strstr(channel_bandwidth_str, "20") != NULL)
1947 num_subcarrier = 52;
1948 code_bits = 8;
1949 code_rate = (float)5/6;
1950 Symbol_duration = 32;
1951 } else if (mode_map & WIFI_MODE_N) {
1952 if (strstr(channel_bandwidth_str, "160") != NULL)
1953 num_subcarrier = 468;
1954 else if (strstr(channel_bandwidth_str, "80") != NULL)
1955 num_subcarrier = 234;
1956 else if (strstr(channel_bandwidth_str, "40") != NULL)
1957 num_subcarrier = 108;
1958 else if (strstr(channel_bandwidth_str, "20") != NULL)
1959 num_subcarrier = 52;
1960 code_bits = 6;
1961 code_rate = (float)3/4;
1962 Symbol_duration = 32;
1963 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
1964 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
1965 snprintf(output_string, 64, "65 Mb/s");
1966 return RETURN_OK;
1967 } else {
1968 snprintf(output_string, 64, "0 Mb/s");
1969 return RETURN_OK;
1970 }
1971
1972 // Spatial streams
developera1255e42023-05-13 17:45:02 +08001973 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +08001974 fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
1975 return RETURN_ERR;
1976 }
developera1255e42023-05-13 17:45:02 +08001977 for (; ant_bitmap > 0; ant_bitmap >>= 1)
1978 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08001979
1980 // multiple 10 is to align duration unit (0.1 us)
1981 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
1982 snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
developera1255e42023-05-13 17:45:02 +08001983 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
1984 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
developer72fb0bb2023-01-11 09:46:29 +08001985 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1986
1987 return RETURN_OK;
1988}
1989#if 0
1990INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
1991{
1992 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1993 char cmd[64];
1994 char buf[1024];
1995 int apIndex;
1996
developer69b61b02023-03-07 17:17:44 +08001997 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08001998 return RETURN_ERR;
1999
2000 apIndex=(radioIndex==0)?0:1;
2001
2002 snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name);
2003 _syscmd(cmd,buf, sizeof(buf));
2004
2005 snprintf(output_string, 64, "%s", buf);
2006 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2007 return RETURN_OK;
2008}
2009#endif
2010
2011
2012//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2013//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
2014INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2015{
2016 wifi_band band = band_invalid;
2017
2018 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2019 if (NULL == output_string)
2020 return RETURN_ERR;
2021
2022 band = wifi_index_to_band(radioIndex);
2023
2024 memset(output_string, 0, 10);
2025 if (band == band_2_4)
2026 strcpy(output_string, "2.4GHz");
2027 else if (band == band_5)
2028 strcpy(output_string, "5GHz");
2029 else if (band == band_6)
2030 strcpy(output_string, "6GHz");
2031 else
2032 return RETURN_ERR;
2033 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2034
2035 return RETURN_OK;
2036#if 0
2037 char buf[MAX_BUF_SIZE]={'\0'};
2038 char str[MAX_BUF_SIZE]={'\0'};
2039 char cmd[MAX_CMD_SIZE]={'\0'};
2040 char *ch=NULL;
2041 char *ch2=NULL;
2042
2043 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2044 if (NULL == output_string)
2045 return RETURN_ERR;
2046
2047
2048 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2049
2050 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2051 {
2052 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2053 return RETURN_ERR;
2054 }
2055 ch=strchr(buf,'\n');
2056 *ch='\0';
2057 ch=strchr(buf,'=');
2058 if(ch==NULL)
2059 return RETURN_ERR;
2060
2061
2062 ch++;
2063
2064 /* prepend 0 for channel with single digit. for ex, 6 would be 06 */
2065 strcpy(buf,"0");
2066 if(strlen(ch) == 1)
2067 ch=strcat(buf,ch);
2068
2069
2070 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2071
2072 if(_syscmd(cmd,str,64) == RETURN_ERR)
2073 {
2074 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2075 return RETURN_ERR;
2076 }
2077
2078
2079 ch2=strchr(str,'\n');
2080 //replace \n with \0
2081 *ch2='\0';
2082 ch2=strchr(str,'=');
2083 if(ch2==NULL)
2084 {
2085 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2086 return RETURN_ERR;
2087 }
2088 else
2089 wifi_dbg_printf("%s",ch2+1);
2090
2091
2092 ch2++;
2093
2094
2095 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch);
2096
2097 memset(buf,'\0',sizeof(buf));
2098 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2099 {
2100 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2101 return RETURN_ERR;
2102 }
2103 if (strstr(buf,"2.4") != NULL )
2104 strcpy(output_string,"2.4GHz");
2105 else if(strstr(buf,"5.") != NULL )
2106 strcpy(output_string,"5GHz");
2107 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2108
2109 return RETURN_OK;
2110#endif
2111}
2112
2113//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2114//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
2115INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2116{
2117 wifi_band band = band_invalid;
2118 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2119 if (NULL == output_string)
2120 return RETURN_ERR;
2121 band = wifi_index_to_band(radioIndex);
2122
developer69b61b02023-03-07 17:17:44 +08002123 if (band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08002124 snprintf(output_string, 64, "2.4GHz");
2125 else if (band == band_5)
developer69b61b02023-03-07 17:17:44 +08002126 snprintf(output_string, 64, "5GHz");
developer72fb0bb2023-01-11 09:46:29 +08002127 else if (band == band_6)
2128 snprintf(output_string, 64, "6GHz");
2129
2130 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2131
2132 return RETURN_OK;
2133#if 0
2134 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2135 char buf[MAX_BUF_SIZE]={'\0'};
2136 char str[MAX_BUF_SIZE]={'\0'};
2137 char cmd[MAX_CMD_SIZE]={'\0'};
2138 char *ch=NULL;
2139 char *ch2=NULL;
2140 char ch1[5]="0";
2141
2142 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2143
2144 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2145 {
2146 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2147 return RETURN_ERR;
2148 }
2149
2150 ch=strchr(buf,'\n');
2151 *ch='\0';
2152 ch=strchr(buf,'=');
2153 if(ch==NULL)
2154 return RETURN_ERR;
2155 ch++;
2156
2157 if(strlen(ch)==1)
2158 {
2159 strcat(ch1,ch);
2160
2161 }
2162 else
2163 {
2164 strcpy(ch1,ch);
2165 }
2166
2167
2168
2169 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2170 if(_syscmd(cmd,str,64) == RETURN_ERR)
2171 {
2172 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2173 return RETURN_ERR;
2174 }
2175
2176
2177 ch2=strchr(str,'\n');
2178 //replace \n with \0
2179 *ch2='\0';
2180 ch2=strchr(str,'=');
2181 if(ch2==NULL)
2182 {
2183 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2184 return RETURN_ERR;
2185 }
2186 else
2187 wifi_dbg_printf("%s",ch2+1);
2188 ch2++;
2189
2190
2191 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1);
2192 memset(buf,'\0',sizeof(buf));
2193 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2194 {
2195 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2196 return RETURN_ERR;
2197 }
2198
2199
2200 if(strstr(buf,"2.4")!=NULL)
2201 {
2202 strcpy(output_string,"2.4GHz");
2203 }
2204 if(strstr(buf,"5.")!=NULL)
2205 {
2206 strcpy(output_string,"5GHz");
2207 }
2208 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2209 return RETURN_OK;
2210#endif
2211}
2212
2213//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2214//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
2215INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2216{
2217 char cmd[128]={0};
2218 char buf[128]={0};
2219 char temp_output[128] = {0};
2220 wifi_band band;
2221 int phyId = 0;
2222
2223 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08002224 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002225 return RETURN_ERR;
2226
2227 band = wifi_index_to_band(radioIndex);
2228 if (band == band_2_4) {
2229 strcat(temp_output, "b,g,");
2230 } else if (band == band_5) {
2231 strcat(temp_output, "a,");
2232 }
2233 phyId = radio_index_to_phy(radioIndex);
2234 // ht capabilities
2235 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep '[^PHY|MAC|VHT].Capabilities' | head -n 1 | cut -d ':' -f2 | sed 's/^.//' | tr -d '\\n'", phyId);
2236 _syscmd(cmd, buf, sizeof(buf));
2237 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
2238 strcat(temp_output, "n,");
2239 }
2240
2241 // vht capabilities
2242 if (band == band_5) {
2243 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2244 _syscmd(cmd, buf, sizeof(buf));
2245 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
2246 strcat(temp_output, "ac,");
2247 }
2248 }
2249
2250 // he capabilities
2251 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'HE MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
2252 _syscmd(cmd, buf, sizeof(buf));
2253 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2254 strcat(temp_output, "ax,");
2255 }
2256
developere82c0ca2023-05-10 16:25:35 +08002257 // eht capabilities
2258 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'EHT MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
2259 _syscmd(cmd, buf, sizeof(buf));
2260 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2261 strcat(temp_output, "be,");
2262 }
2263
developer72fb0bb2023-01-11 09:46:29 +08002264 // Remove the last comma
2265 if (strlen(temp_output) != 0)
2266 temp_output[strlen(temp_output)-1] = '\0';
2267 strncpy(output_string, temp_output, strlen(temp_output));
2268 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2269 return RETURN_OK;
2270}
2271
2272//Get the radio operating mode, and pure mode flag. eg: "ac"
2273//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
2274INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
2275{
2276 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2277 if (NULL == output_string)
2278 return RETURN_ERR;
2279
2280 if (radioIndex == 0) {
2281 snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
2282 *gOnly = FALSE;
2283 *nOnly = TRUE;
2284 *acOnly = FALSE;
2285 } else {
2286 snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
2287 *gOnly = FALSE;
2288 *nOnly = FALSE;
2289 *acOnly = FALSE;
2290 }
2291 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2292
2293 return RETURN_OK;
2294#if 0
2295 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2296 char buf[64] = {0};
2297 char config_file[MAX_BUF_SIZE] = {0};
2298
developer69b61b02023-03-07 17:17:44 +08002299 if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly))
developer72fb0bb2023-01-11 09:46:29 +08002300 return RETURN_ERR;
2301
2302 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2303 wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf));
2304
2305 wifi_dbg_printf("\nhw_mode=%s\n",buf);
developer69b61b02023-03-07 17:17:44 +08002306 if (strlen(buf) == 0)
developer72fb0bb2023-01-11 09:46:29 +08002307 {
2308 wifi_dbg_printf("\nwifi_hostapdRead returned none\n");
2309 return RETURN_ERR;
2310 }
2311 if(strcmp(buf,"g")==0)
2312 {
2313 wifi_dbg_printf("\nG\n");
2314 *gOnly=TRUE;
2315 *nOnly=FALSE;
2316 *acOnly=FALSE;
2317 }
2318 else if(strcmp(buf,"n")==0)
2319 {
2320 wifi_dbg_printf("\nN\n");
2321 *gOnly=FALSE;
2322 *nOnly=TRUE;
2323 *acOnly=FALSE;
2324 }
2325 else if(strcmp(buf,"ac")==0)
2326 {
2327 wifi_dbg_printf("\nac\n");
2328 *gOnly=FALSE;
2329 *nOnly=FALSE;
2330 *acOnly=TRUE;
2331 }
2332 /* hostapd-5G.conf has "a" as hw_mode */
2333 else if(strcmp(buf,"a")==0)
2334 {
2335 wifi_dbg_printf("\na\n");
2336 *gOnly=FALSE;
2337 *nOnly=FALSE;
2338 *acOnly=FALSE;
2339 }
2340 else
2341 wifi_dbg_printf("\nInvalid Mode %s\n", buf);
2342
2343 //for a,n mode
2344 if(radioIndex == 1)
2345 {
2346 wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf));
2347 if(strcmp(buf,"1")==0)
2348 {
2349 strncpy(output_string, "n", 1);
2350 *nOnly=FALSE;
2351 }
2352 }
2353
2354 wifi_dbg_printf("\nReturning from getRadioStandard\n");
2355 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2356 return RETURN_OK;
2357#endif
2358}
2359
developer0f10c772023-05-16 21:43:39 +08002360enum WIFI_MODE {
2361 WMODE_INVALID = 0,
2362 WMODE_A = 1 << 0,
2363 WMODE_B = 1 << 1,
2364 WMODE_G = 1 << 2,
2365 WMODE_GN = 1 << 3,
2366 WMODE_AN = 1 << 4,
2367 WMODE_AC = 1 << 5,
2368 WMODE_AX_24G = 1 << 6,
2369 WMODE_AX_5G = 1 << 7,
2370 WMODE_AX_6G = 1 << 8,
2371 WMODE_BE_24G = 1 << 9,
2372 WMODE_BE_5G = 1 << 10,
2373 WMODE_BE_6G = 1 << 11,
2374 /*
2375 * total types of supported wireless mode,
2376 * add this value once yow add new type
2377 */
2378 WMODE_COMP = 12,
2379};
2380
2381#define RADIO_MODE_LEN 32
developer72fb0bb2023-01-11 09:46:29 +08002382INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
2383{
developer0f10c772023-05-16 21:43:39 +08002384 char cmd[MAX_CMD_SIZE] = {0};
2385 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002386 wifi_band band;
developer0f10c772023-05-16 21:43:39 +08002387 unsigned int phymode;
2388 unsigned char radio_mode_tem_len;
2389 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002390
2391 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2392 if(NULL == output_string || NULL == pureMode)
2393 return RETURN_ERR;
2394
developer0f10c772023-05-16 21:43:39 +08002395 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2396 return RETURN_ERR;
2397
2398 snprintf(cmd, sizeof(cmd), "mwctl %s dump radio_info | grep 'phymode' | cut -d ' ' -f2", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08002399 _syscmd(cmd, buf, sizeof(buf));
2400
developer0f10c772023-05-16 21:43:39 +08002401 phymode = strtoul(buf, NULL, 10);
2402 band = wifi_index_to_band(radioIndex);
2403
2404 // puremode is a bit map
developer72fb0bb2023-01-11 09:46:29 +08002405 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08002406 memset(output_string, 0, RADIO_MODE_LEN);
2407
2408 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2409
2410 switch (band) {
2411 case band_2_4:
2412 if (phymode & WMODE_B) {
2413 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
2414 *pureMode |= WIFI_MODE_B;
2415 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2416 }
2417 if (phymode & WMODE_G) {
2418 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
2419 *pureMode |= WIFI_MODE_G;
2420 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2421 }
2422 if (phymode & WMODE_GN) {
2423 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2424 *pureMode |= WIFI_MODE_N;
2425 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2426 }
2427 if (phymode & WMODE_AX_24G) {
2428 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2429 *pureMode |= WIFI_MODE_AX;
2430 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2431 }
2432 if (phymode & WMODE_BE_24G) {
2433 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2434 *pureMode |= WIFI_MODE_BE;
2435 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2436 }
2437 break;
2438 case band_5:
2439 if (phymode & WMODE_A) {
2440 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
2441 *pureMode |= WIFI_MODE_A;
2442 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2443 }
2444 if (phymode & WMODE_AN) {
2445 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2446 *pureMode |= WIFI_MODE_N;
2447 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2448 }
2449 if (phymode & WMODE_AC) {
2450 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
2451 *pureMode |= WIFI_MODE_AC;
2452 }
2453 if (phymode & WMODE_AX_5G) {
2454 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2455 *pureMode |= WIFI_MODE_AX;
2456 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2457 }
2458 if (phymode & WMODE_BE_5G) {
2459 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2460 *pureMode |= WIFI_MODE_BE;
2461 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2462 }
2463 break;
2464 case band_6:
2465 if (phymode & WMODE_AX_6G) {
2466 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2467 *pureMode |= WIFI_MODE_AX;
2468 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2469 }
2470 if (phymode & WMODE_BE_6G) {
2471 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2472 *pureMode |= WIFI_MODE_BE;
2473 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2474 }
2475 break;
2476 default:
2477 fprintf(stderr, "%s band_idx invalid\n", __func__);
2478 break;
2479 }
2480
2481 /* Remove the last comma */
2482 if (strlen(output_string) != 0)
2483 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08002484
2485 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2486 return RETURN_OK;
2487}
2488
2489// Set the radio operating mode, and pure mode flag.
2490INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
2491{
developer69b61b02023-03-07 17:17:44 +08002492 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002493 if (strcmp (channelMode,"11A") == 0)
2494 {
2495 writeBandWidth(radioIndex,"20MHz");
2496 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2497 printf("\nChannel Mode is 802.11a (5GHz)\n");
2498 }
2499 else if (strcmp (channelMode,"11NAHT20") == 0)
2500 {
2501 writeBandWidth(radioIndex,"20MHz");
2502 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2503 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
2504 }
2505 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
2506 {
2507 writeBandWidth(radioIndex,"40MHz");
2508 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2509 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
2510 }
2511 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
2512 {
2513 writeBandWidth(radioIndex,"40MHz");
2514 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2515 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
2516 }
2517 else if (strcmp (channelMode,"11ACVHT20") == 0)
2518 {
2519 writeBandWidth(radioIndex,"20MHz");
2520 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2521 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
2522 }
2523 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
2524 {
2525 writeBandWidth(radioIndex,"40MHz");
2526 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2527 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
2528 }
2529 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
2530 {
2531 writeBandWidth(radioIndex,"40MHz");
2532 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2533 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
2534 }
2535 else if (strcmp (channelMode,"11ACVHT80") == 0)
2536 {
2537 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
2538 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
2539 }
2540 else if (strcmp (channelMode,"11ACVHT160") == 0)
2541 {
2542 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
2543 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
developer69b61b02023-03-07 17:17:44 +08002544 }
developer72fb0bb2023-01-11 09:46:29 +08002545 else if (strcmp (channelMode,"11B") == 0)
2546 {
2547 writeBandWidth(radioIndex,"20MHz");
2548 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2549 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
2550 }
2551 else if (strcmp (channelMode,"11G") == 0)
2552 {
2553 writeBandWidth(radioIndex,"20MHz");
2554 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2555 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
2556 }
2557 else if (strcmp (channelMode,"11NGHT20") == 0)
2558 {
2559 writeBandWidth(radioIndex,"20MHz");
2560 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2561 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
2562 }
2563 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
2564 {
2565 writeBandWidth(radioIndex,"40MHz");
2566 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2567 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
2568 }
2569 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
2570 {
2571 writeBandWidth(radioIndex,"40MHz");
2572 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2573 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
2574 }
developer69b61b02023-03-07 17:17:44 +08002575 else
developer72fb0bb2023-01-11 09:46:29 +08002576 {
2577 return RETURN_ERR;
2578 }
2579 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2580
2581 return RETURN_OK;
2582}
2583
developer0f10c772023-05-16 21:43:39 +08002584typedef enum _RT_802_11_PHY_MODE {
2585 PHY_11BG_MIXED = 0,
2586 PHY_11B = 1,
2587 PHY_11A = 2,
2588 PHY_11ABG_MIXED = 3,
2589 PHY_11G = 4,
2590 PHY_11ABGN_MIXED = 5, /* both band 5 */
2591 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
2592 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
2593 PHY_11AN_MIXED = 8, /* 5G band 8 */
2594 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
2595 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
2596 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
2597 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
2598 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
2599 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
2600 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
2601 PHY_11AX_24G = 16,
2602 PHY_11AX_5G = 17,
2603 PHY_11AX_6G = 18,
2604 PHY_11AX_24G_6G = 19,
2605 PHY_11AX_5G_6G = 20,
2606 PHY_11AX_24G_5G_6G = 21,
2607 PHY_11BE_24G = 22,
2608 PHY_11BE_5G = 23,
2609 PHY_11BE_6G = 24,
2610 PHY_11BE_24G_6G = 25,
2611 PHY_11BE_5G_6G = 26,
2612 PHY_11BE_24G_5G_6G = 27,
2613 PHY_MODE_MAX,
2614} RT_802_11_PHY_MODE;
2615
2616unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
2617{
2618 int band_idx = 0;
2619 unsigned int wireless_mode = PHY_MODE_MAX;
2620
2621 band_idx = radio_index_to_band(radioIndex);
2622
2623 switch (band_idx) {
2624 case band_2_4:
2625 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
2626 wireless_mode = PHY_11GN_MIXED;
2627 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
2628 wireless_mode = PHY_11BGN_MIXED;
2629 if (pureMode & WIFI_MODE_AX)
2630 wireless_mode = PHY_11AX_24G;
2631 if (pureMode & WIFI_MODE_BE)
2632 wireless_mode = PHY_11BE_24G;
2633 break;
2634 case band_5:
2635 if (pureMode == WIFI_MODE_N)
2636 wireless_mode = PHY_11N_5G;
2637 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
2638 wireless_mode = PHY_11VHT_N_MIXED;
2639 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
2640 wireless_mode = PHY_11VHT_N_A_MIXED;
2641 if (pureMode & WIFI_MODE_AX)
2642 wireless_mode = PHY_11AX_5G;
2643 if (pureMode & WIFI_MODE_BE)
2644 wireless_mode = PHY_11BE_5G;
2645 break;
2646 case band_6:
2647 if (pureMode & WIFI_MODE_AX)
2648 wireless_mode = PHY_11AX_6G;
2649 if (pureMode & WIFI_MODE_BE)
2650 wireless_mode = PHY_11BE_6G;
2651 break;
2652 default:
2653 fprintf(stderr, "%s band_idx invalid\n", __func__);
2654 break;
2655 }
2656
2657 return wireless_mode;
2658}
2659
developer72fb0bb2023-01-11 09:46:29 +08002660// Set the radio operating mode, and pure mode flag.
2661INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
2662{
developer0f10c772023-05-16 21:43:39 +08002663 unsigned int wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08002664
developer0f10c772023-05-16 21:43:39 +08002665 char interface_name[IF_NAME_SIZE] = {0};
2666 char cmd[MAX_CMD_SIZE] = {0};
2667 char buf[MAX_BUF_SIZE] = {0};
2668 int i;
developer72fb0bb2023-01-11 09:46:29 +08002669
developer0f10c772023-05-16 21:43:39 +08002670 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002671
developer0f10c772023-05-16 21:43:39 +08002672 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08002673
developer0f10c772023-05-16 21:43:39 +08002674 if (wireless_mode == PHY_MODE_MAX) {
2675 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
2676 return RETURN_ERR;
2677 }
developer72fb0bb2023-01-11 09:46:29 +08002678
developer0f10c772023-05-16 21:43:39 +08002679 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2680 return RETURN_ERR;
2681 snprintf(cmd, sizeof(cmd), "mwctl %s set phymode %d", interface_name, wireless_mode);
2682 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08002683
developer0f10c772023-05-16 21:43:39 +08002684 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2685
2686 return RETURN_OK;
2687}
2688
2689INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
2690{
2691 unsigned int wireless_mode = PHY_MODE_MAX;
2692 char interface_name[IF_NAME_SIZE] = {0};
2693 char cmd[MAX_CMD_SIZE] = {0};
2694 char buf[MAX_BUF_SIZE] = {0};
2695 int i;
2696 char dat_file[MAX_BUF_SIZE] = {0};
2697 struct params params={0};
2698
2699 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
2700
2701 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
2702
2703 if (wireless_mode == PHY_MODE_MAX) {
2704 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
2705 return RETURN_ERR;
2706 }
2707
2708 params.name = "WirelessMode";
2709 snprintf(buf, sizeof(buf), "%d", wireless_mode);
2710 params.value = buf;
2711
2712 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
2713 wifi_datfileWrite(dat_file, &params, 1);
2714
developer72fb0bb2023-01-11 09:46:29 +08002715 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2716
2717 return RETURN_OK;
2718}
2719
2720INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
2721
2722 char config_file[64] = {0};
2723 char buf[64] = {0};
2724 struct params params = {0};
2725 wifi_band band = band_invalid;
2726
2727 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2728
2729 band = wifi_index_to_band(radioIndex);
2730
2731 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
2732 return RETURN_ERR;
2733 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
2734 return RETURN_ERR;
2735 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
2736 return RETURN_ERR;
2737
2738 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2739 params.name = "hw_mode";
2740 params.value = hw_mode;
2741 wifi_hostapdWrite(config_file, &params, 1);
2742 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2743
2744 if (band == band_2_4) {
2745 if (strncmp(hw_mode, "b", 1) == 0) {
2746 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
2747 snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
2748 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
2749 snprintf(buf, sizeof(buf), "%s", "1,2");
2750 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
2751 } else {
2752 // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
2753
2754 snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
2755 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
2756 snprintf(buf, sizeof(buf), "%s", "6,12,24");
2757 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
2758 }
2759 }
2760
2761 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2762 return RETURN_OK;
2763}
2764
2765INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
2766{
2767 char config_file[64] = {0};
2768 struct params params = {0};
2769 wifi_band band = band_invalid;
2770
2771 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2772
2773 band = wifi_index_to_band(radioIndex);
2774 if (band != band_2_4)
2775 return RETURN_OK;
2776
2777 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2778 params.name = "noscan";
2779 params.value = noscan;
2780 wifi_hostapdWrite(config_file, &params, 1);
2781 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2782
2783 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2784 return RETURN_OK;
2785}
2786
2787//Get the list of supported channel. eg: "1-11"
2788//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
2789INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
2790{
2791 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08002792 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002793 return RETURN_ERR;
2794 char cmd[256] = {0};
2795 char buf[128] = {0};
2796 BOOL dfs_enable = false;
2797 int phyId = 0;
2798
2799 // Parse possible channel number and separate them with commas.
2800 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
2801 phyId = radio_index_to_phy(radioIndex);
2802 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
2803 if (dfs_enable)
2804 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId);
developer69b61b02023-03-07 17:17:44 +08002805 else
developer72fb0bb2023-01-11 09:46:29 +08002806 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'radar\\|no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId);
2807
2808 _syscmd(cmd,buf,sizeof(buf));
2809 strncpy(output_string, buf, sizeof(buf));
2810
2811 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2812 return RETURN_OK;
2813}
developerf6a87542023-05-16 15:47:28 +08002814
developer72fb0bb2023-01-11 09:46:29 +08002815//Get the list for used channel. eg: "1,6,9,11"
2816//The output_string is a max length 256 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
2817INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
2818{
2819 char interface_name[16] = {0};
2820 char cmd[128] = {0};
2821 char buf[128] = {0};
2822 char config_file[64] = {0};
2823 int channel = 0;
2824 int freq = 0;
2825 int bandwidth = 0;
2826 int center_freq = 0;
2827 int center_channel = 0;
2828 int channel_delta = 0;
2829 wifi_band band = band_invalid;
2830
2831 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2832
2833 if (NULL == output_string)
2834 return RETURN_ERR;
2835
2836 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2837 return RETURN_ERR;
2838 sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
2839 _syscmd(cmd, buf, sizeof(buf));
2840 if (strlen(buf) == 0) {
2841 fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__);
2842 return RETURN_ERR;
2843 }
2844 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
2845
2846 if (bandwidth == 20) {
2847 snprintf(output_string, 256, "%d", channel);
2848 return RETURN_OK;
2849 }
2850
2851 center_channel = ieee80211_frequency_to_channel(center_freq);
2852
2853 band = wifi_index_to_band(radioIndex);
2854 if (band == band_2_4 && bandwidth == 40) {
2855 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2856 memset(buf, 0, sizeof(buf));
2857 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
2858
2859 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
2860 snprintf(output_string, 256, "%d,%d", channel, channel+4);
2861 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
2862 snprintf(output_string, 256, "%d,%d", channel-4, channel);
2863 } else {
2864 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
2865 return RETURN_ERR;
2866 }
2867 } else if (band == band_5 || band == band_6){
2868 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
developer59fda4f2023-05-16 15:47:38 +08002869 // example: bandwidth 80: center is 42 (5210), channels are 36-48 (5170-5250). The delta should be 6.
developer72fb0bb2023-01-11 09:46:29 +08002870 channel_delta = (bandwidth-20)/10;
developer59fda4f2023-05-16 15:47:38 +08002871 snprintf(output_string, 256, "%d-%d", (center_channel-channel_delta), (center_channel+channel_delta));
developer72fb0bb2023-01-11 09:46:29 +08002872 } else
2873 return RETURN_ERR;
2874
2875 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2876 return RETURN_OK;
2877}
2878
developer69b61b02023-03-07 17:17:44 +08002879//Get the running channel number
developer72fb0bb2023-01-11 09:46:29 +08002880INT wifi_getRadioChannel(INT radioIndex,ULONG *output_ulong) //RDKB
2881{
2882 char channel_str[16] = {0};
2883 char config_file[128] = {0};
2884
2885 if (output_ulong == NULL)
2886 return RETURN_ERR;
2887
2888 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
2889 wifi_hostapdRead(config_file, "channel", channel_str, sizeof(channel_str));
2890
2891 *output_ulong = strtoul(channel_str, NULL, 10);
2892
2893 return RETURN_OK;
2894}
2895
2896
2897INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
2898{
2899 char cmd[1024] = {0}, buf[5] = {0};
2900 char interface_name[16] = {0};
2901
2902 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2903 if (NULL == output_ulong)
2904 return RETURN_ERR;
2905
2906 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name);
2907 if (wifi_getApName(apIndex,interface_name) != RETURN_OK)
2908 return RETURN_ERR;
2909 _syscmd(cmd,buf,sizeof(buf));
2910 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
2911 if (*output_ulong == 0) {
2912 return RETURN_ERR;
2913 }
2914
2915 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2916 return RETURN_OK;
2917}
2918
2919//Storing the previous channel value
2920INT wifi_storeprevchanval(INT radioIndex)
2921{
2922 char buf[256] = {0};
2923 char output[4]={'\0'};
2924 char config_file[MAX_BUF_SIZE] = {0};
2925 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
2926 wifi_hostapdRead(config_file, "channel", output, sizeof(output));
2927 if(radioIndex == 0)
2928 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
2929 else if(radioIndex == 1)
2930 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
2931 system(buf);
2932 Radio_flag = FALSE;
2933 return RETURN_OK;
2934}
2935
2936//Set the running channel number
2937INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
2938{
2939 // We only write hostapd config here
2940 char str_channel[8]={0};
2941 char *list_channel;
2942 char config_file[128] = {0};
2943 char possible_channels[256] = {0};
2944 int max_radio_num = 0;
2945 struct params list = {0};
2946
2947 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2948
2949 // Check valid
2950 sprintf(str_channel, "%lu", channel);
2951
2952 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
2953 list_channel = strtok(possible_channels, ",");
2954 while(true)
2955 {
2956 if(list_channel == NULL) { // input not in the list
2957 fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel);
2958 return RETURN_ERR;
2959 }
2960 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
2961 break;
2962 list_channel = strtok(NULL, ",");
2963 }
developerf6a87542023-05-16 15:47:28 +08002964
developer72fb0bb2023-01-11 09:46:29 +08002965 list.name = "channel";
2966 list.value = str_channel;
2967 wifi_getMaxRadioNumber(&max_radio_num);
2968 for(int i=0; i<=MAX_APS/max_radio_num;i++)
2969 {
2970 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
2971 wifi_hostapdWrite(config_file, &list, 1);
2972 }
developerf6a87542023-05-16 15:47:28 +08002973
developer72fb0bb2023-01-11 09:46:29 +08002974 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2975 return RETURN_OK;
2976}
2977
2978INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
2979{
2980 struct params list[2];
2981 char str_idx[16];
2982 char config_file[64];
2983 int max_num_radios = 0;
2984 wifi_band band = band_invalid;
2985
2986 band = wifi_index_to_band(radioIndex);
2987 if (band == band_2_4)
2988 return RETURN_OK;
2989
2990 snprintf(str_idx, sizeof(str_idx), "%lu", channel);
2991 list[0].name = "vht_oper_centr_freq_seg0_idx";
2992 list[0].value = str_idx;
2993 list[1].name = "he_oper_centr_freq_seg0_idx";
2994 list[1].value = str_idx;
2995
2996 wifi_getMaxRadioNumber(&max_num_radios);
2997 for(int i=0; i<=MAX_APS/max_num_radios; i++)
2998 {
2999 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
3000 if (band == band_6)
3001 wifi_hostapdWrite(config_file, &list[1], 1);
3002 else
3003 wifi_hostapdWrite(config_file, list, 2);
3004 }
3005
3006 return RETURN_OK;
3007}
3008
3009//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
3010//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
3011INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
3012{
3013 //Set to wifi config only. Wait for wifi reset to apply.
3014 char buf[256] = {0};
3015 char str_channel[256] = {0};
3016 int count = 0;
3017 ULONG Value = 0;
3018 FILE *fp = NULL;
3019 if(enable == TRUE)
3020 {
3021 wifi_setRadioChannel(radioIndex,Value);
3022 }
3023 return RETURN_OK;
3024}
3025
3026INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
3027{
3028 if (output_bool == NULL)
3029 return RETURN_ERR;
3030
3031 *output_bool = TRUE;
3032
3033 return RETURN_OK;
3034}
3035
3036INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
3037{
developer69b61b02023-03-07 17:17:44 +08003038 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003039 return RETURN_ERR;
3040 *output_bool=FALSE;
3041 return RETURN_OK;
3042}
3043
3044INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
3045{
developer69b61b02023-03-07 17:17:44 +08003046 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003047 return RETURN_ERR;
3048 *output_bool=FALSE;
3049 return RETURN_OK;
3050}
3051
3052INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
3053{
3054 //Set to wifi config only. Wait for wifi reset to apply.
3055 return RETURN_OK;
3056}
3057
3058INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
3059{
3060 return RETURN_OK;
3061}
3062
3063INT wifi_factoryResetAP(int apIndex)
3064{
3065 char ap_config_file[64] = {0};
3066 char cmd[128] = {0};
3067
3068 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3069
3070 wifi_setApEnable(apIndex, FALSE);
3071 sprintf(ap_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
3072 sprintf(cmd, "rm %s && sh /lib/rdk/hostapd-init.sh", ap_config_file);
3073 wifi_setApEnable(apIndex, TRUE);
3074
3075 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3076
3077 return RETURN_OK;
3078}
3079
3080//To set Band Steering AP group
3081//To-do
3082INT wifi_setBandSteeringApGroup(char *ApGroup)
3083{
3084 return RETURN_OK;
3085}
3086
3087INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
3088{
3089 char config_file[128] = {'\0'};
3090 char buf[128] = {'\0'};
3091
3092 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3093 if (dtimInterval == NULL)
3094 return RETURN_ERR;
3095
3096 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
3097 wifi_hostapdRead(config_file, "dtime_period", buf, sizeof(buf));
3098
3099 if (strlen(buf) == 0) {
3100 *dtimInterval = 2;
3101 } else {
3102 *dtimInterval = strtoul(buf, NULL, 10);
3103 }
3104
3105 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3106 return RETURN_OK;
3107}
3108
3109INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
3110{
3111 struct params params={0};
3112 char config_file[MAX_BUF_SIZE] = {'\0'};
3113 char buf[MAX_BUF_SIZE] = {'\0'};
3114
3115 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3116 if (dtimInterval < 1 || dtimInterval > 255) {
3117 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
3118 return RETURN_ERR;
3119 }
developer69b61b02023-03-07 17:17:44 +08003120
developer72fb0bb2023-01-11 09:46:29 +08003121 params.name = "dtim_period";
3122 snprintf(buf, sizeof(buf), "%d", dtimInterval);
3123 params.value = buf;
3124
3125 sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex);
3126 wifi_hostapdWrite(config_file, &params, 1);
3127 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3128
3129 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3130 return RETURN_OK;
3131}
3132
3133//Check if the driver support the Dfs
3134INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
3135{
3136 wifi_band band = band_invalid;
developer69b61b02023-03-07 17:17:44 +08003137 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003138 return RETURN_ERR;
3139 *output_bool=FALSE;
3140
3141 band = wifi_index_to_band(radioIndex);
3142 if (band == band_5)
3143 *output_bool = TRUE;
3144 return RETURN_OK;
3145}
3146
3147//The output_string is a max length 256 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
3148//The value of this parameter is a comma seperated list of channel number
3149INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
3150{
developer69b61b02023-03-07 17:17:44 +08003151 if (NULL == output_pool)
developer72fb0bb2023-01-11 09:46:29 +08003152 return RETURN_ERR;
3153 if (radioIndex==1)
developer69b61b02023-03-07 17:17:44 +08003154 return RETURN_OK;//TODO need to handle for 5GHz band, i think
developer72fb0bb2023-01-11 09:46:29 +08003155 snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
3156
3157 return RETURN_OK;
3158}
3159
3160INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
3161{
3162 //Set to wifi config. And apply instantly.
3163 return RETURN_OK;
3164}
3165
3166INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
3167{
developer69b61b02023-03-07 17:17:44 +08003168 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
developer72fb0bb2023-01-11 09:46:29 +08003169 return RETURN_ERR;
3170 *output_interval_seconds=1800;
3171 *output_dwell_milliseconds=40;
3172
3173 return RETURN_OK;
3174}
3175
3176INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
3177{
3178 //Set to wifi config. And apply instantly.
3179 return RETURN_OK;
3180}
3181
3182INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
3183{
3184 if (output_bool == NULL)
3185 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08003186 *output_bool = true;
3187 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003188}
3189
3190INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
3191{
3192 return RETURN_OK;
3193}
3194
3195//Get the Dfs enable status
3196INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
3197{
3198 char buf[16] = {0};
3199 FILE *f = NULL;
3200
3201 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3202
3203 if (output_bool == NULL)
3204 return RETURN_ERR;
developer4903e3f2023-05-15 10:04:40 +08003205
developerf6a87542023-05-16 15:47:28 +08003206 *output_bool = TRUE; // default
3207 f = fopen(DFS_ENABLE_FILE, "r");
3208 if (f != NULL) {
3209 fgets(buf, 2, f);
3210 if (strncmp(buf, "0", 1) == 0)
3211 *output_bool = FALSE;
3212 fclose(f);
3213 }
developer72fb0bb2023-01-11 09:46:29 +08003214 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3215 return RETURN_OK;
3216}
3217
3218//Set the Dfs enable status
3219INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
3220{
3221 char config_file[128] = {0};
3222 FILE *f = NULL;
developerf6a87542023-05-16 15:47:28 +08003223 struct params params={0};
developer72fb0bb2023-01-11 09:46:29 +08003224
3225 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3226
3227 f = fopen(DFS_ENABLE_FILE, "w");
3228 if (f == NULL)
3229 return RETURN_ERR;
3230 fprintf(f, "%d", enable);
3231 fclose(f);
3232
3233 params.name = "acs_exclude_dfs";
3234 params.value = enable?"0":"1";
3235 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3236 wifi_hostapdWrite(config_file, &params, 1);
3237 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developerf6a87542023-05-16 15:47:28 +08003238
developer72fb0bb2023-01-11 09:46:29 +08003239 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
3240
3241 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3242 return RETURN_OK;
3243}
3244
3245//Check if the driver support the AutoChannelRefreshPeriod
3246INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
3247{
developer69b61b02023-03-07 17:17:44 +08003248 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003249 return RETURN_ERR;
3250 *output_bool=FALSE; //not support
3251
3252 return RETURN_OK;
3253}
3254
3255//Get the ACS refresh period in seconds
3256INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
3257{
developer69b61b02023-03-07 17:17:44 +08003258 if (NULL == output_ulong)
developer72fb0bb2023-01-11 09:46:29 +08003259 return RETURN_ERR;
3260 *output_ulong=300;
3261
3262 return RETURN_OK;
3263}
3264
3265//Set the ACS refresh period in seconds
3266INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
3267{
3268 return RETURN_ERR;
3269}
3270
3271//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
3272//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
3273INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
3274{
developer8666b312023-03-24 14:05:31 +08003275 char cmd[MAX_CMD_SIZE] = {0}, buf[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003276 char extchannel[128] = {0};
developer8666b312023-03-24 14:05:31 +08003277 char interface_name[64] = {0};
3278 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08003279 BOOL radio_enable = FALSE;
3280 wifi_band band;
3281
3282 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3283
3284 if (NULL == output_string)
3285 return RETURN_ERR;
3286
3287 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR)
3288 return RETURN_ERR;
3289
3290 if (radio_enable != TRUE)
3291 return RETURN_OK;
3292
developer8666b312023-03-24 14:05:31 +08003293 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3294 return RETURN_ERR;
3295 /*IW command get BW320 to do*/
3296 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
3297 ret = _syscmd(cmd, buf, sizeof(buf));
3298 len = strlen(buf);
3299 if((ret != 0) || (len == 0))
3300 {
3301 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
3302 return RETURN_ERR;
3303 }
3304
developer72fb0bb2023-01-11 09:46:29 +08003305 band = wifi_index_to_band(radioIndex);
developer8666b312023-03-24 14:05:31 +08003306 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
developer72fb0bb2023-01-11 09:46:29 +08003307 wifi_getRadioExtChannel(radioIndex, extchannel);
developer8666b312023-03-24 14:05:31 +08003308 if (strncmp(extchannel, "Auto", 4) != 0) // not auto means we have set HT40+/-
3309 snprintf(buf, sizeof(buf), "40");
developer72fb0bb2023-01-11 09:46:29 +08003310 }
developer8666b312023-03-24 14:05:31 +08003311 snprintf(output_string, 64, "%sMHz", buf);
developer72fb0bb2023-01-11 09:46:29 +08003312 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3313
3314 return RETURN_OK;
3315}
developer72fb0bb2023-01-11 09:46:29 +08003316//Set the Operating Channel Bandwidth.
3317INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
3318{
3319 char config_file[128];
3320 char set_value[16];
3321 struct params params[2];
3322 int max_radio_num = 0;
3323
3324 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3325
3326 if(NULL == bandwidth)
3327 return RETURN_ERR;
3328
3329 if(strstr(bandwidth,"160") != NULL)
3330 strcpy(set_value, "2");
3331 else if(strstr(bandwidth,"80") != NULL)
3332 strcpy(set_value, "1");
3333 else if(strstr(bandwidth,"20") != NULL || strstr(bandwidth,"40") != NULL)
3334 strcpy(set_value, "0");
3335 else
3336 {
3337 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
3338 return RETURN_ERR;
3339 }
3340
3341 params[0].name = "vht_oper_chwidth";
3342 params[0].value = set_value;
3343 params[1].name = "he_oper_chwidth";
3344 params[1].value = set_value;
3345
3346 wifi_getMaxRadioNumber(&max_radio_num);
3347 for(int i=0; i<=MAX_APS/max_radio_num; i++)
3348 {
3349 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3350 wifi_hostapdWrite(config_file, params, 2);
3351 }
3352
3353 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3354 return RETURN_OK;
3355}
3356
developerf6a87542023-05-16 15:47:28 +08003357//Getting current radio extension channel
3358INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3359{
3360 CHAR buf[150] = {0};
3361 CHAR cmd[150] = {0};
3362 sprintf(cmd,"%s%s%s","cat ",file," | grep -w ht_capab=");
3363 _syscmd(cmd, buf, sizeof(buf));
3364 if(NULL != strstr(buf,"HT40+"))
3365 strcpy(Value,"AboveControlChannel");
3366 else if(NULL != strstr(buf,"HT40-"))
3367 strcpy(Value,"BelowControlChannel");
3368 return RETURN_OK;
3369}
developer72fb0bb2023-01-11 09:46:29 +08003370
3371//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
3372//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
3373INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
3374{
3375 char config_file[64] = {0};
3376 char mode_str[16] = {0};
3377 char buf[64] = {0};
3378 wifi_band band;
developerf6a87542023-05-16 15:47:28 +08003379 int channel = 0, centr_channel = 0;
developer72fb0bb2023-01-11 09:46:29 +08003380 UINT mode_map = 0;
3381
3382 if (output_string == NULL)
3383 return RETURN_ERR;
3384
3385 wifi_getRadioMode(radioIndex, mode_str, &mode_map);
3386
3387 band = wifi_index_to_band(radioIndex);
3388 if (band == band_invalid)
3389 return RETURN_ERR;
3390
3391 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3392
3393 snprintf(output_string, 64, "Auto");
developer23e71282023-01-18 10:25:19 +08003394 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
developer72fb0bb2023-01-11 09:46:29 +08003395 // 2G band or ac and ax mode is disable, we will check ht_capab
3396 wifi_halgetRadioExtChannel(config_file, output_string);
developer23e71282023-01-18 10:25:19 +08003397 if (!(mode_map&WIFI_MODE_N))
developer72fb0bb2023-01-11 09:46:29 +08003398 snprintf(output_string, 64, "Auto");
3399 } else {
3400 // 5G and 6G band with ac or ax mode.
3401 wifi_getRadioChannel(radioIndex, &channel);
3402 if (mode_map&WIFI_MODE_AX)
3403 wifi_hostapdRead(config_file, "he_oper_centr_freq_seg0_idx", buf, sizeof(buf));
3404 else
3405 wifi_hostapdRead(config_file, "vht_oper_centr_freq_seg0_idx", buf, sizeof(buf));
3406 centr_channel = strtol(buf, NULL, 10);
3407 if (centr_channel > channel)
3408 snprintf(output_string, 64, "AboveControlChannel");
3409 else
3410 snprintf(output_string, 64, "BelowControlChannel");
3411 }
3412
3413 return RETURN_OK;
3414}
3415
3416//Set the extension channel.
3417INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08003418{
developer72fb0bb2023-01-11 09:46:29 +08003419 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3420 struct params params={0};
3421 char config_file[64] = {0};
3422 char ext_channel[128]={0};
3423 char buf[128] = {0};
3424 char cmd[128] = {0};
3425 int max_radio_num =0, ret = 0, bandwidth = 0;
3426 unsigned long channel = 0, centr_channel = 0;
3427 bool stbcEnable = FALSE;
3428 params.name = "ht_capab";
3429 wifi_band band;
3430
3431 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3432 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
3433 _syscmd(cmd, buf, sizeof(buf));
3434 if (strlen(buf) != 0)
3435 stbcEnable = TRUE;
3436 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
3437 return RETURN_ERR;
3438 bandwidth = strtol(buf, NULL, 10);
3439 // TDK expected to get error with 20MHz
3440 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
3441 return RETURN_ERR;
3442
3443 band = wifi_index_to_band(radioIndex);
3444 if (band == band_invalid)
3445 return RETURN_ERR;
3446
3447 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
3448 return RETURN_ERR;
3449
3450 if (band == band_5) {
3451 snprintf(buf, sizeof(buf), "HT%d", bandwidth);
3452 centr_channel = util_unii_5g_centerfreq(buf, channel);
3453 if (centr_channel == 0)
3454 return RETURN_ERR;
3455 }
3456
3457 if(NULL!= strstr(string,"Above")) {
3458 if ((band == band_2_4 && channel > 9) || (band == band_5 && channel > centr_channel))
3459 return RETURN_ERR;
3460 strcpy(ext_channel, HOSTAPD_HT_CAPAB "[HT40+]");
3461 } else if(NULL!= strstr(string,"Below")) {
3462 if ((band == band_2_4 && channel < 5) || (band == band_5 && channel < centr_channel))
3463 return RETURN_ERR;
3464 strcpy(ext_channel, HOSTAPD_HT_CAPAB "[HT40-]");
3465 } else {
3466 strcpy(ext_channel, HOSTAPD_HT_CAPAB);
3467 }
3468
3469 params.value = ext_channel;
3470
3471 wifi_getMaxRadioNumber(&max_radio_num);
3472 for(int i=0; i<=MAX_APS/max_radio_num; i++)
3473 {
3474 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
3475 wifi_hostapdWrite(config_file, &params, 1);
3476 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
3477 }
3478
3479 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
3480 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3481 return RETURN_OK;
3482}
3483
3484//Get the guard interval value. eg "400nsec" or "800nsec"
3485//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
3486INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
3487{
3488 wifi_guard_interval_t GI;
3489
3490 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3491
3492 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
3493 return RETURN_ERR;
3494
3495 if (GI == wifi_guard_interval_400)
3496 strcpy(output_string, "400nsec");
3497 else if (GI == wifi_guard_interval_800)
3498 strcpy(output_string, "800nsec");
3499 else if (GI == wifi_guard_interval_1600)
3500 strcpy(output_string, "1600nsec");
3501 else if (GI == wifi_guard_interval_3200)
3502 strcpy(output_string, "3200nsec");
3503 else
3504 strcpy(output_string, "Auto");
3505
3506 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3507 return RETURN_OK;
3508}
3509
3510//Set the guard interval value.
3511INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
3512{
3513 wifi_guard_interval_t GI;
3514 int ret = 0;
3515
3516 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3517
3518 if (strcmp(string, "400nsec") == 0)
3519 GI = wifi_guard_interval_400;
3520 else if (strcmp(string , "800nsec") == 0)
3521 GI = wifi_guard_interval_800;
3522 else if (strcmp(string , "1600nsec") == 0)
3523 GI = wifi_guard_interval_1600;
3524 else if (strcmp(string , "3200nsec") == 0)
3525 GI = wifi_guard_interval_3200;
3526 else
3527 GI = wifi_guard_interval_auto;
3528
3529 ret = wifi_setGuardInterval(radioIndex, GI);
3530
3531 if (ret == RETURN_ERR) {
3532 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
3533 return RETURN_ERR;
3534 }
3535
3536 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3537 return RETURN_OK;
3538}
3539
3540//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
3541INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
3542{
3543 char buf[32]={0};
3544 char mcs_file[64] = {0};
3545 char cmd[64] = {0};
3546 int mode_bitmap = 0;
3547
3548 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3549 if(output_int == NULL)
3550 return RETURN_ERR;
3551 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
3552
3553 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
3554 _syscmd(cmd, buf, sizeof(buf));
3555 if (strlen(buf) > 0)
3556 *output_int = strtol(buf, NULL, 10);
3557 else {
3558 // output the max MCS for the current radio mode
3559 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
3560 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
3561 return RETURN_ERR;
3562 }
3563 if (mode_bitmap & WIFI_MODE_AX) {
3564 *output_int = 11;
3565 } else if (mode_bitmap & WIFI_MODE_AC) {
3566 *output_int = 9;
3567 } else if (mode_bitmap & WIFI_MODE_N) {
3568 *output_int = 7;
3569 }
3570 }
3571 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3572
3573 return RETURN_OK;
3574}
3575
3576//Set the Modulation Coding Scheme index
3577INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
3578{
developera1255e42023-05-13 17:45:02 +08003579 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
3580 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
developer72fb0bb2023-01-11 09:46:29 +08003581 char config_file[64] = {0};
3582 char set_value[16] = {0};
3583 char mcs_file[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003584 struct params set_config = {0};
3585 FILE *f = NULL;
developera1255e42023-05-13 17:45:02 +08003586 INT nss = 0;
3587 int ant_bitmap = 0;
3588 unsigned short cal_value = 0;
3589 UCHAR tval = 0, i = 0;
developer72fb0bb2023-01-11 09:46:29 +08003590
3591 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3592
3593 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3594
3595 // -1 means auto
3596 if (MCS > 15 || MCS < -1) {
3597 fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS);
3598 return RETURN_ERR;
3599 }
developera1255e42023-05-13 17:45:02 +08003600 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
3601 for(; ant_bitmap > 0; ant_bitmap >>= 1)
3602 nss += 1;
3603 //printf("%s:nss = %d\n", __func__, nss);
3604 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
3605 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
developer72fb0bb2023-01-11 09:46:29 +08003606 if (MCS > 9 || MCS == -1)
developera1255e42023-05-13 17:45:02 +08003607 tval = 2;/*one stream value*/
developer72fb0bb2023-01-11 09:46:29 +08003608 else if (MCS > 7)
developera1255e42023-05-13 17:45:02 +08003609 tval = 1;
developer72fb0bb2023-01-11 09:46:29 +08003610 else
developera1255e42023-05-13 17:45:02 +08003611 tval = 0;
3612 for (i = 0; i < nss; i++)
3613 cal_value |= (tval << (2*i));
3614 snprintf(set_value, sizeof(set_value), "%x", cal_value);
3615 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
3616 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
developer72fb0bb2023-01-11 09:46:29 +08003617 set_config.value = set_value;
3618
3619 wifi_hostapdWrite(config_file, &set_config, 1);
3620 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
3621
3622 // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
3623 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
3624 f = fopen(mcs_file, "w");
3625 if (f == NULL) {
3626 fprintf(stderr, "%s: fopen failed\n", __func__);
3627 return RETURN_ERR;
3628 }
3629 fprintf(f, "%d", MCS);
3630 fclose(f);
3631
3632 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3633 return RETURN_OK;
3634}
3635
3636//Get supported Transmit Power list, eg : "0,25,50,75,100"
3637//The output_list is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
3638INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
3639{
3640 if (NULL == output_list)
3641 return RETURN_ERR;
3642 snprintf(output_list, 64,"0,25,50,75,100");
3643 return RETURN_OK;
3644}
3645
3646//Get current Transmit Power in dBm units.
3647//The transmite power level is in units of full power for this radio.
3648INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
3649{
3650 char interface_name[16] = {0};
3651 char cmd[128]={0};
3652 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08003653 char pwr_file[128]={0};
3654
developer72fb0bb2023-01-11 09:46:29 +08003655 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3656
3657 if(output_ulong == NULL)
3658 return RETURN_ERR;
3659
3660 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3661 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08003662/*
developer72fb0bb2023-01-11 09:46:29 +08003663 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
3664 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003665 *output_ulong = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +08003666*/
3667 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
3668 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
3669 _syscmd(cmd, buf, sizeof(buf));
3670 if (strlen(buf) > 0)
3671 *output_ulong = strtol(buf, NULL, 10);
3672 else
3673 *output_ulong = 100;
developer72fb0bb2023-01-11 09:46:29 +08003674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3675 return RETURN_OK;
3676}
3677
3678//Set Transmit Power
3679//The transmite power level is in units of full power for this radio.
3680INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
3681{
3682 char interface_name[16] = {0};
3683 char *support;
3684 char cmd[128]={0};
3685 char buf[128]={0};
3686 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08003687 char pwr_file[128]={0};
3688 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08003689
3690 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3691
3692 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3693 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08003694 // Get the Tx power supported list and check that is the input in the list
3695 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
3696 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
3697 support = strtok(buf, ",");
3698 while(true)
3699 {
3700 if(support == NULL) { // input not in the list
3701 wifi_dbg_printf("Input value is invalid.\n");
3702 return RETURN_ERR;
3703 }
3704 if (strncmp(txpower_str, support, strlen(support)) == 0) {
3705 break;
3706 }
3707 support = strtok(NULL, ",");
3708 }
3709 snprintf(cmd, sizeof(cmd), "mwctl dev %s set pwr PercentageCtrl=1\n", interface_name);
3710 _syscmd(cmd, buf, sizeof(buf));
3711 snprintf(cmd, sizeof(cmd), "mwctl dev %s set pwr PowerDropCtrl=%lu\n", interface_name, TransmitPower);
3712 _syscmd(cmd, buf, sizeof(buf));
3713 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
3714 f = fopen(pwr_file, "w");
3715 if (f == NULL) {
3716 fprintf(stderr, "%s: fopen failed\n", __func__);
3717 return RETURN_ERR;
3718 }
3719 fprintf(f, "%d", TransmitPower);
3720 fclose(f);
3721/* snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08003722 _syscmd(cmd, buf, sizeof(buf));
3723 maximum_tx = strtol(buf, NULL, 10);
3724
3725 // Get the Tx power supported list and check that is the input in the list
3726 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
3727 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
3728 support = strtok(buf, ",");
3729 while(true)
3730 {
3731 if(support == NULL) { // input not in the list
3732 wifi_dbg_printf("Input value is invalid.\n");
3733 return RETURN_ERR;
3734 }
3735 if (strncmp(txpower_str, support, strlen(support)) == 0) {
3736 break;
3737 }
3738 support = strtok(NULL, ",");
3739 }
3740 txpower = TransmitPower*maximum_tx/100;
3741 phyId = radio_index_to_phy(radioIndex);
3742 snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower);
3743 _syscmd(cmd, buf, sizeof(buf));
3744 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +08003745*/
3746 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003747}
3748
3749//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
3750INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
3751{
developer69b61b02023-03-07 17:17:44 +08003752 if (NULL == Supported)
developer72fb0bb2023-01-11 09:46:29 +08003753 return RETURN_ERR;
3754 *Supported = TRUE;
3755
3756 return RETURN_OK;
3757}
3758
3759//Get 80211h feature enable
3760INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
3761{
3762 char buf[64]={'\0'};
3763 char config_file[64] = {'\0'};
3764
3765 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3766 if(enable == NULL)
3767 return RETURN_ERR;
3768
3769 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3770 wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf));
3771
3772 if (strncmp(buf, "1", 1) == 0)
3773 *enable = TRUE;
3774 else
3775 *enable = FALSE;
3776
3777 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3778 return RETURN_OK;
3779}
3780
3781//Set 80211h feature enable
3782INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
3783{
3784 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3785 struct params params={'\0'};
3786 char config_file[MAX_BUF_SIZE] = {0};
3787
3788 params.name = "ieee80211h";
3789
3790 if (enable) {
3791 params.value = "1";
3792 } else {
3793 params.value = "0";
3794 }
3795
3796 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3797 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08003798
developer72fb0bb2023-01-11 09:46:29 +08003799 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3800 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3801 return RETURN_OK;
3802}
3803
3804//Indicates the Carrier Sense ranges supported by the radio. It is measured in dBm. Refer section A.2.3.2 of CableLabs Wi-Fi MGMT Specification.
3805INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
3806{
3807 if (NULL == output)
3808 return RETURN_ERR;
3809 *output=100;
3810
3811 return RETURN_OK;
3812}
3813
3814//The RSSI signal level at which CS/CCA detects a busy condition. This attribute enables APs to increase minimum sensitivity to avoid detecting busy condition from multiple/weak Wi-Fi sources in dense Wi-Fi environments. It is measured in dBm. Refer section A.2.3.2 of CableLabs Wi-Fi MGMT Specification.
3815INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
3816{
3817 if (NULL == output)
3818 return RETURN_ERR;
3819 *output = -99;
3820
3821 return RETURN_OK;
3822}
3823
3824INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
3825{
3826 return RETURN_ERR;
3827}
3828
3829
3830//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
3831INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
3832{
3833 char interface_name[16] = {0};
3834 char cmd[MAX_BUF_SIZE]={'\0'};
3835 char buf[MAX_CMD_SIZE]={'\0'};
3836
3837 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3838 if(output == NULL)
3839 return RETURN_ERR;
3840
3841 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3842 return RETURN_ERR;
3843 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
3844 _syscmd(cmd, buf, sizeof(buf));
3845 *output = atoi(buf);
3846
3847 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3848 return RETURN_OK;
3849}
developer69b61b02023-03-07 17:17:44 +08003850
developer72fb0bb2023-01-11 09:46:29 +08003851INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
3852{
3853 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3854 struct params params={'\0'};
3855 char buf[MAX_BUF_SIZE] = {'\0'};
3856 char config_file[MAX_BUF_SIZE] = {'\0'};
3857
3858 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
3859 return RETURN_ERR;
3860
3861 params.name = "beacon_int";
3862 snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
3863 params.value = buf;
3864
3865 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3866 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08003867
developer72fb0bb2023-01-11 09:46:29 +08003868 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3869 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3870 return RETURN_OK;
3871}
3872
3873//Comma-separated list of strings. The set of data rates, in Mbps, that have to be supported by all stations that desire to join this BSS. The stations have to be able to receive and transmit at each of the data rates listed inBasicDataTransmitRates. For example, a value of "1,2", indicates that stations support 1 Mbps and 2 Mbps. Most control packets use a data rate in BasicDataTransmitRates.
3874INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
3875{
3876 //TODO: need to revisit below implementation
3877 char *temp;
3878 char temp_output[128] = {0};
3879 char temp_TransmitRates[64] = {0};
3880 char config_file[64] = {0};
3881
3882 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3883 if (NULL == output)
3884 return RETURN_ERR;
3885 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
3886 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08003887
developer72fb0bb2023-01-11 09:46:29 +08003888 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
3889 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
3890 } else {
3891 temp = strtok(temp_TransmitRates," ");
3892 while(temp!=NULL)
3893 {
3894 // Convert 100 kbps to Mbps
3895 temp[strlen(temp)-1]=0;
3896 if((temp[0]=='5') && (temp[1]=='\0'))
3897 {
3898 temp="5.5";
3899 }
3900 strcat(temp_output,temp);
3901 temp = strtok(NULL," ");
3902 if(temp!=NULL)
3903 {
3904 strcat(temp_output,",");
3905 }
3906 }
3907 strcpy(output,temp_output);
3908 }
3909 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3910 return RETURN_OK;
3911}
3912
3913INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
3914{
3915 char *temp;
3916 char temp1[128];
3917 char temp_output[128];
3918 char temp_TransmitRates[128];
3919 char set[128];
3920 char sub_set[128];
3921 int set_count=0,subset_count=0;
3922 int set_index=0,subset_index=0;
3923 char *token;
3924 int flag=0, i=0;
3925 struct params params={'\0'};
3926 char config_file[MAX_BUF_SIZE] = {0};
3927 wifi_band band = wifi_index_to_band(radioIndex);
3928
3929 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3930 if(NULL == TransmitRates)
3931 return RETURN_ERR;
3932 strcpy(sub_set,TransmitRates);
3933
3934 //Allow only supported Data transmit rate to be set
3935 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
3936 token = strtok(sub_set,",");
3937 while( token != NULL ) /* split the basic rate to be set, by comma */
3938 {
3939 sub_set[subset_count]=atoi(token);
3940 subset_count++;
3941 token=strtok(NULL,",");
3942 }
3943 token=strtok(set,",");
3944 while(token!=NULL) /* split the supported rate by comma */
3945 {
3946 set[set_count]=atoi(token);
3947 set_count++;
3948 token=strtok(NULL,",");
3949 }
3950 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
3951 {
3952 for(set_index=0;set_index < set_count;set_index++)
3953 {
3954 flag=0;
3955 if(sub_set[subset_index]==set[set_index])
3956 break;
3957 else
3958 flag=1; /* No match found */
3959 }
3960 if(flag==1)
3961 return RETURN_ERR; //If value not found return Error
3962 }
3963 strcpy(temp_TransmitRates,TransmitRates);
3964
3965 for(i=0;i<strlen(temp_TransmitRates);i++)
3966 {
3967 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
3968 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
3969 {
3970 continue;
3971 }
3972 else
3973 {
3974 return RETURN_ERR;
3975 }
3976 }
3977 strcpy(temp_output,"");
3978 temp = strtok(temp_TransmitRates,",");
3979 while(temp!=NULL)
3980 {
3981 strcpy(temp1,temp);
3982 if(band == band_5)
3983 {
3984 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
3985 {
3986 return RETURN_ERR;
3987 }
3988 }
3989
3990 if(strcmp(temp,"5.5")==0)
3991 {
3992 strcpy(temp1,"55");
3993 }
3994 else
3995 {
3996 strcat(temp1,"0");
3997 }
3998 strcat(temp_output,temp1);
3999 temp = strtok(NULL,",");
4000 if(temp!=NULL)
4001 {
4002 strcat(temp_output," ");
4003 }
4004 }
4005 strcpy(TransmitRates,temp_output);
4006
4007 params.name= "basic_rates";
4008 params.value =TransmitRates;
4009
4010 wifi_dbg_printf("\n%s:",__func__);
4011 wifi_dbg_printf("\nparams.value=%s\n",params.value);
4012 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
4013 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4014 wifi_hostapdWrite(config_file,&params,1);
4015 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4016 return RETURN_OK;
4017}
4018
4019//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
4020INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
4021{
4022 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4023 FILE *fp = NULL;
4024 char path[256] = {0}, output_string[256] = {0};
4025 int count = 0;
4026 char *interface = NULL;
4027
4028 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
4029 if (fp == NULL)
4030 {
4031 printf("Failed to run command in Function %s\n", __FUNCTION__);
4032 return RETURN_ERR;
4033 }
4034 if (fgets(path, sizeof(path) - 1, fp) != NULL)
4035 {
4036 interface = strchr(path, '=');
4037
4038 if (interface != NULL)
4039 {
4040 strcpy(output_string, interface + 1);
4041 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
4042 interface_name[count] = output_string[count];
4043
4044 interface_name[count] = '\0';
4045 }
4046 }
4047 pclose(fp);
4048 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4049 return RETURN_OK;
4050}
4051
4052INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
4053{
4054 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4055 output_struct->radio_BytesSent = 0;
4056 output_struct->radio_BytesReceived = 0;
4057 output_struct->radio_PacketsSent = 0;
4058 output_struct->radio_PacketsReceived = 0;
4059 output_struct->radio_ErrorsSent = 0;
4060 output_struct->radio_ErrorsReceived = 0;
4061 output_struct->radio_DiscardPacketsSent = 0;
4062 output_struct->radio_DiscardPacketsReceived = 0;
4063 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4064 return RETURN_OK;
4065}
4066
4067
4068INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
4069{
4070 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4071 CHAR buf[MAX_CMD_SIZE] = {0};
4072 CHAR Value[MAX_BUF_SIZE] = {0};
4073 FILE *fp = NULL;
4074
4075 if (ifname == NULL || strlen(ifname) <= 1)
4076 return RETURN_OK;
4077
4078 snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
4079 system(buf);
4080
4081 fp = fopen("/tmp/Radio_Stats.txt", "r");
4082 if(fp == NULL)
4083 {
4084 printf("/tmp/Radio_Stats.txt not exists \n");
4085 return RETURN_ERR;
4086 }
4087 fclose(fp);
4088
4089 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4090 File_Reading(buf, Value);
4091 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
4092
4093 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4094 File_Reading(buf, Value);
4095 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
4096
4097 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4098 File_Reading(buf, Value);
4099 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
4100
4101 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4102 File_Reading(buf, Value);
4103 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
4104
4105 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4106 File_Reading(buf, Value);
4107 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
4108
4109 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4110 File_Reading(buf, Value);
4111 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
4112
4113 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4114 File_Reading(buf, Value);
4115 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
4116
4117 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4118 File_Reading(buf, Value);
4119 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
4120
4121 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4122 return RETURN_OK;
4123}
4124
4125INT GetIfacestatus(CHAR *interface_name, CHAR *status)
4126{
developer7e4a2a62023-04-06 19:56:03 +08004127 CHAR buf[MAX_CMD_SIZE] = {0};
4128 INT count = 0;
developer72fb0bb2023-01-11 09:46:29 +08004129
developer7e4a2a62023-04-06 19:56:03 +08004130 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4131
4132 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
4133 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
4134 File_Reading(buf, status);
4135 }
4136
4137 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4138 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004139}
4140
4141//Get detail radio traffic static info
4142INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
4143{
4144
developer69b61b02023-03-07 17:17:44 +08004145#if 0
4146 //ifconfig radio_x
developer72fb0bb2023-01-11 09:46:29 +08004147 output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters.
4148 output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters.
4149 output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface.
4150 output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface.
4151
4152 output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors.
4153 output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
4154 output_struct->radio_DiscardPacketsSent=0; //The total number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space.
4155 output_struct->radio_DiscardPacketsReceived=0; //The total number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being delivered. One possible reason for discarding such a packet could be to free up buffer space.
4156
developer69b61b02023-03-07 17:17:44 +08004157 output_struct->radio_PLCPErrorCount=0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
developer72fb0bb2023-01-11 09:46:29 +08004158 output_struct->radio_FCSErrorCount=0; //The number of packets that were received with a detected FCS error. This parameter is based on dot11FCSErrorCount from [Annex C/802.11-2012].
4159 output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error.
4160 output_struct->radio_PacketsOtherReceived=0; //The number of packets that were received, but which were destined for a MAC address that is not associated with this interface.
4161 output_struct->radio_NoiseFloor=-99; //The noise floor for this radio channel where a recoverable signal can be obtained. Expressed as a signed integer in the range (-110:0). Measurement should capture all energy (in dBm) from sources other than Wi-Fi devices as well as interference from Wi-Fi devices too weak to be decoded. Measured in dBm
4162 output_struct->radio_ChannelUtilization=35; //Percentage of time the channel was occupied by the radios own activity (Activity Factor) or the activity of other radios. Channel utilization MUST cover all user traffic, management traffic, and time the radio was unavailable for CSMA activities, including DIFS intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage
4163 output_struct->radio_ActivityFactor=2; //Percentage of time that the radio was transmitting or receiving Wi-Fi packets to/from associated clients. Activity factor MUST include all traffic that deals with communication between the radio and clients associated to the radio as well as management overhead for the radio, including NAV timers, beacons, probe responses,time for receiving devices to send an ACK, SIFC intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage
4164 output_struct->radio_CarrierSenseThreshold_Exceeded=20; //Percentage of time that the radio was unable to transmit or receive Wi-Fi packets to/from associated clients due to energy detection (ED) on the channel or clear channel assessment (CCA). The metric is calculated and updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage
4165 output_struct->radio_RetransmissionMetirc=0; //Percentage of packets that had to be re-transmitted. Multiple re-transmissions of the same packet count as one. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in percentage
4166
4167 output_struct->radio_MaximumNoiseFloorOnChannel=-1; //Maximum Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm
4168 output_struct->radio_MinimumNoiseFloorOnChannel=-1; //Minimum Noise on the channel. The metric is updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm
4169 output_struct->radio_MedianNoiseFloorOnChannel=-1; //Median Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm
4170 output_struct->radio_StatisticsStartTime=0; //The date and time at which the collection of the current set of statistics started. This time must be updated whenever the radio statistics are reset.
4171
4172 return RETURN_OK;
4173#endif
4174
4175 CHAR interface_name[64] = {0};
4176 BOOL iface_status = FALSE;
4177 wifi_radioTrafficStats2_t radioTrafficStats = {0};
4178
4179 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4180 if (NULL == output_struct)
4181 return RETURN_ERR;
4182
4183 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4184 return RETURN_ERR;
4185
4186 wifi_getApEnable(radioIndex, &iface_status);
4187
4188 if (iface_status == TRUE)
4189 wifi_halGetIfStats(interface_name, &radioTrafficStats);
4190 else
4191 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
4192
4193 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
4194 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
4195 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
4196 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
4197 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
4198 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
4199 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
4200 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
4201
4202 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
4203 output_struct->radio_FCSErrorCount = 0; //The number of packets that were received with a detected FCS error. This parameter is based on dot11FCSErrorCount from [Annex C/802.11-2012].
4204 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
4205 output_struct->radio_PacketsOtherReceived = 0; //The number of packets that were received, but which were destined for a MAC address that is not associated with this interface.
4206 output_struct->radio_NoiseFloor = -99; //The noise floor for this radio channel where a recoverable signal can be obtained. Expressed as a signed integer in the range (-110:0). Measurement should capture all energy (in dBm) from sources other than Wi-Fi devices as well as interference from Wi-Fi devices too weak to be decoded. Measured in dBm
4207 output_struct->radio_ChannelUtilization = 35; //Percentage of time the channel was occupied by the radio\92s own activity (Activity Factor) or the activity of other radios. Channel utilization MUST cover all user traffic, management traffic, and time the radio was unavailable for CSMA activities, including DIFS intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage
4208 output_struct->radio_ActivityFactor = 2; //Percentage of time that the radio was transmitting or receiving Wi-Fi packets to/from associated clients. Activity factor MUST include all traffic that deals with communication between the radio and clients associated to the radio as well as management overhead for the radio, including NAV timers, beacons, probe responses,time for receiving devices to send an ACK, SIFC intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage
4209 output_struct->radio_CarrierSenseThreshold_Exceeded = 20; //Percentage of time that the radio was unable to transmit or receive Wi-Fi packets to/from associated clients due to energy detection (ED) on the channel or clear channel assessment (CCA). The metric is calculated and updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage
4210 output_struct->radio_RetransmissionMetirc = 0; //Percentage of packets that had to be re-transmitted. Multiple re-transmissions of the same packet count as one. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in percentage
4211
4212 output_struct->radio_MaximumNoiseFloorOnChannel = -1; //Maximum Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm
4213 output_struct->radio_MinimumNoiseFloorOnChannel = -1; //Minimum Noise on the channel. The metric is updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm
4214 output_struct->radio_MedianNoiseFloorOnChannel = -1; //Median Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm
4215 output_struct->radio_StatisticsStartTime = 0; //The date and time at which the collection of the current set of statistics started. This time must be updated whenever the radio statistics are reset.
4216
4217 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4218
4219 return RETURN_OK;
4220}
4221
4222//Set radio traffic static Measureing rules
4223INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
4224{
4225 //zqiu: If the RadioTrafficStats process running, and the new value is different from old value, the process needs to be reset. The Statistics date, such as MaximumNoiseFloorOnChannel, MinimumNoiseFloorOnChannel and MedianNoiseFloorOnChannel need to be reset. And the "StatisticsStartTime" must be reset to the current time. Units in Seconds
4226 // Else, save the MeasuringRate and MeasuringInterval for future usage
4227
4228 return RETURN_OK;
4229}
4230
4231//To start or stop RadioTrafficStats
4232INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
4233{
4234 //zqiu: If the RadioTrafficStats process running
4235 // if(enable)
4236 // return RETURN_OK.
4237 // else
4238 // Stop RadioTrafficStats process
developer69b61b02023-03-07 17:17:44 +08004239 // Else
developer72fb0bb2023-01-11 09:46:29 +08004240 // if(enable)
4241 // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds
4242 // else
4243 // return RETURN_OK.
4244
4245 return RETURN_OK;
4246}
4247
4248//Clients associated with the AP over a specific interval. The histogram MUST have a range from -110to 0 dBm and MUST be divided in bins of 3 dBM, with bins aligning on the -110 dBm end of the range. Received signal levels equal to or greater than the smaller boundary of a bin and less than the larger boundary are included in the respective bin. The bin associated with the client?s current received signal level MUST be incremented when a client associates with the AP. Additionally, the respective bins associated with each connected client?s current received signal level MUST be incremented at the interval defined by "Radio Statistics Measuring Rate". The histogram?s bins MUST NOT be incremented at any other time. The histogram data collected during the interval MUST be published to the parameter only at the end of the interval defined by "Radio Statistics Measuring Interval". The underlying histogram data MUST be cleared at the start of each interval defined by "Radio Statistics Measuring Interval?. If any of the parameter's representing this histogram is queried before the histogram has been updated with an initial set of data, it MUST return -1. Units dBm
4249INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
4250{
4251 //zqiu: Please ignor signalIndex.
developer69b61b02023-03-07 17:17:44 +08004252 if (NULL == SignalLevel)
developer72fb0bb2023-01-11 09:46:29 +08004253 return RETURN_ERR;
4254 *SignalLevel=(radioIndex==0)?-19:-19;
4255
4256 return RETURN_OK;
4257}
4258
4259//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
4260INT wifi_applyRadioSettings(INT radioIndex)
4261{
4262 return RETURN_OK;
4263}
4264
4265//Get the radio index assocated with this SSID entry
4266INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
4267{
4268 if(NULL == radioIndex)
4269 return RETURN_ERR;
4270 int max_radio_num = 0;
4271 wifi_getMaxRadioNumber(&max_radio_num);
4272 *radioIndex = ssidIndex%max_radio_num;
4273 return RETURN_OK;
4274}
4275
4276//Device.WiFi.SSID.{i}.Enable
4277//Get SSID enable configuration parameters (not the SSID enable status)
4278INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
4279{
developer69b61b02023-03-07 17:17:44 +08004280 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08004281 return RETURN_ERR;
4282
4283 return wifi_getApEnable(ssidIndex, output_bool);
4284}
4285
4286//Device.WiFi.SSID.{i}.Enable
4287//Set SSID enable configuration parameters
4288INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
4289{
4290 return wifi_setApEnable(ssidIndex, enable);
4291}
4292
4293//Device.WiFi.SSID.{i}.Status
4294//Get the SSID enable status
4295INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
4296{
4297 char cmd[MAX_CMD_SIZE]={0};
4298 char buf[MAX_BUF_SIZE]={0};
4299 BOOL output_bool;
4300
4301 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4302 if (NULL == output_string)
4303 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08004304
developer72fb0bb2023-01-11 09:46:29 +08004305 wifi_getApEnable(ssidIndex,&output_bool);
4306 snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
4307
4308 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4309 return RETURN_OK;
4310}
4311
4312// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
4313INT wifi_getSSIDName(INT apIndex, CHAR *output)
4314{
4315 char config_file[MAX_BUF_SIZE] = {0};
4316
developer69b61b02023-03-07 17:17:44 +08004317 if (NULL == output)
developer72fb0bb2023-01-11 09:46:29 +08004318 return RETURN_ERR;
4319
4320 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4321 wifi_hostapdRead(config_file,"ssid",output,32);
4322
4323 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
4324 return RETURN_OK;
4325}
4326
developer69b61b02023-03-07 17:17:44 +08004327// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08004328INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
4329{
4330 char str[MAX_BUF_SIZE]={'\0'};
4331 char cmd[MAX_CMD_SIZE]={'\0'};
4332 struct params params;
4333 char config_file[MAX_BUF_SIZE] = {0};
4334
4335 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4336 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
4337 return RETURN_ERR;
4338
4339 params.name = "ssid";
4340 params.value = ssid_string;
4341 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4342 wifi_hostapdWrite(config_file, &params, 1);
4343 wifi_hostapdProcessUpdate(apIndex, &params, 1);
4344 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4345
4346 return RETURN_OK;
4347}
4348
4349//Get the BSSID
4350INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
4351{
developer7e4a2a62023-04-06 19:56:03 +08004352 char cmd[MAX_CMD_SIZE] = {0};
4353 char inf_name[IF_NAME_SIZE] = {0};
4354 char conf_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004355
developer7e4a2a62023-04-06 19:56:03 +08004356 if (!output_string)
developer72fb0bb2023-01-11 09:46:29 +08004357 return RETURN_ERR;
4358
developer7e4a2a62023-04-06 19:56:03 +08004359 wifi_GetInterfaceName(ssidIndex, inf_name);
4360
4361 if(ssidIndex >= 0 && ssidIndex < MAX_APS) {
4362 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
developer72fb0bb2023-01-11 09:46:29 +08004363 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08004364 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004365 }
developer7e4a2a62023-04-06 19:56:03 +08004366
developer72fb0bb2023-01-11 09:46:29 +08004367 strncpy(output_string, "\0", 1);
4368
4369 return RETURN_ERR;
4370}
4371
4372//Get the MAC address associated with this Wifi SSID
4373INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
4374{
4375 wifi_getBaseBSSID(ssidIndex,output_string);
4376 return RETURN_OK;
4377}
4378
4379//Get the basic SSID traffic static info
4380//Apply SSID and AP (in the case of Acess Point devices) to the hardware
4381//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
4382INT wifi_applySSIDSettings(INT ssidIndex)
4383{
4384 char interface_name[16] = {0};
4385 BOOL status = false;
4386 char cmd[MAX_CMD_SIZE] = {0};
4387 char buf[MAX_CMD_SIZE] = {0};
4388 int apIndex, ret;
4389 int max_radio_num = 0;
4390 int radioIndex = 0;
4391
4392 wifi_getMaxRadioNumber(&max_radio_num);
4393
4394 radioIndex = ssidIndex % max_radio_num;
4395
4396 wifi_getApEnable(ssidIndex,&status);
4397 // Do not apply when ssid index is disabled
4398 if (status == false)
4399 return RETURN_OK;
4400
4401 /* Doing full remove and add for ssid Index
4402 * Not all hostapd options are supported with reload
4403 * for example macaddr_acl
4404 */
4405 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
4406 return RETURN_ERR;
4407
4408 ret = wifi_setApEnable(ssidIndex,true);
4409
4410 /* Workaround for hostapd issue with multiple bss definitions
4411 * when first created interface will be removed
4412 * then all vaps other vaps on same phy are removed
4413 * after calling setApEnable to false readd all enabled vaps */
4414 for(int i=0; i < MAX_APS/max_radio_num; i++) {
4415 apIndex = max_radio_num*i+radioIndex;
4416 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
4417 return RETURN_ERR;
4418 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
4419 _syscmd(cmd, buf, sizeof(buf));
4420 if(*buf == '1')
4421 wifi_setApEnable(apIndex, true);
4422 }
4423
4424 return ret;
4425}
4426
4427struct channels_noise {
4428 int channel;
4429 int noise;
4430};
4431
4432// Return noise array for each channel
4433int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
4434{
4435 char interface_name[16] = {0};
4436 FILE *f = NULL;
4437 char cmd[128] = {0};
4438 char line[256] = {0};
4439 size_t len = 0;
4440 ssize_t read = 0;
4441 int tmp = 0, arr_index = -1;
4442
4443 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4444 return RETURN_ERR;
4445 sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
4446
4447 if ((f = popen(cmd, "r")) == NULL) {
4448 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
4449 return RETURN_ERR;
4450 }
developer69b61b02023-03-07 17:17:44 +08004451
developer72fb0bb2023-01-11 09:46:29 +08004452 while(fgets(line, sizeof(line), f) != NULL) {
4453 if(arr_index < channels_num){
4454 sscanf(line, "%d", &tmp);
4455 if (tmp > 0) { // channel frequency, the first line must be frequency
4456 arr_index++;
4457 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
4458 } else { // noise
4459 channels_noise_arr[arr_index].noise = tmp;
4460 }
4461 }else{
4462 break;
4463 }
4464 }
4465 pclose(f);
4466 return RETURN_OK;
4467}
4468
4469//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
4470//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08004471INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08004472{
4473 int index = -1;
4474 wifi_neighbor_ap2_t *scan_array = NULL;
4475 char cmd[256]={0};
4476 char buf[128]={0};
4477 char file_name[32] = {0};
4478 char filter_SSID[32] = {0};
4479 char line[256] = {0};
4480 char interface_name[16] = {0};
4481 char *ret = NULL;
4482 int freq=0;
4483 FILE *f = NULL;
4484 size_t len=0;
4485 int channels_num = 0;
4486 int vht_channel_width = 0;
4487 int get_noise_ret = RETURN_ERR;
4488 bool filter_enable = false;
4489 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
4490 int phyId = 0;
4491
4492 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
4493
4494 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4495 return RETURN_ERR;
4496
4497 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
4498 f = fopen(file_name, "r");
4499 if (f != NULL) {
4500 fgets(filter_SSID, sizeof(file_name), f);
4501 if (strlen(filter_SSID) != 0)
4502 filter_enable = true;
4503 fclose(f);
4504 }
4505
4506 phyId = radio_index_to_phy(radioIndex);
4507 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
4508 _syscmd(cmd, buf, sizeof(buf));
4509 channels_num = strtol(buf, NULL, 10);
4510
4511
4512
4513 sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
4514 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
4515 fprintf(stderr, "cmd: %s\n", cmd);
4516 if ((f = popen(cmd, "r")) == NULL) {
4517 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
4518 return RETURN_ERR;
4519 }
developer69b61b02023-03-07 17:17:44 +08004520
developer72fb0bb2023-01-11 09:46:29 +08004521 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
4522 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08004523
developer72fb0bb2023-01-11 09:46:29 +08004524 ret = fgets(line, sizeof(line), f);
4525 while (ret != NULL) {
4526 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +08004527 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
developer72fb0bb2023-01-11 09:46:29 +08004528 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
4529 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
4530
4531 if (!filter_BSS) {
4532 index++;
4533 wifi_neighbor_ap2_t *tmp;
4534 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
4535 if (tmp == NULL) { // no more memory to use
4536 index--;
4537 wifi_dbg_printf("%s: realloc failed\n", __func__);
4538 break;
4539 }
4540 scan_array = tmp;
4541 }
4542 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
4543
4544 filter_BSS = false;
4545 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
4546 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
4547 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
4548 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
4549 } else if (strstr(line, "freq") != NULL) {
4550 sscanf(line," freq: %d", &freq);
4551 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
4552
4553 if (freq >= 2412 && freq <= 2484) {
4554 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
4555 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
4556 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
4557 }
4558 else if (freq >= 5160 && freq <= 5805) {
4559 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
4560 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
4561 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
4562 }
4563
4564 scan_array[index].ap_Noise = 0;
4565 if (get_noise_ret == RETURN_OK) {
4566 for (int i = 0; i < channels_num; i++) {
4567 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
4568 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
4569 break;
4570 }
4571 }
4572 }
4573 } else if (strstr(line, "beacon interval") != NULL) {
4574 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
4575 } else if (strstr(line, "signal") != NULL) {
4576 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
4577 } else if (strstr(line,"SSID") != NULL) {
4578 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
4579 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
4580 filter_BSS = true;
4581 }
4582 } else if (strstr(line, "Supported rates") != NULL) {
4583 char SRate[80] = {0}, *tmp = NULL;
4584 memset(buf, 0, sizeof(buf));
4585 strcpy(SRate, line);
4586 tmp = strtok(SRate, ":");
4587 tmp = strtok(NULL, ":");
4588 strcpy(buf, tmp);
4589 memset(SRate, 0, sizeof(SRate));
4590
4591 tmp = strtok(buf, " \n");
4592 while (tmp != NULL) {
4593 strcat(SRate, tmp);
4594 if (SRate[strlen(SRate) - 1] == '*') {
4595 SRate[strlen(SRate) - 1] = '\0';
4596 }
4597 strcat(SRate, ",");
4598
4599 tmp = strtok(NULL, " \n");
4600 }
4601 SRate[strlen(SRate) - 1] = '\0';
4602 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
4603 } else if (strstr(line, "DTIM") != NULL) {
4604 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
4605 } else if (strstr(line, "VHT capabilities") != NULL) {
4606 strcat(scan_array[index].ap_SupportedStandards, ",ac");
4607 strcpy(scan_array[index].ap_OperatingStandards, "ac");
4608 } else if (strstr(line, "HT capabilities") != NULL) {
4609 strcat(scan_array[index].ap_SupportedStandards, ",n");
4610 strcpy(scan_array[index].ap_OperatingStandards, "n");
4611 } else if (strstr(line, "VHT operation") != NULL) {
4612 ret = fgets(line, sizeof(line), f);
4613 sscanf(line," * channel width: %d", &vht_channel_width);
4614 if(vht_channel_width == 1) {
4615 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
4616 } else {
4617 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
4618 }
4619 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
4620 continue;
4621 } else if (strstr(line, "HT operation") != NULL) {
4622 ret = fgets(line, sizeof(line), f);
4623 sscanf(line," * secondary channel offset: %s", &buf);
4624 if (!strcmp(buf, "above")) {
4625 //40Mhz +
4626 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
4627 }
4628 else if (!strcmp(buf, "below")) {
4629 //40Mhz -
4630 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
4631 } else {
4632 //20Mhz
4633 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
4634 }
4635 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
4636 continue;
4637 } else if (strstr(line, "HE capabilities") != NULL) {
4638 strcat(scan_array[index].ap_SupportedStandards, ",ax");
4639 strcpy(scan_array[index].ap_OperatingStandards, "ax");
4640 ret = fgets(line, sizeof(line), f);
4641 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
4642 if (strstr(line, "HE40/2.4GHz") != NULL)
4643 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
4644 else
4645 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
4646 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
4647 if (strstr(line, "HE80/5GHz") != NULL) {
4648 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
4649 ret = fgets(line, sizeof(line), f);
4650 } else
4651 continue;
4652 if (strstr(line, "HE160/5GHz") != NULL)
4653 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
4654 }
4655 continue;
4656 } else if (strstr(line, "WPA") != NULL) {
4657 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
4658 } else if (strstr(line, "RSN") != NULL) {
4659 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
4660 } else if (strstr(line, "Group cipher") != NULL) {
4661 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
4662 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
4663 strcpy(scan_array[index].ap_EncryptionMode, "AES");
4664 }
4665 }
4666 ret = fgets(line, sizeof(line), f);
4667 }
4668
4669 if (!filter_BSS) {
4670 *output_array_size = index + 1;
4671 } else {
4672 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
4673 *output_array_size = index;
4674 }
4675 *neighbor_ap_array = scan_array;
4676 pclose(f);
4677 free(channels_noise_arr);
4678 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4679 return RETURN_OK;
4680}
4681
4682//>> Deprecated: used for old RDKB code.
4683INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
4684{
4685 INT status = RETURN_ERR;
4686
4687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4688 output_struct->wifi_PLCPErrorCount = 0;
4689 output_struct->wifi_FCSErrorCount = 0;
4690 output_struct->wifi_InvalidMACCount = 0;
4691 output_struct->wifi_PacketsOtherReceived = 0;
4692 output_struct->wifi_Noise = 0;
4693 status = RETURN_OK;
4694 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4695 return status;
4696}
4697
4698INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
4699{
4700 char interface_name[16] = {0};
4701 char cmd[128] = {0};
4702 char buf[1280] = {0};
4703 char *pos = NULL;
4704
4705 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4706 if (NULL == output_struct)
4707 return RETURN_ERR;
4708
4709 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
4710 return RETURN_ERR;
4711
4712 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
4713
4714 snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
4715 _syscmd(cmd, buf, sizeof(buf));
4716
4717 pos = buf;
4718 if ((pos = strstr(pos, "RX packets:")) == NULL)
4719 return RETURN_ERR;
4720 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
4721
4722 if ((pos = strstr(pos, "TX packets:")) == NULL)
4723 return RETURN_ERR;
4724 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
4725
4726 if ((pos = strstr(pos, "RX bytes:")) == NULL)
4727 return RETURN_ERR;
4728 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
4729
4730 if ((pos = strstr(pos, "TX bytes:")) == NULL)
4731 return RETURN_ERR;
4732 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
4733
4734 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
4735 _syscmd(cmd, buf, sizeof(buf));
4736 sscanf(buf, "%lu", &output_struct->wifi_Associations);
4737
4738#if 0
4739 //TODO: need to revisit below implementation
4740 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4741 char interface_name[MAX_BUF_SIZE] = {0};
4742 char interface_status[MAX_BUF_SIZE] = {0};
4743 char Value[MAX_BUF_SIZE] = {0};
4744 char buf[MAX_CMD_SIZE] = {0};
4745 char cmd[MAX_CMD_SIZE] = {0};
4746 FILE *fp = NULL;
4747
4748 if (NULL == output_struct) {
4749 return RETURN_ERR;
4750 }
4751
4752 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
4753
4754 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
4755 {
4756 if(apIndex == 0) //private_wifi for 2.4G
4757 {
4758 wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
4759 }
4760 else if(apIndex == 1) //private_wifi for 5G
4761 {
4762 wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
4763 }
4764 else if(apIndex == 4) //public_wifi for 2.4G
4765 {
4766 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
4767 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
4768 {
4769 return RETURN_ERR;
4770 }
4771 if(buf[0] == '#')//tp-link
4772 wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
4773 else//tenda
4774 wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name);
4775 }
4776 else if(apIndex == 5) //public_wifi for 5G
4777 {
4778 wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
4779 }
4780
4781 GetIfacestatus(interface_name, interface_status);
4782
4783 if(0 != strcmp(interface_status, "1"))
4784 return RETURN_ERR;
4785
4786 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
4787 system(cmd);
4788
4789 fp = fopen("/tmp/SSID_Stats.txt", "r");
4790 if(fp == NULL)
4791 {
4792 printf("/tmp/SSID_Stats.txt not exists \n");
4793 return RETURN_ERR;
4794 }
4795 fclose(fp);
4796
4797 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4798 File_Reading(buf, Value);
4799 output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10);
4800
4801 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4802 File_Reading(buf, Value);
4803 output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10);
4804
4805 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4806 File_Reading(buf, Value);
4807 output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10);
4808
4809 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4810 File_Reading(buf, Value);
4811 output_struct->wifi_BytesSent = strtoul(Value, NULL, 10);
4812
4813 /* There is no specific parameter from caller to associate the value wifi_Associations */
4814 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);
4815 //_syscmd(cmd, buf, sizeof(buf));
4816 //sscanf(buf,"%lu", &output_struct->wifi_Associations);
4817 }
4818#endif
4819 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4820 return RETURN_OK;
4821}
4822
4823INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
4824{
4825 char interface_name[MAX_BUF_SIZE] = {0};
4826 char interface_status[MAX_BUF_SIZE] = {0};
4827 char Value[MAX_BUF_SIZE] = {0};
4828 char buf[MAX_CMD_SIZE] = {0};
4829 char cmd[MAX_CMD_SIZE] = {0};
4830 FILE *fp = NULL;
4831
4832 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4833 if (NULL == output_struct)
4834 return RETURN_ERR;
4835
4836 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
4837
4838 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
4839 return RETURN_ERR;
4840 GetIfacestatus(interface_name, interface_status);
4841
4842 if(0 != strcmp(interface_status, "1"))
4843 return RETURN_ERR;
4844
4845 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
4846 system(cmd);
4847
4848 fp = fopen("/tmp/SSID_Stats.txt", "r");
4849 if(fp == NULL)
4850 {
4851 printf("/tmp/SSID_Stats.txt not exists \n");
4852 return RETURN_ERR;
4853 }
4854 fclose(fp);
4855
4856 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4857 File_Reading(buf, Value);
4858 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
4859
4860 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4861 File_Reading(buf, Value);
4862 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
4863
4864 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4865 File_Reading(buf, Value);
4866 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
4867
4868 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4869 File_Reading(buf, Value);
4870 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
4871
4872 output_struct->wifi_UnicastPacketsSent = 0;
4873 output_struct->wifi_UnicastPacketsReceived = 0;
4874 output_struct->wifi_MulticastPacketsSent = 0;
4875 output_struct->wifi_MulticastPacketsReceived = 0;
4876 output_struct->wifi_BroadcastPacketsSent = 0;
4877 output_struct->wifi_BroadcastPacketsRecevied = 0;
4878 output_struct->wifi_UnknownPacketsReceived = 0;
4879
4880 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4881 return RETURN_OK;
4882}
4883
4884INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
4885{
4886 INT status = RETURN_ERR;
4887
4888 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4889 //Below values should get updated from hal
4890 output_struct->wifi_RetransCount=0;
4891 output_struct->wifi_FailedRetransCount=0;
4892 output_struct->wifi_RetryCount=0;
4893 output_struct->wifi_MultipleRetryCount=0;
4894 output_struct->wifi_ACKFailureCount=0;
4895 output_struct->wifi_AggregatedPacketCount=0;
4896
4897 status = RETURN_OK;
4898 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4899
4900 return status;
4901}
4902
4903INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
4904{
4905 INT status = RETURN_ERR;
4906 UINT index;
4907 wifi_neighbor_ap_t *pt=NULL;
4908
4909 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4910 *output_array_size=2;
4911 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
4912 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
4913 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
4914 strcpy(pt->ap_Radio,"");
4915 strcpy(pt->ap_SSID,"");
4916 strcpy(pt->ap_BSSID,"");
4917 strcpy(pt->ap_Mode,"");
4918 pt->ap_Channel=1;
4919 pt->ap_SignalStrength=0;
4920 strcpy(pt->ap_SecurityModeEnabled,"");
4921 strcpy(pt->ap_EncryptionMode,"");
4922 strcpy(pt->ap_OperatingFrequencyBand,"");
4923 strcpy(pt->ap_SupportedStandards,"");
4924 strcpy(pt->ap_OperatingStandards,"");
4925 strcpy(pt->ap_OperatingChannelBandwidth,"");
4926 pt->ap_BeaconPeriod=1;
4927 pt->ap_Noise=0;
4928 strcpy(pt->ap_BasicDataTransferRates,"");
4929 strcpy(pt->ap_SupportedDataTransferRates,"");
4930 pt->ap_DTIMPeriod=1;
4931 pt->ap_ChannelUtilization = 1;
4932 }
4933
4934 status = RETURN_OK;
4935 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4936
4937 return status;
4938}
4939
4940//----------------- AP HAL -------------------------------
4941
4942//>> Deprecated: used for old RDKB code.
4943INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
4944{
4945 if (NULL == output_ulong || NULL == output_struct)
4946 return RETURN_ERR;
4947 *output_ulong = 0;
4948 *output_struct = NULL;
4949 return RETURN_OK;
4950}
4951
4952#ifdef HAL_NETLINK_IMPL
4953static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
4954 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4955 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4956 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
4957 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
4958 char mac_addr[20];
4959 static int count=0;
4960 int rate=0;
4961
4962 wifi_device_info_t *out = (wifi_device_info_t*)arg;
4963
4964 nla_parse(tb,
4965 NL80211_ATTR_MAX,
4966 genlmsg_attrdata(gnlh, 0),
4967 genlmsg_attrlen(gnlh, 0),
4968 NULL);
4969
4970 if(!tb[NL80211_ATTR_STA_INFO]) {
4971 fprintf(stderr, "sta stats missing!\n");
4972 return NL_SKIP;
4973 }
4974
4975
4976 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
4977 fprintf(stderr, "failed to parse nested attributes!\n");
4978 return NL_SKIP;
4979 }
4980
4981 //devIndex starts from 1
4982 if( ++count == out->wifi_devIndex )
4983 {
4984 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
4985 //Getting the mac addrress
4986 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
4987
4988 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
4989 fprintf(stderr, "failed to parse nested rate attributes!");
4990 return NL_SKIP;
4991 }
4992
4993 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
4994 if(rinfo[NL80211_RATE_INFO_BITRATE])
4995 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
4996 out->wifi_devTxRate = rate/10;
4997 }
4998
4999 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
5000 fprintf(stderr, "failed to parse nested rate attributes!");
5001 return NL_SKIP;
5002 }
5003
5004 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
5005 if(rinfo[NL80211_RATE_INFO_BITRATE])
5006 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5007 out->wifi_devRxRate = rate/10;
5008 }
5009 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
5010 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
5011
5012 out->wifi_devAssociatedDeviceAuthentiationState = 1;
5013 count = 0; //starts the count for next cycle
5014 return NL_STOP;
5015 }
5016
5017 return NL_SKIP;
5018
5019}
5020#endif
5021
5022INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
5023{
5024#ifdef HAL_NETLINK_IMPL
5025 Netlink nl = {0};
5026 char if_name[10] = {0};
5027 char interface_name[16] = {0};
5028
5029 wifi_device_info_t info = {0};
5030 info.wifi_devIndex = devIndex;
5031
5032 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5033 return RETURN_ERR;
5034
5035 snprintf(if_name,sizeof(if_name),"%s", interface_name);
5036
5037 nl.id = initSock80211(&nl);
5038
5039 if (nl.id < 0) {
5040 fprintf(stderr, "Error initializing netlink \n");
5041 return -1;
5042 }
5043
5044 struct nl_msg* msg = nlmsg_alloc();
5045
5046 if (!msg) {
5047 fprintf(stderr, "Failed to allocate netlink message.\n");
5048 nlfree(&nl);
5049 return -2;
5050 }
5051
5052 genlmsg_put(msg,
5053 NL_AUTO_PORT,
5054 NL_AUTO_SEQ,
5055 nl.id,
5056 0,
5057 NLM_F_DUMP,
5058 NL80211_CMD_GET_STATION,
5059 0);
5060
5061 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
5062 nl_send_auto(nl.socket, msg);
5063 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
5064 nl_recvmsgs(nl.socket, nl.cb);
5065 nlmsg_free(msg);
5066 nlfree(&nl);
5067
5068 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
5069 output_struct->wifi_devRxRate = info.wifi_devRxRate;
5070 output_struct->wifi_devTxRate = info.wifi_devTxRate;
5071 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
5072 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
5073 return RETURN_OK;
5074#else
5075 //iw utility to retrieve station information
5076#define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt"
5077#define SIGNALFILE "/tmp/wifi_signalstrength.txt"
5078#define MACFILE "/tmp/wifi_AssoMac.txt"
5079#define TXRATEFILE "/tmp/wifi_txrate.txt"
5080#define RXRATEFILE "/tmp/wifi_rxrate.txt"
5081 FILE *file = NULL;
5082 char if_name[10] = {'\0'};
5083 char pipeCmd[256] = {'\0'};
5084 char line[256] = {0};
5085 char interface_name[16] = {0};
5086 int count = 0, device = 0;
5087
5088 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5089 return RETURN_ERR;
5090
5091 snprintf(if_name,sizeof(if_name),"%s", interface_name);
5092
5093 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name);
5094 file = popen(pipeCmd, "r");
5095
5096 if(file == NULL)
5097 return RETURN_ERR; //popen failed
5098
5099 fgets(line, sizeof line, file);
5100 device = atoi(line);
5101 pclose(file);
5102
5103 if(device == 0)
5104 return RETURN_ERR; //No devices are connected
5105
5106 sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name);
5107 system(pipeCmd);
5108
5109 system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE);
5110
5111 system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE);
5112
5113 system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE);
5114
5115 system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE);
5116
5117 //devIndex starts from 1, ++count
5118 if((file = fopen(SIGNALFILE, "r")) != NULL )
5119 {
5120 for(count =0;fgets(line, sizeof line, file) != NULL;)
5121 {
5122 if (++count == devIndex)
5123 {
5124 output_struct->wifi_devSignalStrength = atoi(line);
5125 break;
5126 }
5127 }
5128 fclose(file);
5129 }
5130 else
5131 fprintf(stderr,"fopen wifi_signalstrength.txt failed");
5132
5133 if((file = fopen(MACFILE, "r")) != NULL )
5134 {
5135 for(count =0;fgets(line, sizeof line, file) != NULL;)
5136 {
5137 if (++count == devIndex)
5138 {
5139 sscanf(line, "%02x:%02x:%02x:%02x:%02x:%02x",&output_struct->wifi_devMacAddress[0],&output_struct->wifi_devMacAddress[1],&output_struct->wifi_devMacAddress[2],&output_struct->wifi_devMacAddress[3],&output_struct->wifi_devMacAddress[4],&output_struct->wifi_devMacAddress[5]);
5140 break;
5141 }
5142 }
5143 fclose(file);
5144 }
5145 else
5146 fprintf(stderr,"fopen wifi_AssoMac.txt failed");
5147
5148 if((file = fopen(TXRATEFILE, "r")) != NULL )
5149 {
5150 for(count =0;fgets(line, sizeof line, file) != NULL;)
5151 {
5152 if (++count == devIndex)
5153 {
5154 output_struct->wifi_devTxRate = atoi(line);
5155 break;
5156 }
5157 }
5158 fclose(file);
5159 }
5160 else
5161 fprintf(stderr,"fopen wifi_txrate.txt failed");
5162
5163 if((file = fopen(RXRATEFILE, "r")) != NULL)
5164 {
5165 for(count =0;fgets(line, sizeof line, file) != NULL;)
5166 {
5167 if (++count == devIndex)
5168 {
5169 output_struct->wifi_devRxRate = atoi(line);
5170 break;
5171 }
5172 }
5173 fclose(file);
5174 }
5175 else
5176 fprintf(stderr,"fopen wifi_rxrate.txt failed");
5177
5178 output_struct->wifi_devAssociatedDeviceAuthentiationState = 1;
5179
5180 return RETURN_OK;
5181#endif
5182}
5183
5184INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
5185{
5186 if (NULL == device)
5187 return RETURN_ERR;
5188 return RETURN_OK;
5189}
5190//<<
5191
5192
5193//--------------wifi_ap_hal-----------------------------
5194//enables CTS protection for the radio used by this AP
5195INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
5196{
5197 //save config and Apply instantly
5198 return RETURN_ERR;
5199}
5200
5201// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
5202INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
5203{
5204 char config_file[64] = {'\0'};
5205 char buf[64] = {'\0'};
5206 struct params list;
5207
5208 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5209 list.name = "ht_coex";
5210 snprintf(buf, sizeof(buf), "%d", enable);
5211 list.value = buf;
5212
5213 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5214 wifi_hostapdWrite(config_file, &list, 1);
5215 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5216
5217 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5218
5219 return RETURN_OK;
5220}
5221
5222//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
5223INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
5224{
5225 char config_file[MAX_BUF_SIZE] = {'\0'};
5226 char buf[MAX_BUF_SIZE] = {'\0'};
5227 struct params list;
5228
5229 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5230 if (threshold < 256 || threshold > 2346 )
5231 return RETURN_ERR;
5232 list.name = "fragm_threshold";
5233 snprintf(buf, sizeof(buf), "%d", threshold);
5234 list.value = buf;
5235
5236 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5237 wifi_hostapdWrite(config_file, &list, 1);
5238 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5239
5240 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5241
5242 return RETURN_OK;
5243}
5244
5245// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
5246INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
5247{
5248 char config_file[64] = {'\0'};
5249 char cmd[512] = {'\0'};
5250 char buf[512] = {'\0'};
5251 char stbc_config[16] = {'\0'};
5252 wifi_band band;
5253 int iterator = 0;
5254 BOOL current_stbc = FALSE;
5255 int ant_count = 0;
5256 int ant_bitmap = 0;
5257 struct params list;
developera1255e42023-05-13 17:45:02 +08005258 char dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08005259
5260 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5261
5262 band = wifi_index_to_band(radioIndex);
5263 if (band == band_invalid)
5264 return RETURN_ERR;
5265
5266 if (band == band_2_4)
5267 iterator = 1;
developera1255e42023-05-13 17:45:02 +08005268 else if ((band == band_5) || (band == band_6))
developer72fb0bb2023-01-11 09:46:29 +08005269 iterator = 2;
5270 else
5271 return RETURN_OK;
5272
5273 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
5274 for (; ant_bitmap > 0; ant_bitmap >>= 1)
5275 ant_count += ant_bitmap & 1;
5276
5277 if (ant_count == 1 && STBC_Enable == TRUE) {
5278 fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__);
5279 return RETURN_OK;
5280 }
5281
5282 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5283
5284 // set ht and vht config
5285 for (int i = 0; i < iterator; i++) {
5286 memset(stbc_config, 0, sizeof(stbc_config));
5287 memset(cmd, 0, sizeof(cmd));
5288 memset(buf, 0, sizeof(buf));
5289 list.name = (i == 0)?"ht_capab":"vht_capab";
5290 snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
5291 snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
5292 _syscmd(cmd, buf, sizeof(buf));
5293 if (strlen(buf) != 0)
5294 current_stbc = TRUE;
5295 if (current_stbc == STBC_Enable)
5296 continue;
5297
5298 if (STBC_Enable == TRUE) {
5299 // Append the STBC flags in capab config
5300 memset(cmd, 0, sizeof(cmd));
5301 if (i == 0)
5302 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
5303 else
5304 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
5305 _syscmd(cmd, buf, sizeof(buf));
5306 } else if (STBC_Enable == FALSE) {
5307 // Remove the STBC flags and remain other flags in capab
5308 memset(cmd, 0, sizeof(cmd));
5309 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
5310 _syscmd(cmd, buf, sizeof(buf));
5311 memset(cmd, 0, sizeof(cmd));
5312 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
5313 _syscmd(cmd, buf, sizeof(buf));
5314 }
5315 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
5316 list.value = buf;
5317 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
5318 }
developera1255e42023-05-13 17:45:02 +08005319 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5320 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
5321 _syscmd(cmd, buf, sizeof(buf));
5322 if ((band == band_5) || (band == band_6)) {
5323 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
5324 _syscmd(cmd, buf, sizeof(buf));
5325 }
5326 /*wifi_reloadAp(radioIndex);
5327 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08005328
5329 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5330 return RETURN_OK;
5331}
5332
5333// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
5334INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
5335{
5336 char cmd[128] = {0};
5337 char buf[128] = {0};
5338 char interface_name[16] = {0};
5339
5340 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5341
5342 if(output_bool == NULL)
5343 return RETURN_ERR;
5344
5345 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5346 return RETURN_ERR;
5347
5348 sprintf(cmd, "hostapd_cli -i %s get_amsdu | awk '{print $3}'", interface_name);
5349 _syscmd(cmd, buf, sizeof(buf));
5350
5351 if (strncmp(buf, "1", 1) == 0)
5352 *output_bool = TRUE;
5353 else
5354 *output_bool = FALSE;
5355
5356 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5357 return RETURN_OK;
5358}
5359
5360// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
5361INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
5362{
5363 char config_file[128] = {0};
5364 struct params list = {0};
5365 BOOL enable;
5366
5367 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5368
5369 if (wifi_getRadioAMSDUEnable(radioIndex, &enable) != RETURN_OK)
5370 return RETURN_ERR;
5371
5372 if (amsduEnable == enable)
5373 return RETURN_OK;
5374
5375 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5376 list.name = "amsdu";
5377 list.value = amsduEnable? "1":"0";
5378 wifi_hostapdWrite(config_file, &list, 1);
5379 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
5380 wifi_reloadAp(radioIndex);
5381
5382 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5383 return RETURN_OK;
5384}
5385
5386//P2 // outputs the number of Tx streams
5387INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
5388{
5389 char buf[8] = {0};
5390 char cmd[128] = {0};
5391 int phyId = 0;
5392
5393 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5394
5395 phyId = radio_index_to_phy(radioIndex);
5396 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
5397 _syscmd(cmd, buf, sizeof(buf));
5398
5399 *output_int = (INT)strtol(buf, NULL, 16);
5400
5401 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5402
5403 return RETURN_OK;
5404}
5405
5406INT fitChainMask(INT radioIndex, int antcount)
5407{
5408 char buf[128] = {0};
5409 char cmd[128] = {0};
5410 char config_file[64] = {0};
5411 wifi_band band;
5412 struct params list[2] = {0};
5413
5414 band = wifi_index_to_band(radioIndex);
5415 if (band == band_invalid)
5416 return RETURN_ERR;
5417
5418 list[0].name = "he_mu_beamformer";
5419 list[1].name = "he_su_beamformer";
5420
5421 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5422 if (antcount == 1) {
5423 // remove config about multiple antennas
5424 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
5425 _syscmd(cmd, buf, sizeof(buf));
5426
5427 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
5428 _syscmd(cmd, buf, sizeof(buf));
5429
5430 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
5431 _syscmd(cmd, buf, sizeof(buf));
5432
5433 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
5434 _syscmd(cmd, buf, sizeof(buf));
5435
5436 list[0].value = "0";
5437 list[1].value = "0";
5438 } else {
5439 // If we only set RX STBC means STBC is enable and TX STBC is disable when last time set one antenna. so we need to add it back.
5440 if (band == band_2_4 || band == band_5) {
5441 snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
5442 _syscmd(cmd, buf, sizeof(buf));
5443 if (strlen(buf) > 0) {
5444 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
5445 _syscmd(cmd, buf, sizeof(buf));
5446 }
5447 }
5448 if (band == band_5) {
5449 snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
5450 _syscmd(cmd, buf, sizeof(buf));
5451 if (strlen(buf) > 0) {
5452 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
5453 _syscmd(cmd, buf, sizeof(buf));
5454 }
5455 }
5456
5457 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
5458 _syscmd(cmd, buf, sizeof(buf));
5459 if (strlen(buf) == 0) {
5460 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
5461 _syscmd(cmd, buf, sizeof(buf));
5462 }
5463
5464 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
5465 _syscmd(cmd, buf, sizeof(buf));
5466 if (strlen(buf) == 0) {
5467 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
5468 _syscmd(cmd, buf, sizeof(buf));
5469 }
5470
5471 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
5472 _syscmd(cmd, buf, sizeof(buf));
5473 if (strlen(buf) == 0) {
5474 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
5475 } else {
5476 snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
5477 }
5478 _syscmd(cmd, buf, sizeof(buf));
5479
5480 list[0].value = "1";
5481 list[1].value = "1";
5482 }
5483 wifi_hostapdWrite(config_file, list, 2);
5484}
5485
5486//P2 // sets the number of Tx streams to an enviornment variable
5487INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
5488{
5489 char cmd[128] = {0};
5490 char buf[128] = {0};
5491 int phyId = 0;
5492 int cur_mask = 0;
developera1255e42023-05-13 17:45:02 +08005493 int antcountmsk = 0;
5494 INT cur_nss = 0;
5495 UCHAR dat_file[64] = {0};
5496 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08005497
5498 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5499
5500 if (numStreams <= 0) {
5501 fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams);
5502 return RETURN_ERR;
5503 }
5504
developera1255e42023-05-13 17:45:02 +08005505 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
5506 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
5507 cur_nss += 1;
5508 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
5509 if (cur_nss == numStreams)
developer72fb0bb2023-01-11 09:46:29 +08005510 return RETURN_OK;
5511
5512 wifi_setRadioEnable(radioIndex, FALSE);
5513
5514 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08005515 //iw need mask value.
5516 for (;numStreams > 0; numStreams--)
5517 antcountmsk |= 0x1 << (numStreams - 1);
5518 snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
developer72fb0bb2023-01-11 09:46:29 +08005519 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005520 if (strlen(buf) > 0) {
5521 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
5522 return RETURN_ERR;
5523 }
developera1255e42023-05-13 17:45:02 +08005524 band = wifi_index_to_band(radioIndex);
5525 if (band == band_invalid) {
5526 printf("%s:Band Error\n", __func__);
5527 return RETURN_ERR;
5528 }
5529 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5530 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
5531 _syscmd(cmd, buf, sizeof(buf));
5532 if (strlen(buf) > 0) {
5533 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
5534 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005535 }
developera1255e42023-05-13 17:45:02 +08005536 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
5537 _syscmd(cmd, buf, sizeof(buf));
5538 if (strlen(buf) > 0) {
5539 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
5540 return RETURN_ERR;
5541 }
5542 fitChainMask(radioIndex, numStreams);
developer72fb0bb2023-01-11 09:46:29 +08005543 wifi_setRadioEnable(radioIndex, TRUE);
5544
5545 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5546 return RETURN_OK;
5547}
5548
5549//P2 // outputs the number of Rx streams
5550INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
5551{
5552 char buf[8] = {0};
5553 char cmd[128] = {0};
5554 int phyId = 0;
5555
5556 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5557
5558 phyId = radio_index_to_phy(radioIndex);
5559 sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
5560 _syscmd(cmd, buf, sizeof(buf));
5561
5562 *output_int = (INT)strtol(buf, NULL, 16);
5563
5564 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5565
5566 return RETURN_OK;
5567}
5568
5569//P2 // sets the number of Rx streams to an enviornment variable
5570INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
5571{
5572 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5573 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
5574 fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__);
5575 return RETURN_ERR;
5576 }
5577 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5578 return RETURN_ERR;
5579}
5580
5581//Get radio RDG enable setting
5582INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
5583{
5584 if (NULL == output_bool)
5585 return RETURN_ERR;
5586 *output_bool = TRUE;
5587 return RETURN_OK;
5588}
5589
5590//Get radio RDG enable setting
5591INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
5592{
5593 if (NULL == output_bool)
5594 return RETURN_ERR;
5595 *output_bool = TRUE;
5596 return RETURN_OK;
5597}
5598
5599//Set radio RDG enable setting
5600INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
5601{
5602 return RETURN_ERR;
5603}
5604
5605//Get radio ADDBA enable setting
5606INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
5607{
5608 if (NULL == output_bool)
5609 return RETURN_ERR;
5610 *output_bool = TRUE;
5611 return RETURN_OK;
5612}
5613
5614//Set radio ADDBA enable setting
5615INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
5616{
5617 return RETURN_ERR;
5618}
5619
5620//Get radio auto block ack enable setting
5621INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
5622{
5623 if (NULL == output_bool)
5624 return RETURN_ERR;
5625 *output_bool = TRUE;
5626 return RETURN_OK;
5627}
5628
5629//Set radio auto block ack enable setting
5630INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
5631{
5632 return RETURN_ERR;
5633}
5634
5635//Get radio 11n pure mode enable support
5636INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
5637{
5638 if (NULL == output_bool)
5639 return RETURN_ERR;
5640 *output_bool = TRUE;
5641 return RETURN_OK;
5642}
5643
5644//Get radio 11n pure mode enable setting
5645INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
5646{
5647 if (NULL == output_bool)
5648 return RETURN_ERR;
5649 *output_bool = TRUE;
5650 return RETURN_OK;
5651}
5652
5653//Set radio 11n pure mode enable setting
5654INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
5655{
5656 return RETURN_ERR;
5657}
5658
5659//Get radio IGMP snooping enable setting
5660INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
5661{
5662 char interface_name[16] = {0};
5663 char cmd[128]={0};
5664 char buf[4]={0};
5665 bool bridge = FALSE, mac80211 = FALSE;
5666 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5667
5668 if(output_bool == NULL)
5669 return RETURN_ERR;
5670
5671 *output_bool = FALSE;
5672
5673 snprintf(cmd, sizeof(cmd), "cat /sys/devices/virtual/net/%s/bridge/multicast_snooping", BRIDGE_NAME);
5674 _syscmd(cmd, buf, sizeof(buf));
5675 if (strncmp(buf, "1", 1) == 0)
5676 bridge = TRUE;
5677
5678 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5679 return RETURN_ERR;
5680 snprintf(cmd, sizeof(cmd), "cat /sys/devices/virtual/net/%s/brif/%s/multicast_to_unicast", BRIDGE_NAME, interface_name);
5681 _syscmd(cmd, buf, sizeof(buf));
5682 if (strncmp(buf, "1", 1) == 0)
5683 mac80211 = TRUE;
5684
5685 if (bridge && mac80211)
5686 *output_bool = TRUE;
5687
5688 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5689 return RETURN_OK;
5690}
5691
5692//Set radio IGMP snooping enable setting
5693INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
5694{
5695 char interface_name[16] = {0};
5696 char cmd[128]={0};
5697 char buf[4]={0};
5698 int max_num_radios =0;
5699 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5700
5701 // bridge
5702 snprintf(cmd, sizeof(cmd), "echo %d > /sys/devices/virtual/net/%s/bridge/multicast_snooping", enable, BRIDGE_NAME);
5703 _syscmd(cmd, buf, sizeof(buf));
5704
5705 wifi_getMaxRadioNumber(&max_num_radios);
5706 // mac80211
5707 for (int i = 0; i < max_num_radios; i++) {
5708 if (wifi_GetInterfaceName(i, interface_name) != RETURN_OK)
5709 return RETURN_ERR;
5710 snprintf(cmd, sizeof(cmd), "echo %d > /sys/devices/virtual/net/%s/brif/%s/multicast_to_unicast", enable, BRIDGE_NAME, interface_name);
5711 _syscmd(cmd, buf, sizeof(buf));
5712 }
5713 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5714 return RETURN_OK;
5715}
5716
5717//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08005718INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08005719{
developer69b61b02023-03-07 17:17:44 +08005720 if (NULL == output_int)
developer72fb0bb2023-01-11 09:46:29 +08005721 return RETURN_ERR;
5722 *output_int = (radioIndex==0)? 1: 3;
5723
5724 return RETURN_OK;
5725}
5726
5727
5728//---------------------------------------------------------------------------------------------------
5729//
5730// Additional Wifi AP level APIs used for Access Point devices
5731//
5732//---------------------------------------------------------------------------------------------------
5733
5734// creates a new ap and pushes these parameters to the hardware
5735INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
5736{
5737 // Deprecated when use hal version 3, use wifi_createVap() instead.
5738 return RETURN_OK;
5739}
5740
5741// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
5742INT wifi_deleteAp(INT apIndex)
5743{
developer7e4a2a62023-04-06 19:56:03 +08005744 char interface_name[16] = {0};
5745 char buf[MAX_BUF_SIZE];
5746 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08005747
developer7e4a2a62023-04-06 19:56:03 +08005748 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5749 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08005750
developer7e4a2a62023-04-06 19:56:03 +08005751 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
5752 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005753
developer7e4a2a62023-04-06 19:56:03 +08005754 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08005755
developer7e4a2a62023-04-06 19:56:03 +08005756 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005757}
5758
5759// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
5760INT wifi_getApName(INT apIndex, CHAR *output_string)
5761{
developer7e4a2a62023-04-06 19:56:03 +08005762 char interface_name[IF_NAME_SIZE] = {0};
5763 char radio_idx = 0;
5764 char bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08005765
developer7e4a2a62023-04-06 19:56:03 +08005766 if(!output_string)
5767 return RETURN_ERR;
5768
5769 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
5770 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
5771
5772 snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model.
5773 } else
5774 snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
5775
5776 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005777}
5778
5779// Outputs the index number in that corresponds to the SSID string
5780INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
5781{
developer7e4a2a62023-04-06 19:56:03 +08005782 char cmd [128] = {0};
5783 char buf[32] = {0};
5784 char ap_idx = 0;
5785 char *apIndex_str = NULL;
5786 char radio_idx = 0;
5787 char bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08005788
developer7e4a2a62023-04-06 19:56:03 +08005789 snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
5790 inputSsidString);
5791 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005792
developer7e4a2a62023-04-06 19:56:03 +08005793 if (strlen(buf)) {
5794 apIndex_str = strtok(buf, "\n");
5795 *output_int = strtoul(apIndex_str, NULL, 10);
5796 return RETURN_OK;
5797 }
developer72fb0bb2023-01-11 09:46:29 +08005798
developer7e4a2a62023-04-06 19:56:03 +08005799 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
5800 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
5801 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
5802 radio_idx = 2;
5803 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
5804 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
5805 radio_idx = 1;
5806 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
5807 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
5808 radio_idx = 0;
5809 } else {
5810 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
5811 __func__, inputSsidString, ap_idx);
5812 *output_int = -1;
5813 return RETURN_ERR;
5814 }
5815
5816 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
5817
5818 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
5819 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
5820 __func__, inputSsidString, ap_idx);
5821 *output_int = ap_idx;
5822 return RETURN_OK;
5823 }
5824
5825 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005826}
5827
5828INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
5829{
5830 return wifi_getIndexFromName(inputSsidString, output_int);
5831}
5832
5833// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
5834INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
5835{
5836 char buf[MAX_BUF_SIZE] = {0};
5837 char cmd[MAX_CMD_SIZE] = {0};
5838 char config_file[MAX_BUF_SIZE] = {0};
5839
5840 if(NULL == output_string)
5841 return RETURN_ERR;
5842
5843 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5844 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
5845 if((strcmp(buf,"3")==0))
5846 snprintf(output_string, 32, "WPAand11i");
5847 else if((strcmp(buf,"2")==0))
5848 snprintf(output_string, 32, "11i");
5849 else if((strcmp(buf,"1")==0))
5850 snprintf(output_string, 32, "WPA");
5851 else
5852 snprintf(output_string, 32, "None");
5853
5854 return RETURN_OK;
5855}
5856
5857// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
5858INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
5859{
5860 char config_file[MAX_BUF_SIZE] = {0};
5861 struct params list;
5862
5863 if (NULL == beaconTypeString)
5864 return RETURN_ERR;
5865 list.name = "wpa";
5866 list.value = "0";
5867
5868 if((strcmp(beaconTypeString,"WPAand11i")==0))
5869 list.value="3";
5870 else if((strcmp(beaconTypeString,"11i")==0))
5871 list.value="2";
5872 else if((strcmp(beaconTypeString,"WPA")==0))
5873 list.value="1";
5874
5875 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5876 wifi_hostapdWrite(config_file, &list, 1);
5877 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5878 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
5879 return RETURN_OK;
5880}
5881
5882// sets the beacon interval on the hardware for this AP
5883INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
5884{
5885 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5886 struct params params={'\0'};
5887 char buf[MAX_BUF_SIZE] = {'\0'};
5888 char config_file[MAX_BUF_SIZE] = {'\0'};
5889
5890 params.name = "beacon_int";
5891 snprintf(buf, sizeof(buf), "%u", beaconInterval);
5892 params.value = buf;
5893
5894 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
5895 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08005896
developer72fb0bb2023-01-11 09:46:29 +08005897 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5898 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5899 return RETURN_OK;
5900}
5901
5902INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
5903{
5904 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
5905 return RETURN_ERR;
5906 return RETURN_OK;
5907}
5908
5909// Get the packet size threshold supported.
5910INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
5911{
5912 //save config and apply instantly
5913 if (NULL == output_bool)
5914 return RETURN_ERR;
5915 *output_bool = TRUE;
5916 return RETURN_OK;
5917}
5918
5919// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
5920INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
5921{
developer72fb0bb2023-01-11 09:46:29 +08005922 char buf[16] = {0};
5923 char config_file[128] = {0};
5924 struct params param = {0};
5925
5926 if (threshold > 65535) {
5927 fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold);
5928 return RETURN_ERR;
5929 }
5930
developer23e71282023-01-18 10:25:19 +08005931 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer72fb0bb2023-01-11 09:46:29 +08005932 snprintf(buf, sizeof(buf), "%u", threshold);
5933 param.name = "rts_threshold";
5934 param.value = buf;
5935 wifi_hostapdWrite(config_file, &param, 1);
5936 wifi_hostapdProcessUpdate(apIndex, &param, 1);
5937 wifi_reloadAp(apIndex);
5938
5939 return RETURN_OK;
5940}
5941
5942// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
5943INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
5944{
5945 if (NULL == output_string)
5946 return RETURN_ERR;
5947 snprintf(output_string, 32, "TKIPandAESEncryption");
5948 return RETURN_OK;
5949
5950}
5951
5952// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
5953INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
5954{
5955 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5956 char *param_name = NULL;
5957 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
5958
5959 if(NULL == output_string)
5960 return RETURN_ERR;
5961
5962 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5963 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
5964
5965 if(strcmp(buf,"0")==0)
5966 {
5967 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
5968 snprintf(output_string, 32, "None");
5969 return RETURN_OK;
5970 }
5971 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
5972 param_name = "rsn_pairwise";
5973 else if((strcmp(buf,"1")==0))
5974 param_name = "wpa_pairwise";
5975 else
5976 return RETURN_ERR;
5977 memset(output_string,'\0',32);
5978 wifi_hostapdRead(config_file,param_name,output_string,32);
5979 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
5980 param_name = "wpa_pairwise";
5981 memset(output_string, '\0', 32);
5982 wifi_hostapdRead(config_file, param_name, output_string, 32);
5983 }
5984 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
5985
developere5750452023-05-15 16:46:42 +08005986 if(strcmp(output_string,"TKIP CCMP") == 0)
5987 strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption"));
5988 else if(strcmp(output_string,"TKIP") == 0)
developer72fb0bb2023-01-11 09:46:29 +08005989 strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption"));
5990 else if(strcmp(output_string,"CCMP") == 0)
5991 strncpy(output_string,"AESEncryption", strlen("AESEncryption"));
developer72fb0bb2023-01-11 09:46:29 +08005992
5993 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5994 return RETURN_OK;
5995}
5996
5997// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
5998INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
5999{
6000 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6001 struct params params={'\0'};
6002 char output_string[32];
6003 char config_file[MAX_BUF_SIZE] = {0};
6004
6005 memset(output_string,'\0',32);
developere5750452023-05-15 16:46:42 +08006006 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08006007
6008 if(strcmp(encMode, "TKIPEncryption") == 0)
6009 params.value = "TKIP";
6010 else if(strcmp(encMode,"AESEncryption") == 0)
6011 params.value = "CCMP";
6012 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
6013 params.value = "TKIP CCMP";
6014
6015 if((strcmp(output_string,"WPAand11i")==0))
6016 {
6017 params.name = "wpa_pairwise";
6018 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6019 wifi_hostapdWrite(config_file, &params, 1);
6020 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6021
6022 params.name = "rsn_pairwise";
6023 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6024 wifi_hostapdWrite(config_file, &params, 1);
6025 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6026
6027 return RETURN_OK;
6028 }
6029 else if((strcmp(output_string,"11i")==0))
6030 {
6031 params.name = "rsn_pairwise";
6032 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6033 wifi_hostapdWrite(config_file, &params, 1);
6034 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6035 return RETURN_OK;
6036 }
6037 else if((strcmp(output_string,"WPA")==0))
6038 {
6039 params.name = "wpa_pairwise";
6040 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6041 wifi_hostapdWrite(config_file, &params, 1);
6042 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6043 return RETURN_OK;
6044 }
6045
6046 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6047 return RETURN_OK;
6048}
6049
6050// deletes internal security varable settings for this ap
6051INT wifi_removeApSecVaribles(INT apIndex)
6052{
6053 //TODO: remove the entry in hostapd config file
6054 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name);
6055 //_syscmd(cmd, buf, sizeof(buf));
6056
6057 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name);
6058 //_syscmd(cmd, buf, sizeof(buf));
6059 return RETURN_ERR;
6060}
6061
6062// changes the hardware settings to disable encryption on this ap
6063INT wifi_disableApEncryption(INT apIndex)
6064{
6065 //Apply instantly
6066 return RETURN_ERR;
6067}
6068
6069// set the authorization mode on this ap
6070// mode mapping as: 1: open, 2: shared, 4:auto
6071INT wifi_setApAuthMode(INT apIndex, INT mode)
6072{
6073 struct params params={0};
6074 char config_file[64] = {0};
6075 int ret;
6076
6077 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6078
6079 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
6080 params.name = "auth_algs";
6081
developere5750452023-05-15 16:46:42 +08006082 if ((mode & 1 && mode & 2) || mode & 4)
developer72fb0bb2023-01-11 09:46:29 +08006083 params.value = "3";
6084 else if (mode & 2)
6085 params.value = "2";
6086 else if (mode & 1)
6087 params.value = "1";
6088 else
6089 params.value = "0";
6090
6091 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6092 wifi_hostapdWrite(config_file, &params, 1);
6093 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08006094 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006095 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6096
6097 return RETURN_OK;
6098}
6099
6100// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
6101INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
6102{
6103 //save to wifi config, and wait for wifi restart to apply
6104 struct params params={'\0'};
6105 char config_file[MAX_BUF_SIZE] = {0};
6106 int ret;
6107
6108 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6109 if(authMode == NULL)
6110 return RETURN_ERR;
6111
6112 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
6113 params.name = "wpa_key_mgmt";
6114
6115 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
6116 params.value = "WPA-PSK";
6117 else if(strcmp(authMode,"EAPAuthentication") == 0)
6118 params.value = "WPA-EAP";
6119 else if (strcmp(authMode, "SAEAuthentication") == 0)
6120 params.value = "SAE";
6121 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
6122 params.value = "WPA-EAP-SUITE-B-192";
6123 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
6124 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
developer3086e2f2023-01-17 09:40:01 +08006125 else if (strcmp(authMode, "Enhanced_Open") == 0)
6126 params.value = "OWE";
developer72fb0bb2023-01-11 09:46:29 +08006127 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
6128 return RETURN_OK; //This is taken careof in beaconType
6129
6130 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6131 ret=wifi_hostapdWrite(config_file,&params,1);
6132 if(!ret)
6133 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
6134 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6135
6136 return ret;
6137}
6138
6139// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
6140INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
6141{
6142 //save to wifi config, and wait for wifi restart to apply
6143 char BeaconType[50] = {0};
6144 char config_file[MAX_BUF_SIZE] = {0};
6145
6146 *authMode = 0;
6147 wifi_getApBeaconType(apIndex,BeaconType);
6148 printf("%s____%s \n",__FUNCTION__,BeaconType);
6149
6150 if(strcmp(BeaconType,"None") == 0)
6151 strcpy(authMode,"None");
6152 else
6153 {
6154 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6155 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
6156 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
6157 if(strcmp(authMode,"WPA-PSK") == 0)
6158 strcpy(authMode,"SharedAuthentication");
6159 else if(strcmp(authMode,"WPA-EAP") == 0)
6160 strcpy(authMode,"EAPAuthentication");
6161 }
6162
6163 return RETURN_OK;
6164}
6165
6166// Outputs the number of stations associated per AP
6167INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
6168{
6169 char interface_name[16] = {0};
6170 char cmd[128]={0};
6171 char buf[128]={0};
6172 BOOL status = false;
6173
6174 if(apIndex > MAX_APS)
6175 return RETURN_ERR;
6176
6177 wifi_getApEnable(apIndex,&status);
6178 if (!status)
6179 return RETURN_OK;
6180
6181 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
6182 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6183 return RETURN_ERR;
6184 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name);
6185 _syscmd(cmd, buf, sizeof(buf));
6186 sscanf(buf,"%lu", output_ulong);
6187
6188 return RETURN_OK;
6189}
6190
6191// manually removes any active wi-fi association with the device specified on this ap
6192INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
6193{
developer7e4a2a62023-04-06 19:56:03 +08006194 char inf_name[16] = {0};
6195 char cmd[MAX_CMD_SIZE] = {0};
6196 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006197
developer7e4a2a62023-04-06 19:56:03 +08006198 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08006199 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08006200
6201 snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
6202 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006203
6204 return RETURN_OK;
6205}
6206
6207// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
6208INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
6209{
developer7e4a2a62023-04-06 19:56:03 +08006210 int max_radio_num = 0;
6211
6212 if(NULL == output_int)
6213 return RETURN_ERR;
6214
6215 wifi_getMaxRadioNumber(&max_radio_num);
6216 *output_int = apIndex % max_radio_num;
6217
6218 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006219}
6220
6221// sets the radio index for the specific ap
6222INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
6223{
6224 //set to config only and wait for wifi reset to apply settings
6225 return RETURN_ERR;
6226}
6227
6228// Get the ACL MAC list per AP
6229INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
6230{
developer7e4a2a62023-04-06 19:56:03 +08006231 char cmd[MAX_CMD_SIZE] = {0};
6232 char buf[MAX_BUF_SIZE] = {0};
6233 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006234
developer7e4a2a62023-04-06 19:56:03 +08006235 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6236 return RETURN_ERR;
6237
6238 /* mwctl acl del sta */
6239 snprintf(cmd, sizeof(cmd), "mwctl %s acl show_all | grep ':'", inf_name);
6240 _syscmd(cmd, buf, sizeof(buf));
6241
6242 memcpy(macArray, buf, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08006243
6244 return RETURN_OK;
6245}
6246
6247INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
6248{
developer72fb0bb2023-01-11 09:46:29 +08006249
developer7e4a2a62023-04-06 19:56:03 +08006250 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08006251
6252 return RETURN_OK;
6253}
6254
6255
6256// Get the list of stations associated per AP
6257INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
6258{
developer7e4a2a62023-04-06 19:56:03 +08006259 char interface_name[IF_NAME_SIZE] = {0};
6260 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08006261
developer7e4a2a62023-04-06 19:56:03 +08006262 if(apIndex > 3) //Currently supporting apIndex upto 3
6263 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006264
developer7e4a2a62023-04-06 19:56:03 +08006265 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6266 return RETURN_ERR;
6267
6268 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
6269 _syscmd(cmd, macArray, buf_size);
6270 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006271}
6272
6273// adds the mac address to the filter list
6274//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
6275INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
6276{
developer7e4a2a62023-04-06 19:56:03 +08006277 char cmd[MAX_CMD_SIZE] = {0};
6278 char buf[MAX_BUF_SIZE] = {0};
6279 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006280
developer7e4a2a62023-04-06 19:56:03 +08006281 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6282 return RETURN_ERR;
6283
6284 if (!DeviceMacAddress)
6285 return RETURN_ERR;
6286
6287 /* mwctl acl add sta */
6288 snprintf(cmd, sizeof(cmd), "mwctl %s acl add=%s", inf_name, DeviceMacAddress);
6289 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006290
6291 return RETURN_OK;
6292}
6293
6294// deletes the mac address from the filter list
6295//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
6296INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
6297{
developer7e4a2a62023-04-06 19:56:03 +08006298 char cmd[MAX_CMD_SIZE] = {0};
6299 char buf[MAX_BUF_SIZE] = {0};
6300 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006301
developer7e4a2a62023-04-06 19:56:03 +08006302 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6303 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006304
developer7e4a2a62023-04-06 19:56:03 +08006305 if (!DeviceMacAddress)
6306 return RETURN_ERR;
6307
6308 /* mwctl acl del sta */
6309 snprintf(cmd, sizeof(cmd), "mwctl %s acl del=%s", inf_name, DeviceMacAddress);
6310 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006311
6312 return RETURN_OK;
6313}
6314
6315// outputs the number of devices in the filter list
6316INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
6317{
developer7e4a2a62023-04-06 19:56:03 +08006318 char cmd[MAX_CMD_SIZE] = {0};
6319 char buf[MAX_BUF_SIZE] = {0};
6320 char inf_name[IF_NAME_SIZE] = {0};
6321 char sta_num = 0;
developer72fb0bb2023-01-11 09:46:29 +08006322
developer72fb0bb2023-01-11 09:46:29 +08006323 if(output_uint == NULL)
6324 return RETURN_ERR;
6325
developer7e4a2a62023-04-06 19:56:03 +08006326 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6327 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006328
developer7e4a2a62023-04-06 19:56:03 +08006329 /* mwctl acl get sta num */
6330 snprintf(cmd, sizeof(cmd), "mwctl %s acl show_all | wc -l | tr -d '\\n'", inf_name);
6331 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006332
developer7e4a2a62023-04-06 19:56:03 +08006333 if (atoi(buf) > 1)
6334 *output_uint = atoi(buf) - 1; /*except the line of acl_policy*/
6335 else {
6336 *output_uint = 0;
6337 printf("%s: acl get wrong return content!!!\n", __func__);
6338 }
6339
6340 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006341}
6342
6343INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
6344{
6345 char cmd[128]={'\0'};
6346 char buf[128]={'\0'};
6347
6348 if(strcmp(action,"DENY")==0)
6349 {
6350 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
6351 system(buf);
6352 return RETURN_OK;
6353 }
6354
6355 if(strcmp(action,"ALLOW")==0)
6356 {
6357 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
6358 system(buf);
6359 return RETURN_OK;
6360 }
6361
6362 return RETURN_ERR;
6363
6364}
6365
6366// enable kick for devices on acl black list
6367INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
6368{
6369 char aclArray[512] = {0}, *acl = NULL;
6370 char assocArray[512] = {0}, *asso = NULL;
6371
6372 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
6373 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
6374
developer7e4a2a62023-04-06 19:56:03 +08006375 /* if there are no devices connected there is nothing to do */
developer72fb0bb2023-01-11 09:46:29 +08006376 if (strlen(assocArray) < 17)
6377 return RETURN_OK;
6378
developer7e4a2a62023-04-06 19:56:03 +08006379 if (enable == TRUE) {
6380 /* kick off the MAC which is in ACL array (deny list) */
6381 acl = strtok(aclArray, "\n");
developer72fb0bb2023-01-11 09:46:29 +08006382 while (acl != NULL) {
6383 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
6384 wifi_kickApAssociatedDevice(apIndex, acl);
6385
developer7e4a2a62023-04-06 19:56:03 +08006386 acl = strtok(NULL, "\n");
developer72fb0bb2023-01-11 09:46:29 +08006387 }
6388 wifi_setApMacAddressControlMode(apIndex, 2);
developer7e4a2a62023-04-06 19:56:03 +08006389 } else
developer72fb0bb2023-01-11 09:46:29 +08006390 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08006391
developer72fb0bb2023-01-11 09:46:29 +08006392 return RETURN_OK;
6393}
6394
6395INT wifi_setPreferPrivateConnection(BOOL enable)
6396{
6397 return RETURN_OK;
6398}
6399
6400// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
6401INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
6402{
developer7e4a2a62023-04-06 19:56:03 +08006403 char inf_name[IF_NAME_SIZE] = {0};
6404 char cmd[MAX_CMD_SIZE] = {0};
6405 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006406
developer7e4a2a62023-04-06 19:56:03 +08006407 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6408 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006409
developer7e4a2a62023-04-06 19:56:03 +08006410 /*mwctl set acl policy*/
6411 snprintf(cmd, sizeof(cmd), "mwctl %s acl policy=%d", inf_name, filterMode);
6412 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006413
developer7e4a2a62023-04-06 19:56:03 +08006414 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006415}
6416
6417// enables internal gateway VLAN mode. In this mode a Vlan tag is added to upstream (received) data packets before exiting the Wifi driver. VLAN tags in downstream data are stripped from data packets before transmission. Default is FALSE.
6418INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
6419{
6420 return RETURN_ERR;
6421}
6422
6423// gets the vlan ID for this ap from an internal enviornment variable
6424INT wifi_getApVlanID(INT apIndex, INT *output_int)
6425{
6426 if(apIndex==0)
6427 {
6428 *output_int=100;
6429 return RETURN_OK;
6430 }
6431
6432 return RETURN_ERR;
6433}
6434
6435// sets the vlan ID for this ap to an internal enviornment variable
6436INT wifi_setApVlanID(INT apIndex, INT vlanId)
6437{
6438 //save the vlanID to config and wait for wifi reset to apply (wifi up module would read this parameters and tag the AP with vlan id)
6439 return RETURN_ERR;
6440}
6441
6442// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
6443INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
6444{
6445 snprintf(bridgeName, 32, "brlan0");
6446 snprintf(IP, 32, "10.0.0.1");
6447 snprintf(subnet, 32, "255.255.255.0");
6448
6449 return RETURN_OK;
6450}
6451
6452//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
6453INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
6454{
6455 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
6456 return RETURN_ERR;
6457}
6458
6459// reset the vlan configuration for this ap
6460INT wifi_resetApVlanCfg(INT apIndex)
6461{
6462 char original_config_file[64] = {0};
6463 char current_config_file[64] = {0};
6464 char buf[64] = {0};
6465 char cmd[64] = {0};
6466 char vlan_file[64] = {0};
6467 char vlan_tagged_interface[16] = {0};
6468 char vlan_bridge[16] = {0};
6469 char vlan_naming[16] = {0};
6470 struct params list[4] = {0};
6471 wifi_band band;
developera1255e42023-05-13 17:45:02 +08006472 char interface_name[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006473
6474 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006475 band = wifi_index_to_band(apIndex);
6476 if (band == band_2_4)
developera1255e42023-05-13 17:45:02 +08006477 snprintf(original_config_file, sizeof(original_config_file), "/etc/hostapd-2G.conf");
developer72fb0bb2023-01-11 09:46:29 +08006478 else if (band == band_5)
developera1255e42023-05-13 17:45:02 +08006479 snprintf(original_config_file, sizeof(original_config_file), "/etc/hostapd-5G.conf");
developer72fb0bb2023-01-11 09:46:29 +08006480 else if (band == band_6)
developera1255e42023-05-13 17:45:02 +08006481 snprintf(original_config_file, sizeof(original_config_file), "/etc/hostapd-6G.conf");
developer72fb0bb2023-01-11 09:46:29 +08006482
6483 wifi_hostapdRead(original_config_file, "vlan_file", vlan_file, sizeof(vlan_file));
6484
6485 if (strlen(vlan_file) == 0)
6486 strcpy(vlan_file, VLAN_FILE);
6487
6488 // The file should exist or this vap would not work.
6489 if (access(vlan_file, F_OK) != 0) {
developera1255e42023-05-13 17:45:02 +08006490 snprintf(cmd, sizeof(cmd), "touch %s", vlan_file);
developer72fb0bb2023-01-11 09:46:29 +08006491 _syscmd(cmd, buf, sizeof(buf));
6492 }
6493 list[0].name = "vlan_file";
6494 list[0].value = vlan_file;
6495
6496 wifi_hostapdRead(original_config_file, "vlan_tagged_interface", vlan_tagged_interface, sizeof(vlan_tagged_interface));
6497 list[1].name = "vlan_tagged_interface";
6498 list[1].value = vlan_tagged_interface;
6499
6500 wifi_hostapdRead(original_config_file, "vlan_bridge", vlan_bridge, sizeof(vlan_bridge));
6501 list[2].name = "vlan_bridge";
6502 list[2].value = vlan_bridge;
6503
6504 wifi_hostapdRead(original_config_file, "vlan_naming", vlan_naming, sizeof(vlan_naming));
6505 list[3].name = "vlan_naming";
6506 list[3].value = vlan_naming;
6507
developera1255e42023-05-13 17:45:02 +08006508 snprintf(current_config_file, sizeof(current_config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006509 wifi_hostapdWrite(current_config_file, list, 4);
6510 //Reapply vlan settings
6511 // wifi_pushBridgeInfo(apIndex);
6512
6513 // restart this ap
6514 wifi_setApEnable(apIndex, FALSE);
6515 wifi_setApEnable(apIndex, TRUE);
developera1255e42023-05-13 17:45:02 +08006516 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6517 return RETURN_ERR;
6518 snprintf(cmd, sizeof(cmd), "mwctl dev %s set vlan_tag 0\n", interface_name);
6519 _syscmd(cmd, buf, sizeof(buf));
6520 snprintf(cmd, sizeof(cmd), "mwctl dev %s set vlan_priority 0\n", interface_name);
6521 _syscmd(cmd, buf, sizeof(buf));
6522 snprintf(cmd, sizeof(cmd), "mwctl dev %s set vlan_id 0\n", interface_name);
6523 _syscmd(cmd, buf, sizeof(buf));
6524 snprintf(cmd, sizeof(cmd), "mwctl dev %s set vlan_en 0\n", interface_name);
6525 _syscmd(cmd, buf, sizeof(buf));
6526 snprintf(cmd, sizeof(cmd), "mwctl dev %s set vlan_policy 0:4\n", interface_name);
6527 _syscmd(cmd, buf, sizeof(buf));
6528 snprintf(cmd, sizeof(cmd), "mwctl dev %s set vlan_policy 1:0\n", interface_name);
6529 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006530 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6531
6532 return RETURN_OK;
6533}
6534
6535// creates configuration variables needed for WPA/WPS. These variables are implementation dependent and in some implementations these variables are used by hostapd when it is started. Specific variables that are needed are dependent on the hostapd implementation. These variables are set by WPA/WPS security functions in this wifi HAL. If not needed for a particular implementation this function may simply return no error.
6536INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
6537{
6538 return RETURN_ERR;
6539}
6540
6541// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
6542INT wifi_startHostApd()
6543{
6544 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6545 system("systemctl start hostapd.service");
6546 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6547 return RETURN_OK;
6548 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
6549}
6550
6551// stops hostapd
developer69b61b02023-03-07 17:17:44 +08006552INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08006553{
6554 char cmd[128] = {0};
6555 char buf[128] = {0};
6556
6557 sprintf(cmd,"systemctl stop hostapd");
6558 _syscmd(cmd, buf, sizeof(buf));
6559
6560 return RETURN_OK;
6561}
6562
6563// restart hostapd dummy function
6564INT wifi_restartHostApd()
6565{
6566 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6567 system("systemctl restart hostapd-global");
6568 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6569
6570 return RETURN_OK;
6571}
6572
6573static int align_hostapd_config(int index)
6574{
6575 ULONG lval;
6576 wifi_getRadioChannel(index%2, &lval);
6577 wifi_setRadioChannel(index%2, lval);
6578 return RETURN_OK;
6579}
6580
6581// sets the AP enable status variable for the specified ap.
6582INT wifi_setApEnable(INT apIndex, BOOL enable)
6583{
developer7e4a2a62023-04-06 19:56:03 +08006584 char interface_name[16] = {0};
6585 char config_file[MAX_BUF_SIZE] = {0};
6586 char cmd[MAX_CMD_SIZE] = {0};
6587 char buf[MAX_BUF_SIZE] = {0};
6588 BOOL status;
6589 int max_radio_num = 0;
6590 int phyId = 0;
developer72fb0bb2023-01-11 09:46:29 +08006591
developer7e4a2a62023-04-06 19:56:03 +08006592 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08006593
developer7e4a2a62023-04-06 19:56:03 +08006594 wifi_getMaxRadioNumber(&max_radio_num);
6595 if (enable == status)
6596 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006597
developer7e4a2a62023-04-06 19:56:03 +08006598 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6599 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006600
developer7e4a2a62023-04-06 19:56:03 +08006601 if (enable == TRUE) {
6602 int radioIndex = apIndex % max_radio_num;
6603 phyId = radio_index_to_phy(radioIndex);
developer8a3bbbf2023-03-15 17:47:23 +08006604
developer7e4a2a62023-04-06 19:56:03 +08006605 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
6606 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
6607 _syscmd(cmd, buf, sizeof(buf));
6608 } else {
6609 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
6610 _syscmd(cmd, buf, sizeof(buf));
6611 }
6612 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
6613 interface_name, interface_name, enable, VAP_STATUS_FILE);
6614 _syscmd(cmd, buf, sizeof(buf));
6615 //Wait for wifi up/down to apply
6616 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006617}
6618
6619// Outputs the setting of the internal variable that is set by wifi_setApEnable().
6620INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
6621{
developer7e4a2a62023-04-06 19:56:03 +08006622 char interface_name[IF_NAME_SIZE] = {0};
6623 char cmd[MAX_CMD_SIZE] = {0};
6624 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006625
developer7e4a2a62023-04-06 19:56:03 +08006626 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
6627 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006628
developer7e4a2a62023-04-06 19:56:03 +08006629 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08006630
developer7e4a2a62023-04-06 19:56:03 +08006631 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
6632 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
6633 *output_bool = FALSE;
6634 return RETURN_OK;
6635 }
6636 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s 2> /dev/null | grep UP", interface_name);
6637 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? 0 : 1;
6638 }
developer72fb0bb2023-01-11 09:46:29 +08006639
developer7e4a2a62023-04-06 19:56:03 +08006640 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006641}
6642
developer69b61b02023-03-07 17:17:44 +08006643// Outputs the AP "Enabled" "Disabled" status from driver
6644INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08006645{
developer7e4a2a62023-04-06 19:56:03 +08006646 char cmd[128] = {0};
6647 char buf[128] = {0};
6648 BOOL output_bool;
developer72fb0bb2023-01-11 09:46:29 +08006649
developer7e4a2a62023-04-06 19:56:03 +08006650 if (!output_string) {
6651 printf("%s: null pointer!", __func__);
6652 return RETURN_ERR;
6653 }
developer72fb0bb2023-01-11 09:46:29 +08006654
developer7e4a2a62023-04-06 19:56:03 +08006655 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006656
developer7e4a2a62023-04-06 19:56:03 +08006657 if(output_bool == 1)
6658 snprintf(output_string, 32, "Up");
6659 else
6660 snprintf(output_string, 32, "Disable");
6661
6662 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006663}
6664
6665//Indicates whether or not beacons include the SSID name.
6666// outputs a 1 if SSID on the AP is enabled, else outputs 0
6667INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
6668{
6669 //get the running status
6670 char config_file[MAX_BUF_SIZE] = {0};
6671 char buf[16] = {0};
6672
6673 if (!output)
6674 return RETURN_ERR;
6675
6676 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6677 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
6678 // default is enable
6679 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
6680 *output = TRUE;
6681
6682 return RETURN_OK;
6683}
6684
6685// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
6686INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
6687{
6688 //store the config, apply instantly
6689 char config_file[MAX_BUF_SIZE] = {0};
6690 struct params list;
6691
6692 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6693 list.name = "ignore_broadcast_ssid";
6694 list.value = enable?"0":"1";
6695
6696 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6697 wifi_hostapdWrite(config_file, &list, 1);
6698 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6699 //TODO: call hostapd_cli for dynamic_config_control
6700 wifi_reloadAp(apIndex);
6701 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6702
6703 return RETURN_OK;
6704}
6705
6706//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
6707INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
6708{
6709 //get the running status
6710 if(!output_uint)
6711 return RETURN_ERR;
6712 *output_uint=16;
6713 return RETURN_OK;
6714}
6715
6716INT wifi_setApRetryLimit(INT apIndex, UINT number)
6717{
6718 //apply instantly
6719 return RETURN_ERR;
6720}
6721
6722//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
6723INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
6724{
6725 if(!output)
6726 return RETURN_ERR;
6727 *output=TRUE;
6728 return RETURN_OK;
6729}
6730
6731//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
6732INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
6733{
6734 //get the running status from driver
6735 char cmd[128] = {0};
6736 char buf[128] = {0};
6737 int max_radio_num = 0, radioIndex = 0;
6738 int phyId = 0;
6739
6740 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6741
6742 wifi_getMaxRadioNumber(&max_radio_num);
6743 radioIndex = apIndex % max_radio_num;
6744 phyId = radio_index_to_phy(radioIndex);
6745 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
6746 _syscmd(cmd,buf, sizeof(buf));
6747
6748 if (strlen(buf) > 0)
6749 *output = true;
6750
6751 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6752
6753 return RETURN_OK;
6754}
6755
6756//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
6757INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
6758{
6759 //get the running status from driver
6760 if(!output)
6761 return RETURN_ERR;
6762
6763 char config_file[MAX_BUF_SIZE] = {0};
6764 char buf[16] = {0};
6765
6766 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6767 wifi_hostapdRead(config_file, "wmm_enabled", buf, sizeof(buf));
6768 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
6769 *output = TRUE;
6770 else
6771 *output = FALSE;
6772
6773 return RETURN_OK;
6774}
6775
6776// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
6777INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
6778{
6779 //Save config and apply instantly.
6780 char config_file[MAX_BUF_SIZE] = {0};
6781 struct params list;
6782
6783 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6784 list.name = "wmm_enabled";
6785 list.value = enable?"1":"0";
6786
6787 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6788 wifi_hostapdWrite(config_file, &list, 1);
6789 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6790 wifi_reloadAp(apIndex);
6791 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6792
6793 return RETURN_OK;
6794}
6795
6796//Whether U-APSD support is currently enabled. When enabled, this is indicated in beacon frames. Note: U-APSD can only be enabled if WMM is also enabled.
6797INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
6798{
6799 //get the running status from driver
6800 if(!output)
6801 return RETURN_ERR;
6802
6803 char config_file[128] = {0};
6804 char buf[16] = {0};
6805
6806 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6807 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
6808 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
6809 *output = TRUE;
6810 else
6811 *output = FALSE;
6812
6813 return RETURN_OK;
6814}
6815
6816// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
6817INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
6818{
6819 //save config and apply instantly.
6820 char config_file[MAX_BUF_SIZE] = {0};
6821 struct params list;
6822
6823 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6824 list.name = "uapsd_advertisement_enabled";
6825 list.value = enable?"1":"0";
6826
6827 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6828 wifi_hostapdWrite(config_file, &list, 1);
6829 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developere82c0ca2023-05-10 16:25:35 +08006830 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006831 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6832
6833 return RETURN_OK;
6834}
6835
6836// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
6837INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
6838{
6839 char interface_name[16] = {0};
6840 // assume class 0->BE, 1->BK, 2->VI, 3->VO
6841 char cmd[128] = {0};
6842 char buf[128] = {0};
6843 char ack_filepath[128] = {0};
6844 uint16_t bitmap = 0;
6845 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
6846 FILE *f = NULL;
6847
6848 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6849
6850 // Get current setting
6851 snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
6852 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
6853 _syscmd(cmd, buf, sizeof(buf));
6854 if (strlen(buf) > 0)
6855 bitmap = strtoul(buf, NULL, 10);
6856
6857 bitmap = strtoul(buf, NULL, 10);
6858
6859 if (ackPolicy == TRUE) { // True, unset this class
6860 bitmap &= ~class_map[class];
6861 } else { // False, set this class
6862 bitmap |= class_map[class];
6863 }
6864
6865 f = fopen(ack_filepath, "w");
6866 if (f == NULL) {
6867 fprintf(stderr, "%s: fopen failed\n", __func__);
6868 return RETURN_ERR;
6869 }
6870 fprintf(f, "%hu", bitmap);
6871 fclose(f);
6872
6873 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6874 return RETURN_ERR;
6875 snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
6876 _syscmd(cmd, buf, sizeof(buf));
6877
6878 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6879 return RETURN_OK;
6880}
6881
6882//The maximum number of devices that can simultaneously be connected to the access point. A value of 0 means that there is no specific limit.
6883INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
6884{
6885 //get the running status from driver
6886 if(!output_uint)
6887 return RETURN_ERR;
6888
6889 char output[16]={'\0'};
6890 char config_file[MAX_BUF_SIZE] = {0};
6891
6892 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6893 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
6894 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
6895 else {
6896 int device_num = atoi(output);
6897 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
6898 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
6899 return RETURN_ERR;
6900 }
6901 else {
6902 *output_uint = device_num;
6903 }
6904 }
6905
6906 return RETURN_OK;
6907}
6908
6909INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
6910{
6911 //store to wifi config, apply instantly
6912 char str[MAX_BUF_SIZE]={'\0'};
6913 char cmd[MAX_CMD_SIZE]={'\0'};
6914 struct params params;
6915 char config_file[MAX_BUF_SIZE] = {0};
6916
6917 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6918 if (number > MAX_ASSOCIATED_STA_NUM) {
6919 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
6920 return RETURN_ERR;
6921 }
6922 sprintf(str, "%d", number);
6923 params.name = "max_num_sta";
6924 params.value = str;
6925
6926 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
6927 int ret = wifi_hostapdWrite(config_file, &params, 1);
6928 if (ret) {
6929 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
6930 ,__func__, ret);
6931 }
6932
6933 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
6934 if (ret) {
6935 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
6936 ,__func__, ret);
6937 }
6938 wifi_reloadAp(apIndex);
6939 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6940
6941 return RETURN_OK;
6942}
6943
6944//The HighWatermarkThreshold value that is lesser than or equal to MaxAssociatedDevices. Setting this parameter does not actually limit the number of clients that can associate with this access point as that is controlled by MaxAssociatedDevices. MaxAssociatedDevices or 50. The default value of this parameter should be equal to MaxAssociatedDevices. In case MaxAssociatedDevices is 0 (zero), the default value of this parameter should be 50. A value of 0 means that there is no specific limit and Watermark calculation algorithm should be turned off.
6945INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
6946{
6947 //get the current threshold
6948 if(!output_uint)
6949 return RETURN_ERR;
6950 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
6951 if (*output_uint == 0)
6952 *output_uint = 50;
6953 return RETURN_OK;
6954}
6955
6956INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
6957{
6958 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
6959 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
6960 return RETURN_OK;
6961 return RETURN_ERR;
6962}
6963
6964//Number of times the current total number of associated device has reached the HighWatermarkThreshold value. This calculation can be based on the parameter AssociatedDeviceNumberOfEntries as well. Implementation specifics about this parameter are left to the product group and the device vendors. It can be updated whenever there is a new client association request to the access point.
6965INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
6966{
6967 if(!output_uint)
6968 return RETURN_ERR;
6969 *output_uint = 3;
6970 return RETURN_OK;
6971}
6972
6973//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
6974INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
6975{
6976 if(!output_uint)
6977 return RETURN_ERR;
6978 *output_uint = 3;
6979 return RETURN_OK;
6980}
6981
6982//Date and Time at which the maximum number of associated devices ever associated with the access point concurrenlty since the last reset of the device or WiFi module (or in short when was X_COMCAST-COM_AssociatedDevicesHighWatermark updated). This dateTime value is in UTC.
6983INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
6984{
6985 if(!output_in_seconds)
6986 return RETURN_ERR;
6987 *output_in_seconds = 0;
6988 return RETURN_OK;
6989}
6990
6991//Comma-separated list of strings. Indicates which security modes this AccessPoint instance is capable of supporting. Each list item is an enumeration of: None,WEP-64,WEP-128,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise
6992INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
6993{
6994 if(!output || apIndex>=MAX_APS)
6995 return RETURN_ERR;
6996 //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
6997 snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
6998 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08006999}
developer72fb0bb2023-01-11 09:46:29 +08007000
7001//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
7002INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
7003{
7004 char config_file[128] = {0};
7005 char wpa[16] = {0};
7006 char key_mgmt[64] = {0};
7007 char buf[16] = {0};
7008 if (!output)
7009 return RETURN_ERR;
7010
7011 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7012 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
7013
7014 strcpy(output, "None");//Copying "None" to output string for default case
7015 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
7016 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
7017 if (!strcmp(wpa, "1"))
7018 snprintf(output, 32, "WPA-Personal");
7019 else if (!strcmp(wpa, "2"))
7020 snprintf(output, 32, "WPA2-Personal");
7021 else if (!strcmp(wpa, "3"))
7022 snprintf(output, 32, "WPA-WPA2-Personal");
7023
developere5750452023-05-15 16:46:42 +08007024 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
7025 snprintf(output, 32, "WPA3-Enterprise");
developer72fb0bb2023-01-11 09:46:29 +08007026 } else if (strstr(key_mgmt, "WPA-EAP")) {
7027 if (!strcmp(wpa, "1"))
7028 snprintf(output, 32, "WPA-Enterprise");
7029 else if (!strcmp(wpa, "2"))
7030 snprintf(output, 32, "WPA2-Enterprise");
7031 else if (!strcmp(wpa, "3"))
7032 snprintf(output, 32, "WPA-WPA2-Enterprise");
7033 } else if (strstr(key_mgmt, "SAE")) {
7034 if (strstr(key_mgmt, "WPA-PSK") == NULL)
7035 snprintf(output, 32, "WPA3-Personal");
7036 else
7037 snprintf(output, 32, "WPA3-Personal-Transition");
developer72fb0bb2023-01-11 09:46:29 +08007038 }
7039
7040 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
7041 return RETURN_OK;
7042#if 0
7043 //TODO: need to revisit below implementation
7044 char securityType[32], authMode[32];
7045 int enterpriseMode=0;
7046
7047 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7048 if(!output)
7049 return RETURN_ERR;
7050
7051 wifi_getApBeaconType(apIndex, securityType);
7052 strcpy(output,"None");//By default, copying "None" to output string
7053 if (strncmp(securityType,"None", strlen("None")) == 0)
7054 return RETURN_OK;
7055
7056 wifi_getApBasicAuthenticationMode(apIndex, authMode);
7057 enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0;
7058
7059 if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0)
7060 snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal");
7061 else if (strncmp(securityType, "WPA", strlen("WPA")) == 0)
7062 snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal");
7063 else if (strncmp(securityType, "11i", strlen("11i")) == 0)
7064 snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal");
7065 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7066
7067 return RETURN_OK;
7068#endif
7069}
developer69b61b02023-03-07 17:17:44 +08007070
developer72fb0bb2023-01-11 09:46:29 +08007071INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
7072{
7073 char securityType[32];
7074 char authMode[32];
7075
7076 //store settings and wait for wifi up to apply
7077 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7078 if(!encMode)
7079 return RETURN_ERR;
7080
7081 if (strcmp(encMode, "None")==0)
7082 {
7083 strcpy(securityType,"None");
7084 strcpy(authMode,"None");
7085 }
7086 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
7087 {
7088 strcpy(securityType,"WPAand11i");
7089 strcpy(authMode,"PSKAuthentication");
7090 }
7091 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
7092 {
7093 strcpy(securityType,"WPAand11i");
7094 strcpy(authMode,"EAPAuthentication");
7095 }
7096 else if (strcmp(encMode, "WPA-Personal")==0)
7097 {
7098 strcpy(securityType,"WPA");
7099 strcpy(authMode,"PSKAuthentication");
7100 }
7101 else if (strcmp(encMode, "WPA-Enterprise")==0)
7102 {
7103 strcpy(securityType,"WPA");
7104 strcpy(authMode,"EAPAuthentication");
7105 }
7106 else if (strcmp(encMode, "WPA2-Personal")==0)
7107 {
7108 strcpy(securityType,"11i");
7109 strcpy(authMode,"PSKAuthentication");
7110 }
7111 else if (strcmp(encMode, "WPA2-Enterprise")==0)
7112 {
7113 strcpy(securityType,"11i");
7114 strcpy(authMode,"EAPAuthentication");
7115 }
7116 else if (strcmp(encMode, "WPA3-Personal") == 0)
7117 {
7118 strcpy(securityType,"11i");
7119 strcpy(authMode,"SAEAuthentication");
7120 }
7121 else if (strcmp(encMode, "WPA3-Personal-Transition") == 0)
7122 {
7123 strcpy(securityType, "11i");
7124 strcpy(authMode, "PSK-SAEAuthentication");
7125 }
7126 else if (strcmp(encMode, "WPA3-Enterprise") == 0)
7127 {
7128 strcpy(securityType,"11i");
7129 strcpy(authMode,"EAP_192-bit_Authentication");
7130 }
developer3086e2f2023-01-17 09:40:01 +08007131 else if (strcmp(encMode, "OWE") == 0)
7132 {
7133 strcpy(securityType,"11i");
7134 strcpy(authMode,"Enhanced_Open");
7135 }
developer72fb0bb2023-01-11 09:46:29 +08007136 else
7137 {
7138 strcpy(securityType,"None");
7139 strcpy(authMode,"None");
7140 }
7141 wifi_setApBeaconType(apIndex, securityType);
7142 wifi_setApBasicAuthenticationMode(apIndex, authMode);
7143 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7144
7145 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08007146}
developer72fb0bb2023-01-11 09:46:29 +08007147
7148
7149//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
7150// output_string must be pre-allocated as 64 character string by caller
7151// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
7152INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
7153{
7154 char buf[16] = {0};
7155 char config_file[MAX_BUF_SIZE] = {0};
7156
7157 if(output_string==NULL)
7158 return RETURN_ERR;
7159
7160 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7161 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
7162
7163 if(strcmp(buf,"0")==0)
7164 {
7165 printf("wpa_mode is %s ......... \n",buf);
7166 return RETURN_ERR;
7167 }
7168
7169 wifi_dbg_printf("\nFunc=%s\n",__func__);
7170 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
developere5750452023-05-15 16:46:42 +08007171 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developer72fb0bb2023-01-11 09:46:29 +08007172 wifi_dbg_printf("\noutput_string=%s\n",output_string);
7173
7174 return RETURN_OK;
7175}
7176
7177// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
7178// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
7179INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
7180{
7181 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
7182 struct params params={'\0'};
7183 int ret;
7184 char config_file[MAX_BUF_SIZE] = {0};
7185
7186 if(NULL == preSharedKey)
7187 return RETURN_ERR;
7188
developere5750452023-05-15 16:46:42 +08007189 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +08007190
developere5750452023-05-15 16:46:42 +08007191 if(strlen(preSharedKey) != 64)
developer72fb0bb2023-01-11 09:46:29 +08007192 {
developere5750452023-05-15 16:46:42 +08007193 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
developer72fb0bb2023-01-11 09:46:29 +08007194 return RETURN_ERR;
7195 }
7196 params.value = preSharedKey;
7197 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7198 ret = wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +08007199 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08007200 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08007201 wifi_reloadAp(apIndex);
7202 }
developer72fb0bb2023-01-11 09:46:29 +08007203 return ret;
7204 //TODO: call hostapd_cli for dynamic_config_control
7205}
7206
7207//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
7208// outputs the passphrase, maximum 63 characters
7209INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
7210{
7211 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
7212
7213 wifi_dbg_printf("\nFunc=%s\n",__func__);
7214 if (NULL == output_string)
7215 return RETURN_ERR;
7216
7217 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7218 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
7219 if(strcmp(buf,"0")==0)
7220 {
7221 printf("wpa_mode is %s ......... \n",buf);
7222 return RETURN_ERR;
7223 }
7224
7225 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
7226 wifi_dbg_printf("\noutput_string=%s\n",output_string);
7227
7228 return RETURN_OK;
7229}
7230
7231// sets the passphrase enviornment variable, max 63 characters
7232INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
7233{
7234 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
7235 struct params params={'\0'};
7236 char config_file[MAX_BUF_SIZE] = {0};
7237 int ret;
7238
7239 if(NULL == passPhrase)
7240 return RETURN_ERR;
7241
7242 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
7243 {
7244 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
7245 return RETURN_ERR;
7246 }
7247 params.name = "wpa_passphrase";
7248 params.value = passPhrase;
7249 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7250 ret=wifi_hostapdWrite(config_file,&params,1);
developere5750452023-05-15 16:46:42 +08007251 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08007252 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08007253 wifi_reloadAp(apIndex);
7254 }
developer72fb0bb2023-01-11 09:46:29 +08007255
7256 return ret;
7257}
7258
7259//When set to true, this AccessPoint instance's WiFi security settings are reset to their factory default values. The affected settings include ModeEnabled, WEPKey, PreSharedKey and KeyPassphrase.
7260INT wifi_setApSecurityReset(INT apIndex)
7261{
7262 char original_config_file[64] = {0};
7263 char current_config_file[64] = {0};
7264 char buf[64] = {0};
7265 char cmd[64] = {0};
7266 char wpa[4] = {0};
7267 char wpa_psk[64] = {0};
7268 char wpa_passphrase[64] = {0};
7269 char wpa_psk_file[128] = {0};
7270 char wpa_key_mgmt[64] = {0};
7271 char wpa_pairwise[32] = {0};
7272 wifi_band band;
7273 struct params list[6];
7274
7275 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7276
7277 band = wifi_index_to_band(apIndex);
7278 if (band == band_2_4)
7279 sprintf(original_config_file, "/etc/hostapd-2G.conf");
7280 else if (band == band_5)
7281 sprintf(original_config_file, "/etc/hostapd-5G.conf");
7282 else if (band == band_6)
7283 sprintf(original_config_file, "/etc/hostapd-6G.conf");
7284 else
7285 return RETURN_ERR;
7286
7287 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
7288 list[0].name = "wpa";
7289 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +08007290
developer72fb0bb2023-01-11 09:46:29 +08007291 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
7292 list[1].name = "wpa_psk";
7293 list[1].value = wpa_psk;
7294
7295 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
7296 list[2].name = "wpa_passphrase";
7297 list[2].value = wpa_passphrase;
7298
7299 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
7300
7301 if (strlen(wpa_psk_file) == 0)
7302 strcpy(wpa_psk_file, PSK_FILE);
7303
7304 if (access(wpa_psk_file, F_OK) != 0) {
7305 sprintf(cmd, "touch %s", wpa_psk_file);
7306 _syscmd(cmd, buf, sizeof(buf));
7307 }
7308 list[3].name = "wpa_psk_file";
7309 list[3].value = wpa_psk_file;
7310
7311 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
7312 list[4].name = "wpa_key_mgmt";
7313 list[4].value = wpa_key_mgmt;
7314
7315 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
7316 list[5].name = "wpa_pairwise";
7317 list[5].value = wpa_pairwise;
7318
7319 sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7320 wifi_hostapdWrite(current_config_file, list, 6);
7321
7322 wifi_setApEnable(apIndex, FALSE);
7323 wifi_setApEnable(apIndex, TRUE);
7324
7325 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7326 return RETURN_OK;
7327}
7328
7329//The IP Address and port number of the RADIUS server used for WLAN security. RadiusServerIPAddr is only applicable when ModeEnabled is an Enterprise type (i.e. WPA-Enterprise, WPA2-Enterprise or WPA-WPA2-Enterprise).
7330INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
7331{
7332 char config_file[64] = {0};
7333 char buf[64] = {0};
7334 char cmd[256] = {0};
7335
7336 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7337
7338 if(!IP_output || !Port_output || !RadiusSecret_output)
7339 return RETURN_ERR;
7340
7341 // Read the first matched config
7342 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7343 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
7344 _syscmd(cmd, buf, sizeof(buf));
7345 strncpy(IP_output, buf, 64);
7346
7347 memset(buf, 0, sizeof(buf));
7348 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
7349 _syscmd(cmd, buf, sizeof(buf));
7350 *Port_output = atoi(buf);
7351
7352 memset(buf, 0, sizeof(buf));
7353 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
7354 _syscmd(cmd, buf, sizeof(buf));
7355 strncpy(RadiusSecret_output, buf, 64);
7356
7357 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7358 return RETURN_OK;
7359}
7360
7361INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
7362{
7363 char config_file[64] = {0};
7364 char port_str[8] = {0};
7365 char cmd[256] = {0};
7366 char buf[128] = {0};
7367
7368 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7369
developere5750452023-05-15 16:46:42 +08007370 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
7371 return RETURN_ERR;
7372
7373 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
7374 return RETURN_ERR;
7375
developer72fb0bb2023-01-11 09:46:29 +08007376 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7377
7378 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
7379 _syscmd(cmd, buf, sizeof(buf));
7380 memset(cmd, 0, sizeof(cmd));
7381
7382 snprintf(port_str, sizeof(port_str), "%d", port);
7383 if (strlen(buf) == 0)
7384 // Append
7385 snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
7386 "auth_server_addr=%s\\n"
7387 "auth_server_port=%s\\n"
7388 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
7389 else {
7390 // Delete the three lines setting after the "# radius 1" comment
7391 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
7392 _syscmd(cmd, buf, sizeof(buf));
7393 memset(cmd, 0, sizeof(cmd));
7394 // Use "# radius 1" comment to find the location to insert the radius setting
7395 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
7396 "# radius 1\\n"
7397 "auth_server_addr=%s\\n"
7398 "auth_server_port=%s\\n"
7399 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
7400 }
7401 if(_syscmd(cmd, buf, sizeof(buf))) {
7402 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
7403 return RETURN_ERR;
7404 }
7405
7406 wifi_reloadAp(apIndex);
7407 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7408 return RETURN_OK;
7409}
7410
7411INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
7412{
7413 char config_file[64] = {0};
7414 char buf[64] = {0};
7415 char cmd[256] = {0};
7416
7417 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7418
7419 if(!IP_output || !Port_output || !RadiusSecret_output)
7420 return RETURN_ERR;
7421
7422 // Read the second matched config
7423 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7424 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
7425 _syscmd(cmd, buf, sizeof(buf));
7426 strncpy(IP_output, buf, 64);
7427
7428 memset(buf, 0, sizeof(buf));
7429 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
7430 _syscmd(cmd, buf, sizeof(buf));
7431 *Port_output = atoi(buf);
7432
7433 memset(buf, 0, sizeof(buf));
7434 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
7435 _syscmd(cmd, buf, sizeof(buf));
7436 strncpy(RadiusSecret_output, buf, 64);
7437
7438 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7439 return RETURN_OK;
7440}
7441
7442INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
7443{
7444 char config_file[64] = {0};
7445 char port_str[8] = {0};
7446 char cmd[256] = {0};
7447 char buf[128] = {0};
7448
7449 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7450
developere5750452023-05-15 16:46:42 +08007451 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
7452 return RETURN_ERR;
7453
7454 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
7455 return RETURN_ERR;
7456
developer72fb0bb2023-01-11 09:46:29 +08007457 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7458
7459 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
7460 _syscmd(cmd, buf, sizeof(buf));
7461 memset(cmd, 0, sizeof(cmd));
7462
7463 snprintf(port_str, sizeof(port_str), "%d", port);
7464 if (strlen(buf) == 0)
7465 // Append
7466 snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
7467 "auth_server_addr=%s\\n"
7468 "auth_server_port=%s\\n"
7469 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
7470 else {
7471 // Delete the three lines setting after the "# radius 2" comment
7472 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
7473 _syscmd(cmd, buf, sizeof(buf));
7474 memset(cmd, 0, sizeof(cmd));
7475 // Use "# radius 2" comment to find the location to insert the radius setting
7476 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
7477 "# radius 2\\n"
7478 "auth_server_addr=%s\\n"
7479 "auth_server_port=%s\\n"
7480 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
7481 }
7482 if(_syscmd(cmd, buf, sizeof(buf))) {
7483 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
7484 return RETURN_ERR;
7485 }
7486
7487 wifi_reloadAp(apIndex);
7488 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7489 return RETURN_OK;
7490}
7491
7492//RadiusSettings
7493INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
7494{
7495 if(!output)
7496 return RETURN_ERR;
7497
7498 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
developer69b61b02023-03-07 17:17:44 +08007499 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
7500 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
7501 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
7502 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
developer72fb0bb2023-01-11 09:46:29 +08007503 output->MaxAuthenticationAttempts = 3; //Indicates the # of time, a client can attempt to login with incorrect credentials. When this limit is reached, the client is blacklisted and not allowed to attempt loging into the network. Settings this parameter to 0 (zero) disables the blacklisting feature.
developer69b61b02023-03-07 17:17:44 +08007504 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
7505 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
7506 output->QuietPeriodAfterFailedAuthentication = 5; //The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it.
developer72fb0bb2023-01-11 09:46:29 +08007507 //snprintf(output->RadiusSecret, 64, "12345678"); //The secret used for handshaking with the RADIUS server [RFC2865]. When read, this parameter returns an empty string, regardless of the actual value.
7508
7509 return RETURN_OK;
7510}
7511
7512INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
7513{
7514 //store the paramters, and apply instantly
7515 return RETURN_ERR;
7516}
7517
7518//Device.WiFi.AccessPoint.{i}.WPS.Enable
7519//Enables or disables WPS functionality for this access point.
7520// outputs the WPS enable state of this ap in output_bool
7521INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
7522{
7523 char interface_name[16] = {0};
7524 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
7525 if(!output_bool)
7526 return RETURN_ERR;
7527 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7528 return RETURN_ERR;
7529 sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name);
7530 _syscmd(cmd, buf, sizeof(buf));
7531 if(strstr(buf, "configured"))
7532 *output_bool=TRUE;
7533 else
7534 *output_bool=FALSE;
7535
7536 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08007537}
developer72fb0bb2023-01-11 09:46:29 +08007538
7539//Device.WiFi.AccessPoint.{i}.WPS.Enable
7540// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
7541INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
7542{
7543 char config_file[MAX_BUF_SIZE] = {0};
developere5750452023-05-15 16:46:42 +08007544 char buf[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007545 struct params params;
7546
7547 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7548 //store the paramters, and wait for wifi up to apply
7549 params.name = "wps_state";
developere5750452023-05-15 16:46:42 +08007550 if (enable == TRUE) {
7551 wifi_getApBeaconType(apIndex, buf);
7552 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
7553 params.value = "1";
7554 else // If ap set encryption
7555 params.value = "2";
7556 } else {
7557 params.value = "0";
7558 }
developer72fb0bb2023-01-11 09:46:29 +08007559
7560 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7561 wifi_hostapdWrite(config_file, &params, 1);
7562 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7563 wifi_reloadAp(apIndex);
7564
7565 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7566 return RETURN_OK;
7567}
7568
7569//Comma-separated list of strings. Indicates WPS configuration methods supported by the device. Each list item is an enumeration of: USBFlashDrive,Ethernet,ExternalNFCToken,IntegratedNFCToken,NFCInterface,PushButton,PIN
7570INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
7571{
7572 if(!output)
7573 return RETURN_ERR;
7574 snprintf(output, 128, "PushButton,PIN");
7575 return RETURN_OK;
7576}
7577
7578//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
7579//Comma-separated list of strings. Each list item MUST be a member of the list reported by the ConfigMethodsSupported parameter. Indicates WPS configuration methods enabled on the device.
7580// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
7581INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
7582{
7583 if(!output)
7584 return RETURN_ERR;
7585 snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
7586
7587 return RETURN_OK;
7588}
7589
7590//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
7591// sets an enviornment variable that specifies the WPS configuration method(s). methodString is a comma separated list of methods USBFlashDrive,Ethernet,ExternalNFCToken,IntegratedNFCToken,NFCInterface,PushButton,PIN
7592INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
7593{
7594 //apply instantly. No setting need to be stored.
7595 char methods[MAX_BUF_SIZE], *token, *next_token;
7596 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
7597 struct params params;
7598
7599 if(!methodString)
7600 return RETURN_ERR;
7601 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7602 //store the paramters, and wait for wifi up to apply
7603
7604 snprintf(methods, sizeof(methods), "%s", methodString);
7605 for(token=methods; *token; token=next_token)
7606 {
7607 strtok_r(token, ",", &next_token);
7608 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
7609 snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
7610 else if(*token=='E')
7611 {
7612 if(!strcmp(methods, "Ethernet"))
7613 snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
7614 else if(!strcmp(methods, "ExternalNFCToken"))
7615 snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
7616 else
7617 printf("%s: Unknown WpsConfigMethod\n", __func__);
7618 }
7619 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
7620 snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
7621 else if(*token=='N' && !strcmp(token, "NFCInterface"))
7622 snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
7623 else if(*token=='P' )
7624 {
7625 if(!strcmp(token, "PushButton"))
developere5750452023-05-15 16:46:42 +08007626 snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developer72fb0bb2023-01-11 09:46:29 +08007627 else if(!strcmp(token, "PIN"))
7628 snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
7629 else
7630 printf("%s: Unknown WpsConfigMethod\n", __func__);
7631 }
7632 else
7633 printf("%s: Unknown WpsConfigMethod\n", __func__);
7634 }
7635 params.name = "config_methods";
7636 params.value = config_methods;
7637 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7638 wifi_hostapdWrite(config_file, &params, 1);
7639 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7640 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7641
7642 return RETURN_OK;
7643}
7644
7645// outputs the pin value, ulong_pin must be allocated by the caller
7646INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
7647{
7648 char buf[MAX_BUF_SIZE] = {0};
7649 char cmd[MAX_CMD_SIZE] = {0};
7650
7651 if(!output_ulong)
7652 return RETURN_ERR;
7653 snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
7654 _syscmd(cmd, buf, sizeof(buf));
7655 if(strlen(buf) > 0)
7656 *output_ulong=strtoul(buf, NULL, 10);
7657
7658 return RETURN_OK;
7659}
7660
7661// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
7662INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
7663{
7664 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
7665 char ap_pin[16] = {0};
7666 char buf[MAX_BUF_SIZE] = {0};
7667 char config_file[MAX_BUF_SIZE] = {0};
7668 ULONG prev_pin = 0;
7669 struct params params;
7670
7671 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7672 snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
7673 params.name = "ap_pin";
7674 params.value = ap_pin;
7675 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7676 wifi_hostapdWrite(config_file, &params, 1);
7677 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7678 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7679
7680 return RETURN_OK;
7681}
7682
7683// Output string is either Not configured or Configured, max 32 characters
7684INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
7685{
7686 char interface_name[16] = {0};
7687 char cmd[MAX_CMD_SIZE];
7688 char buf[MAX_BUF_SIZE]={0};
7689
7690 if(!output_string)
7691 return RETURN_ERR;
7692 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7693 snprintf(output_string, 32, "Not configured");
7694 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7695 return RETURN_ERR;
7696 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
7697 _syscmd(cmd, buf, sizeof(buf));
7698
7699 if(!strncmp(buf, "configured", 10))
7700 snprintf(output_string, 32, "Configured");
7701 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7702
7703 return RETURN_OK;
7704}
7705
7706// sets the WPS pin for this AP
7707INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
7708{
7709 char interface_name[16] = {0};
7710 char cmd[MAX_CMD_SIZE];
7711 char buf[MAX_BUF_SIZE]={0};
7712 BOOL enable;
7713
7714 wifi_getApEnable(apIndex, &enable);
7715 if (!enable)
7716 return RETURN_ERR;
7717 wifi_getApWpsEnable(apIndex, &enable);
7718 if (!enable)
7719 return RETURN_ERR;
7720
7721 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7722 return RETURN_ERR;
7723 snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
7724 _syscmd(cmd, buf, sizeof(buf));
7725 if((strstr(buf, "OK"))!=NULL)
7726 return RETURN_OK;
7727
7728 return RETURN_ERR;
7729}
7730
7731// This function is called when the WPS push button has been pressed for this AP
7732INT wifi_setApWpsButtonPush(INT apIndex)
7733{
7734 char cmd[MAX_CMD_SIZE];
7735 char buf[MAX_BUF_SIZE]={0};
7736 char interface_name[16] = {0};
7737 BOOL enable=FALSE;
7738
7739 wifi_getApEnable(apIndex, &enable);
7740 if (!enable)
7741 return RETURN_ERR;
7742
7743 wifi_getApWpsEnable(apIndex, &enable);
7744 if (!enable)
7745 return RETURN_ERR;
7746
7747 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7748 return RETURN_ERR;
7749
7750 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
7751 _syscmd(cmd, buf, sizeof(buf));
7752
7753 if((strstr(buf, "OK"))!=NULL)
7754 return RETURN_OK;
7755 return RETURN_ERR;
7756}
7757
7758// cancels WPS mode for this AP
7759INT wifi_cancelApWPS(INT apIndex)
7760{
7761 char interface_name[16] = {0};
7762 char cmd[MAX_CMD_SIZE];
7763 char buf[MAX_BUF_SIZE]={0};
7764
7765 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7766 return RETURN_ERR;
7767 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
7768 _syscmd(cmd,buf, sizeof(buf));
7769
7770 if((strstr(buf, "OK"))!=NULL)
7771 return RETURN_OK;
7772 return RETURN_ERR;
7773}
7774
7775//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
7776//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
7777INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
7778{
7779 char interface_name[16] = {0};
7780 FILE *f = NULL;
7781 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
7782 char cmd[256] = {0}, buf[2048] = {0};
7783 char *param = NULL, *value = NULL, *line=NULL;
7784 size_t len = 0;
7785 ssize_t nread = 0;
7786 wifi_associated_dev_t *dev=NULL;
7787
7788 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7789 *associated_dev_array = NULL;
7790 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7791 return RETURN_ERR;
7792 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
7793 _syscmd(cmd,buf,sizeof(buf));
7794 *output_array_size = atoi(buf);
7795
7796 if (*output_array_size <= 0)
7797 return RETURN_OK;
7798
7799 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
7800 *associated_dev_array = dev;
7801 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
7802 _syscmd(cmd,buf,sizeof(buf));
7803 f = fopen("/tmp/connected_devices.txt", "r");
7804 if (f==NULL)
7805 {
7806 *output_array_size=0;
7807 return RETURN_ERR;
7808 }
7809 while ((getline(&line, &len, f)) != -1)
7810 {
7811 param = strtok(line,"=");
7812 value = strtok(NULL,"=");
7813
7814 if( strcmp("flags",param) == 0 )
7815 {
7816 value[strlen(value)-1]='\0';
7817 if(strstr (value,"AUTHORIZED") != NULL )
7818 {
7819 dev[auth_temp].cli_AuthenticationState = 1;
7820 dev[auth_temp].cli_Active = 1;
7821 auth_temp++;
7822 read_flag=1;
7823 }
7824 }
7825 if(read_flag==1)
7826 {
7827 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
7828 {
7829 value[strlen(value)-1]='\0';
7830 sscanf(value, "%x:%x:%x:%x:%x:%x",
7831 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
7832 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
7833 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
7834 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
7835 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
7836 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
7837 mac_temp++;
7838 read_flag=0;
7839 }
7840 }
7841 }
7842 *output_array_size = auth_temp;
7843 auth_temp=0;
7844 mac_temp=0;
7845 free(line);
7846 fclose(f);
7847 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7848 return RETURN_OK;
7849}
7850
7851#define MACADDRESS_SIZE 6
7852
7853INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
7854{
7855 FILE *fp = NULL;
7856 char str[MAX_BUF_SIZE] = {0};
7857 int wificlientindex = 0 ;
7858 int count = 0;
7859 int signalstrength = 0;
7860 int arr[MACADDRESS_SIZE] = {0};
7861 unsigned char mac[MACADDRESS_SIZE] = {0};
7862 UINT wifi_count = 0;
7863 char virtual_interface_name[MAX_BUF_SIZE] = {0};
7864 char pipeCmd[MAX_CMD_SIZE] = {0};
7865
7866 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7867 *output_array_size = 0;
7868 *associated_dev_array = NULL;
7869
7870 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
7871 fp = popen(pipeCmd, "r");
developer69b61b02023-03-07 17:17:44 +08007872 if (fp == NULL)
developer72fb0bb2023-01-11 09:46:29 +08007873 {
7874 printf("Failed to run command inside function %s\n",__FUNCTION__ );
7875 return RETURN_ERR;
7876 }
7877
7878 /* Read the output a line at a time - output it. */
7879 fgets(str, sizeof(str)-1, fp);
7880 wifi_count = (unsigned int) atoi ( str );
7881 *output_array_size = wifi_count;
7882 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
7883 pclose(fp);
7884
7885 if(wifi_count == 0)
7886 {
7887 return RETURN_OK;
7888 }
7889 else
7890 {
7891 wifi_associated_dev3_t* temp = NULL;
7892 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
7893 if(temp == NULL)
7894 {
7895 printf("Error Statement. Insufficient memory \n");
7896 return RETURN_ERR;
7897 }
7898
7899 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
7900 system(pipeCmd);
7901 memset(pipeCmd,0,sizeof(pipeCmd));
7902 if(apIndex == 0)
7903 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
7904 else if(apIndex == 1)
7905 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
7906 system(pipeCmd);
7907
7908 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
7909 if(fp == NULL)
7910 {
7911 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
7912 free(temp);
7913 return RETURN_ERR;
7914 }
7915 fclose(fp);
7916
7917 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
7918 fp = popen(pipeCmd, "r");
7919 if(fp)
7920 {
7921 for(count =0 ; count < wifi_count; count++)
7922 {
7923 fgets(str, MAX_BUF_SIZE, fp);
7924 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
7925 {
7926 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
7927 {
7928 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
7929
7930 }
7931 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
7932 printf("MAC %d = %X:%X:%X:%X:%X:%X \n", count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]);
7933 }
7934 temp[count].cli_AuthenticationState = 1; //TODO
7935 temp[count].cli_Active = 1; //TODO
7936 }
7937 pclose(fp);
7938 }
7939
7940 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
7941 fp = popen(pipeCmd, "r");
7942 if(fp)
developer69b61b02023-03-07 17:17:44 +08007943 {
developer72fb0bb2023-01-11 09:46:29 +08007944 pclose(fp);
7945 }
7946 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
7947 if(fp)
7948 {
7949 for(count =0 ; count < wifi_count ;count++)
7950 {
7951 fgets(str, MAX_BUF_SIZE, fp);
7952 signalstrength = atoi(str);
7953 temp[count].cli_SignalStrength = signalstrength;
7954 temp[count].cli_RSSI = signalstrength;
7955 temp[count].cli_SNR = signalstrength + 95;
7956 }
7957 pclose(fp);
7958 }
7959
7960
7961 if((apIndex == 0) || (apIndex == 4))
7962 {
7963 for(count =0 ; count < wifi_count ;count++)
developer69b61b02023-03-07 17:17:44 +08007964 {
developer72fb0bb2023-01-11 09:46:29 +08007965 strcpy(temp[count].cli_OperatingStandard,"g");
7966 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
7967 }
7968
7969 //BytesSent
7970 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
7971 fp = popen(pipeCmd, "r");
7972 if(fp)
developer69b61b02023-03-07 17:17:44 +08007973 {
developer72fb0bb2023-01-11 09:46:29 +08007974 pclose(fp);
7975 }
7976 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
7977 if(fp)
7978 {
7979 for (count = 0; count < wifi_count; count++)
7980 {
7981 fgets(str, MAX_BUF_SIZE, fp);
7982 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
7983 }
7984 pclose(fp);
7985 }
7986
7987 //BytesReceived
7988 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
7989 fp = popen(pipeCmd, "r");
7990 if (fp)
7991 {
7992 pclose(fp);
7993 }
7994 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
7995 if (fp)
7996 {
7997 for (count = 0; count < wifi_count; count++)
7998 {
7999 fgets(str, MAX_BUF_SIZE, fp);
8000 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
8001 }
8002 pclose(fp);
8003 }
8004
8005 //PacketsSent
8006 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
8007 fp = popen(pipeCmd, "r");
8008 if (fp)
8009 {
8010 pclose(fp);
8011 }
8012
8013 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
8014 if (fp)
8015 {
8016 for (count = 0; count < wifi_count; count++)
8017 {
8018 fgets(str, MAX_BUF_SIZE, fp);
8019 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
8020 }
8021 pclose(fp);
8022 }
8023
8024 //PacketsReceived
8025 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
8026 fp = popen(pipeCmd, "r");
8027 if (fp)
8028 {
8029 pclose(fp);
8030 }
8031 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
8032 if (fp)
8033 {
8034 for (count = 0; count < wifi_count; count++)
8035 {
8036 fgets(str, MAX_BUF_SIZE, fp);
8037 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
8038 }
8039 pclose(fp);
8040 }
8041
8042 //ErrorsSent
8043 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
8044 fp = popen(pipeCmd, "r");
8045 if (fp)
8046 {
8047 pclose(fp);
8048 }
8049 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
8050 if (fp)
8051 {
8052 for (count = 0; count < wifi_count; count++)
8053 {
8054 fgets(str, MAX_BUF_SIZE, fp);
8055 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
8056 }
8057 pclose(fp);
8058 }
8059
8060 //ErrorsSent
8061 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
8062 fp = popen(pipeCmd, "r");
8063 if (fp)
8064 {
8065 pclose(fp);
8066 }
8067 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
8068 if (fp)
8069 {
8070 for (count = 0; count < wifi_count; count++)
8071 {
8072 fgets(str, MAX_BUF_SIZE, fp);
8073 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
8074 }
8075 pclose(fp);
8076 }
8077
8078 //LastDataDownlinkRate
8079 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
8080 fp = popen(pipeCmd, "r");
8081 if (fp)
8082 {
8083 pclose(fp);
8084 }
8085 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
8086 if (fp)
8087 {
8088 for (count = 0; count < wifi_count; count++)
8089 {
8090 fgets(str, MAX_BUF_SIZE, fp);
8091 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
8092 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
8093 }
8094 pclose(fp);
8095 }
8096
8097 //LastDataUplinkRate
8098 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
8099 fp = popen(pipeCmd, "r");
8100 if (fp)
8101 {
8102 pclose(fp);
8103 }
8104 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
8105 if (fp)
8106 {
8107 for (count = 0; count < wifi_count; count++)
8108 {
8109 fgets(str, MAX_BUF_SIZE, fp);
8110 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
8111 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
8112 }
8113 pclose(fp);
8114 }
8115
8116 }
8117 else if ((apIndex == 1) || (apIndex == 5))
8118 {
8119 for (count = 0; count < wifi_count; count++)
8120 {
8121 strcpy(temp[count].cli_OperatingStandard, "a");
8122 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
8123 temp[count].cli_BytesSent = 0;
8124 temp[count].cli_BytesReceived = 0;
8125 temp[count].cli_LastDataUplinkRate = 0;
8126 temp[count].cli_LastDataDownlinkRate = 0;
8127 temp[count].cli_PacketsSent = 0;
8128 temp[count].cli_PacketsReceived = 0;
8129 temp[count].cli_ErrorsSent = 0;
8130 }
8131 }
8132
8133 for (count = 0; count < wifi_count; count++)
8134 {
8135 temp[count].cli_Retransmissions = 0;
8136 temp[count].cli_DataFramesSentAck = 0;
8137 temp[count].cli_DataFramesSentNoAck = 0;
8138 temp[count].cli_MinRSSI = 0;
8139 temp[count].cli_MaxRSSI = 0;
8140 strncpy(temp[count].cli_InterferenceSources, "", 64);
8141 memset(temp[count].cli_IPAddress, 0, 64);
8142 temp[count].cli_RetransCount = 0;
8143 temp[count].cli_FailedRetransCount = 0;
8144 temp[count].cli_RetryCount = 0;
8145 temp[count].cli_MultipleRetryCount = 0;
8146 }
8147 *associated_dev_array = temp;
8148 }
8149 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8150 return RETURN_OK;
8151}
8152
developer7e4a2a62023-04-06 19:56:03 +08008153int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +08008154{
developer7e4a2a62023-04-06 19:56:03 +08008155 char cmd[MAX_CMD_SIZE] = {0};
8156 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008157
developer7e4a2a62023-04-06 19:56:03 +08008158 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
8159
8160 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
8161 interface_name);
8162 _syscmd(cmd, buf, MAX_BUF_SIZE);
8163
8164 strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */
8165
8166 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008167 return RETURN_OK;
8168}
8169
8170/* #define HOSTAPD_STA_PARAM_ENTRIES 29
8171struct hostapd_sta_param {
8172 char key[50];
8173 char value[100];
8174}
8175
8176static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){
8177 int i = 0;
8178
8179 while(i<HOSTAPD_STA_PARAM_ENTRIES) {
8180 if (strncmp(params[i].key,key,50) == 0){
8181 return &params[i].value;
8182 }
8183 i++;
8184 }
8185 return NULL;
8186
8187} */
8188
8189static unsigned int count_occurences(const char *buf, const char *word)
8190{
8191 unsigned int n = 0;
8192 char *ptr = strstr(buf, word);
8193
8194 while (ptr++) {
8195 n++;
8196 ptr = strstr(ptr, word);
8197 }
8198
8199 wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word);
8200 return n;
8201}
8202
8203static const char *get_line_from_str_buf(const char *buf, char *line)
8204{
8205 int i;
8206 int n = strlen(buf);
8207
8208 for (i = 0; i < n; i++) {
8209 line[i] = buf[i];
8210 if (buf[i] == '\n') {
8211 line[i] = '\0';
8212 return &buf[i + 1];
8213 }
8214 }
8215
8216 return NULL;
8217}
8218
8219INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
8220{
8221 unsigned int assoc_cnt = 0;
8222 char interface_name[50] = {0};
8223 char buf[MAX_BUF_SIZE * 50]= {'\0'}; // Increase this buffer if more fields are added to 'iw dev' output filter
8224 char cmd[MAX_CMD_SIZE] = {'\0'};
8225 char line[256] = {'\0'};
8226 int i = 0;
8227 int ret = 0;
8228 const char *ptr = NULL;
8229 char *key = NULL;
8230 char *val = NULL;
8231 wifi_associated_dev3_t *temp = NULL;
8232 int rssi;
8233
8234 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8235
8236 if (wifi_getApName(apIndex, interface_name) != RETURN_OK) {
8237 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
8238 return RETURN_ERR;
8239 }
8240
8241 // Example filtered output of 'iw dev' command:
8242 // Station 0a:69:72:10:d2:fa (on wifi0)
8243 // signal avg:-67 [-71, -71] dBm
8244 // Station 28:c2:1f:25:5f:99 (on wifi0)
8245 // signal avg:-67 [-71, -70] dBm
8246 if (sprintf(cmd,"iw dev %s station dump | tr -d '\\t' | grep 'Station\\|signal avg'", interface_name) < 0) {
8247 wifi_dbg_printf("%s: failed to build iw dev command for %s\n", __FUNCTION__, interface_name);
8248 return RETURN_ERR;
8249 }
8250
8251 ret = _syscmd(cmd, buf, sizeof(buf));
8252 if (ret == RETURN_ERR) {
8253 wifi_dbg_printf("%s: failed to execute '%s' for %s\n", __FUNCTION__, cmd, interface_name);
8254 return RETURN_ERR;
8255 }
8256
8257 *output_array_size = count_occurences(buf, "Station");
8258 if (*output_array_size == 0) return RETURN_OK;
8259
8260 temp = calloc(*output_array_size, sizeof(wifi_associated_dev3_t));
8261 if (temp == NULL) {
8262 wifi_dbg_printf("%s: failed to allocate dev array for %s\n", __FUNCTION__, interface_name);
8263 return RETURN_ERR;
8264 }
8265 *associated_dev_array = temp;
8266
8267 wifi_dbg_printf("%s: array_size = %u\n", __FUNCTION__, *output_array_size);
8268 ptr = get_line_from_str_buf(buf, line);
8269 i = -1;
8270 while (ptr) {
8271 if (strstr(line, "Station")) {
8272 i++;
8273 key = strtok(line, " ");
8274 val = strtok(NULL, " ");
8275 if (sscanf(val, "%02x:%02x:%02x:%02x:%02x:%02x",
8276 &temp[i].cli_MACAddress[0],
8277 &temp[i].cli_MACAddress[1],
8278 &temp[i].cli_MACAddress[2],
8279 &temp[i].cli_MACAddress[3],
8280 &temp[i].cli_MACAddress[4],
8281 &temp[i].cli_MACAddress[5]) != MACADDRESS_SIZE) {
8282 wifi_dbg_printf("%s: failed to parse MAC of client connected to %s\n", __FUNCTION__, interface_name);
8283 free(*associated_dev_array);
8284 return RETURN_ERR;
8285 }
8286 }
8287 else if (i < 0) {
8288 ptr = get_line_from_str_buf(ptr, line);
8289 continue; // We didn't detect 'station' entry yet
8290 }
8291 else if (strstr(line, "signal avg")) {
8292 key = strtok(line, ":");
8293 val = strtok(NULL, " ");
8294 if (sscanf(val, "%d", &rssi) <= 0 ) {
8295 wifi_dbg_printf("%s: failed to parse RSSI of client connected to %s\n", __FUNCTION__, interface_name);
8296 free(*associated_dev_array);
8297 return RETURN_ERR;
8298 }
8299 temp[i].cli_RSSI = rssi;
8300 temp[i].cli_SNR = 95 + rssi; // We use constant -95 noise floor
8301 }
8302 // Here other fields can be parsed if added to filter of 'iw dev' command
8303
8304 ptr = get_line_from_str_buf(ptr, line);
8305 };
8306
8307 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8308
8309 return RETURN_OK;
8310}
8311
8312#if 0
8313//To-do
8314INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
8315{
8316 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8317
8318 //Using different approach to get required WiFi Parameters from system available commands
developer69b61b02023-03-07 17:17:44 +08008319#if 0
developer72fb0bb2023-01-11 09:46:29 +08008320 FILE *f;
8321 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
8322 char cmd[256], buf[2048];
8323 char *param , *value, *line=NULL;
8324 size_t len = 0;
8325 ssize_t nread;
8326 wifi_associated_dev3_t *dev=NULL;
8327 *associated_dev_array = NULL;
8328 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
8329 _syscmd(cmd,buf,sizeof(buf));
8330 *output_array_size = atoi(buf);
8331
8332 if (*output_array_size <= 0)
8333 return RETURN_OK;
8334
8335 dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t));
8336 *associated_dev_array = dev;
8337 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name);
8338 _syscmd(cmd,buf,sizeof(buf));
8339 f = fopen("/tmp/connected_devices.txt", "r");
8340 if (f==NULL)
8341 {
8342 *output_array_size=0;
8343 return RETURN_ERR;
8344 }
8345 while ((nread = getline(&line, &len, f)) != -1)
8346 {
8347 param = strtok(line,"=");
8348 value = strtok(NULL,"=");
8349
8350 if( strcmp("flags",param) == 0 )
8351 {
8352 value[strlen(value)-1]='\0';
8353 if(strstr (value,"AUTHORIZED") != NULL )
8354 {
8355 dev[auth_temp].cli_AuthenticationState = 1;
8356 dev[auth_temp].cli_Active = 1;
8357 auth_temp++;
8358 read_flag=1;
8359 }
8360 }
8361 if(read_flag==1)
8362 {
8363 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
8364 {
8365 value[strlen(value)-1]='\0';
8366 sscanf(value, "%x:%x:%x:%x:%x:%x",
8367 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
8368 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
8369 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
8370 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
8371 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
8372 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
8373
8374 }
8375 else if( strcmp("rx_packets",param) == 0 )
8376 {
8377 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived));
8378 }
8379
8380 else if( strcmp("tx_packets",param) == 0 )
8381 {
developer69b61b02023-03-07 17:17:44 +08008382 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent));
developer72fb0bb2023-01-11 09:46:29 +08008383 }
8384
8385 else if( strcmp("rx_bytes",param) == 0 )
8386 {
8387 sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived));
8388 }
8389
8390 else if( strcmp("tx_bytes",param) == 0 )
8391 {
developer69b61b02023-03-07 17:17:44 +08008392 sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent));
developer72fb0bb2023-01-11 09:46:29 +08008393 mac_temp++;
8394 read_flag=0;
developer69b61b02023-03-07 17:17:44 +08008395 }
developer72fb0bb2023-01-11 09:46:29 +08008396 }
8397 }
8398
8399 *output_array_size = auth_temp;
8400 auth_temp=0;
8401 mac_temp=0;
8402 free(line);
8403 fclose(f);
8404#endif
8405 char interface_name[MAX_BUF_SIZE] = {0};
8406 char wifi_status[MAX_BUF_SIZE] = {0};
8407 char hostapdconf[MAX_BUF_SIZE] = {0};
8408
8409 wifi_associated_dev3_t *dev_array = NULL;
8410 ULONG wifi_count = 0;
8411
8412 *associated_dev_array = NULL;
8413 *output_array_size = 0;
8414
8415 printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex);
8416 //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI.
8417 {
8418 sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex);
8419
8420 wifi_GetInterfaceName(interface_name, hostapdconf);
8421
8422 if(strlen(interface_name) > 1)
8423 {
8424 wifihal_interfacestatus(wifi_status,interface_name);
8425 if(strcmp(wifi_status,"RUNNING") == 0)
8426 {
8427 wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count);
8428
8429 *associated_dev_array = dev_array;
developer69b61b02023-03-07 17:17:44 +08008430 *output_array_size = wifi_count;
developer72fb0bb2023-01-11 09:46:29 +08008431 }
8432 else
8433 {
8434 *associated_dev_array = NULL;
8435 }
8436 }
8437 }
8438
8439 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8440 return RETURN_OK;
8441}
8442#endif
8443
8444/* getIPAddress function */
8445/**
8446* @description Returning IpAddress of the Matched String
8447*
developer69b61b02023-03-07 17:17:44 +08008448* @param
developer72fb0bb2023-01-11 09:46:29 +08008449* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +08008450* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +08008451* @return The status of the operation
8452* @retval RETURN_OK if successful
8453* @retval RETURN_ERR if any error is detected
8454*
8455*/
8456
8457INT getIPAddress(char *str,char *ipaddr)
8458{
8459 FILE *fp = NULL;
8460 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
8461 int LeaseTime = 0,ret = 0;
8462 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
8463 {
8464 return RETURN_ERR;
8465 }
8466
8467 while ( fgets(buf, sizeof(buf), fp)!= NULL )
8468 {
8469 /*
8470 Sample:sss
8471 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
8472 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
8473 */
8474 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
8475 &(LeaseTime),
8476 phyAddr,
8477 ipAddr,
8478 hostName
8479 );
8480 if(ret != 4)
8481 continue;
8482 if(strcmp(str,phyAddr) == 0)
8483 strcpy(ipaddr,ipAddr);
8484 }
8485 fclose(fp);
8486 return RETURN_OK;
8487}
8488
8489/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
8490/**
8491* @description Returning Inactive wireless connected clients informations
8492*
developer69b61b02023-03-07 17:17:44 +08008493* @param
developer72fb0bb2023-01-11 09:46:29 +08008494* @filename Holding private_wifi 2g/5g content files
8495* @associated_dev_array Having inactiv wireless clients informations
8496* @output_array_size Returning Inactive wireless counts
8497* @return The status of the operation
8498* @retval RETURN_OK if successful
8499* @retval RETURN_ERR if any error is detected
8500*
8501*/
8502
8503INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
8504{
8505 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8506 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
8507 FILE *fp = NULL;
8508 int arr[MACADDRESS_SIZE] = {0};
8509 unsigned char mac[MACADDRESS_SIZE] = {0};
8510 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
8511 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
8512 fp = popen(buf,"r");
8513 if(fp == NULL)
8514 return RETURN_ERR;
8515 else
8516 {
8517 fgets(path,sizeof(path),fp);
8518 maccount = atoi(path);
8519 }
8520 pclose(fp);
8521 *output_array_size = maccount;
8522 wifi_associated_dev3_t* temp = NULL;
8523 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
8524 *associated_dev_array = temp;
8525 if(temp == NULL)
8526 {
8527 printf("Error Statement. Insufficient memory \n");
8528 return RETURN_ERR;
8529 }
8530 memset(buf,0,sizeof(buf));
8531 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
8532 fp = popen(buf,"r");
8533 if (fp == NULL) {
8534 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
8535 return RETURN_ERR;
8536 }
8537 for(count = 0; count < maccount ; count++)
8538 {
8539 fgets(path,sizeof(path),fp);
8540 for(i = 0; path[i]!='\n';i++)
8541 str[i]=path[i];
8542 str[i]='\0';
8543 getIPAddress(str,ipaddr);
8544 memset(buf,0,sizeof(buf));
8545 if(strlen(ipaddr) > 0)
8546 {
8547 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
8548 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
8549 {
8550 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
8551 {
8552 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
8553 {
8554 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
8555
8556 }
8557 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
8558 fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]);
8559 }
8560 temp[count].cli_AuthenticationState = 0; //TODO
developer69b61b02023-03-07 17:17:44 +08008561 temp[count].cli_Active = 0; //TODO
developer72fb0bb2023-01-11 09:46:29 +08008562 temp[count].cli_SignalStrength = 0;
8563 }
8564 else //Active wireless clients info
8565 {
8566 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
8567 {
8568 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
8569 {
8570 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
8571
8572 }
8573 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
8574 fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]);
8575 }
8576 temp[count].cli_Active = 1;
8577 }
8578 }
8579 memset(ipaddr,0,sizeof(ipaddr));
8580 }
8581 pclose(fp);
8582 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8583 return RETURN_OK;
8584}
8585//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
8586//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
8587//To get Band Steering Capability
8588INT wifi_getBandSteeringCapability(BOOL *support)
8589{
8590 *support = FALSE;
8591 return RETURN_OK;
8592}
8593
8594
8595//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
8596//To get Band Steering enable status
8597INT wifi_getBandSteeringEnable(BOOL *enable)
8598{
8599 *enable = FALSE;
8600 return RETURN_OK;
8601}
8602
8603//To turn on/off Band steering
8604INT wifi_setBandSteeringEnable(BOOL enable)
8605{
8606 return RETURN_OK;
8607}
8608
8609//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
8610//To get Band Steering AP group
8611INT wifi_getBandSteeringApGroup(char *output_ApGroup)
8612{
8613 if (NULL == output_ApGroup)
8614 return RETURN_ERR;
8615
8616 strcpy(output_ApGroup, "1,2");
8617 return RETURN_OK;
8618}
8619
8620//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
8621//to set and read the band steering BandUtilizationThreshold parameters
8622INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
8623{
8624 return RETURN_ERR;
8625}
8626
8627INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
8628{
8629 return RETURN_ERR;
8630}
8631
8632//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
8633//to set and read the band steering RSSIThreshold parameters
8634INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
8635{
8636 return RETURN_ERR;
8637}
8638
8639INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
8640{
8641 return RETURN_ERR;
8642}
8643
8644
8645//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
8646//to set and read the band steering physical modulation rate threshold parameters
8647INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
8648{
8649 //If chip is not support, return -1
8650 return RETURN_ERR;
8651}
8652
8653INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
8654{
8655 //If chip is not support, return -1
8656 return RETURN_ERR;
8657}
8658
8659//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
8660//to set and read the inactivity time (in seconds) for steering under overload condition
8661INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
8662{
8663 return RETURN_ERR;
8664}
8665
8666INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
8667{
8668 return RETURN_ERR;
8669}
8670
8671//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
8672//to set and read the inactivity time (in seconds) for steering under Idle condition
8673INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
8674{
8675 return RETURN_ERR;
8676}
8677
8678INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
8679{
8680 return RETURN_ERR;
8681}
8682
8683//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
8684//pClientMAC[64]
8685//pSourceSSIDIndex[64]
8686//pDestSSIDIndex[64]
8687//pSteeringReason[256]
8688INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
8689{
8690 //if no steering or redord_index is out of boundary, return -1. pSteeringTime returns the UTC time in seconds. pClientMAC is pre allocated as 64bytes. pSteeringReason returns the predefined steering trigger reason
8691 *pSteeringTime=time(NULL);
8692 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
8693 return RETURN_OK;
8694}
8695
8696INT wifi_ifConfigDown(INT apIndex)
8697{
8698 INT status = RETURN_OK;
8699 char cmd[64];
8700
8701 snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
8702 printf("%s: %s\n", __func__, cmd);
8703 system(cmd);
8704
8705 return status;
8706}
8707
8708INT wifi_ifConfigUp(INT apIndex)
8709{
8710 char interface_name[16] = {0};
8711 char cmd[128];
8712 char buf[1024];
8713
8714 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8715 return RETURN_ERR;
8716 snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
8717 _syscmd(cmd, buf, sizeof(buf));
8718 return 0;
8719}
8720
8721//>> Deprecated. Replace with wifi_applyRadioSettings
8722INT wifi_pushBridgeInfo(INT apIndex)
8723{
8724 char interface_name[16] = {0};
8725 char ip[32] = {0};
8726 char subnet[32] = {0};
8727 char bridge[32] = {0};
8728 int vlanId = 0;
8729 char cmd[128] = {0};
8730 char buf[1024] = {0};
8731
8732 wifi_getApBridgeInfo(apIndex,bridge,ip,subnet);
8733 wifi_getApVlanID(apIndex,&vlanId);
8734
8735 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8736 return RETURN_ERR;
8737 snprintf(cmd, sizeof(cmd), "cfgVlan %s %s %d %s ", interface_name, bridge, vlanId, ip);
8738 _syscmd(cmd,buf, sizeof(buf));
8739
8740 return 0;
8741}
8742
8743INT wifi_pushChannel(INT radioIndex, UINT channel)
8744{
8745 char interface_name[16] = {0};
8746 char cmd[128];
8747 char buf[1024];
8748 int apIndex;
8749
developer69b61b02023-03-07 17:17:44 +08008750 apIndex=(radioIndex==0)?0:1;
developer72fb0bb2023-01-11 09:46:29 +08008751 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
8752 return RETURN_ERR;
8753 snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
8754 _syscmd(cmd,buf, sizeof(buf));
8755
8756 return 0;
8757}
8758
8759INT wifi_pushChannelMode(INT radioIndex)
8760{
8761 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
8762 return RETURN_ERR;
8763}
8764
8765INT wifi_pushDefaultValues(INT radioIndex)
8766{
8767 //Apply Comcast specified default radio settings instantly
8768 //AMPDU=1
8769 //AMPDUFrames=32
8770 //AMPDULim=50000
8771 //txqueuelen=1000
8772
8773 return RETURN_ERR;
8774}
8775
8776INT wifi_pushTxChainMask(INT radioIndex)
8777{
8778 //Apply default TxChainMask instantly
8779 return RETURN_ERR;
8780}
8781
8782INT wifi_pushRxChainMask(INT radioIndex)
8783{
8784 //Apply default RxChainMask instantly
8785 return RETURN_ERR;
8786}
8787
8788INT wifi_pushSSID(INT apIndex, CHAR *ssid)
8789{
developer7e4a2a62023-04-06 19:56:03 +08008790 INT status;
developer72fb0bb2023-01-11 09:46:29 +08008791
developer7e4a2a62023-04-06 19:56:03 +08008792 status = wifi_setSSIDName(apIndex, ssid);
8793 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008794
developer7e4a2a62023-04-06 19:56:03 +08008795 return status;
developer72fb0bb2023-01-11 09:46:29 +08008796}
8797
8798INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
8799{
8800 //Apply default Ssid Advertisement instantly
8801 return RETURN_ERR;
8802}
8803
8804INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
8805{
developere82c0ca2023-05-10 16:25:35 +08008806 time_t now;
8807
8808 time(&now);
8809 if (now > radio_up_time[radioIndex])
8810 *output = now - radio_up_time[radioIndex];
8811 else {
8812 *output = 0;
8813 return RETURN_ERR;
8814 }
8815
8816 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008817}
8818
8819INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
8820{
8821 return RETURN_OK;
8822}
8823
8824INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
8825{
8826 return RETURN_OK;
8827}
8828
8829//To-do
8830INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
8831{
8832 char output[16]={'\0'};
8833 char config_file[MAX_BUF_SIZE] = {0};
8834
8835 if (!output_string)
8836 return RETURN_ERR;
8837
8838 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8839 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
8840
8841 if (strlen(output) == 0)
8842 snprintf(output_string, 64, "Disabled");
8843 else if (strncmp(output, "0", 1) == 0)
8844 snprintf(output_string, 64, "Disabled");
8845 else if (strncmp(output, "1", 1) == 0)
8846 snprintf(output_string, 64, "Optional");
8847 else if (strncmp(output, "2", 1) == 0)
8848 snprintf(output_string, 64, "Required");
8849 else {
8850 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
8851 return RETURN_ERR;
8852 }
8853
8854 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
8855 return RETURN_OK;
8856}
8857INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
8858{
8859 char str[MAX_BUF_SIZE]={'\0'};
8860 char cmd[MAX_CMD_SIZE]={'\0'};
8861 struct params params;
8862 char config_file[MAX_BUF_SIZE] = {0};
8863
8864 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8865 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
8866 return RETURN_ERR;
8867
8868 params.name = "ieee80211w";
8869 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
8870 params.value = "0";
8871 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
8872 params.value = "1";
8873 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
8874 params.value = "2";
8875 else{
8876 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
8877 return RETURN_ERR;
8878 }
8879 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8880 wifi_hostapdWrite(config_file, &params, 1);
8881 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
8882 return RETURN_OK;
8883}
8884INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
8885{
8886 char output[16]={'\0'};
8887 char config_file[MAX_BUF_SIZE] = {0};
8888
8889 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8890 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
8891 wifi_hostapdRead(config_file,"channel",output,sizeof(output));
8892
8893 *output_bool = (strncmp(output, "0", 1)==0) ? TRUE : FALSE;
8894 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
8895
8896 return RETURN_OK;
8897}
8898
8899INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
8900{
8901 return RETURN_OK;
8902}
8903
8904INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
8905{
8906 return RETURN_OK;
8907}
8908
8909INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
8910{
8911 return RETURN_OK;
8912}
8913
8914INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
8915{
8916 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8917 char config_file[MAX_BUF_SIZE] = {0};
8918
8919 if (NULL == output)
8920 return RETURN_ERR;
8921 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
8922 wifi_hostapdRead(config_file,"hw_mode",output,64);
8923
8924 if(strcmp(output,"b")==0)
8925 sprintf(output, "%s", "1,2,5.5,11");
8926 else if (strcmp(output,"a")==0)
8927 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
8928 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
8929 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
8930
8931 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8932 return RETURN_OK;
8933}
8934
8935INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
8936{
8937 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8938 char *temp;
8939 char temp_output[128];
8940 char temp_TransmitRates[128];
8941 char config_file[MAX_BUF_SIZE] = {0};
8942
8943 if (NULL == output)
8944 return RETURN_ERR;
8945
8946 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
8947 wifi_hostapdRead(config_file,"supported_rates",output,64);
8948
8949 if (strlen(output) == 0) {
8950 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
8951 return RETURN_OK;
8952 }
8953 strcpy(temp_TransmitRates,output);
8954 strcpy(temp_output,"");
8955 temp = strtok(temp_TransmitRates," ");
8956 while(temp!=NULL)
8957 {
8958 temp[strlen(temp)-1]=0;
8959 if((temp[0]=='5') && (temp[1]=='\0'))
8960 {
8961 temp="5.5";
8962 }
8963 strcat(temp_output,temp);
8964 temp = strtok(NULL," ");
8965 if(temp!=NULL)
8966 {
8967 strcat(temp_output,",");
8968 }
8969 }
8970 strcpy(output,temp_output);
8971 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8972
8973 return RETURN_OK;
8974}
8975
8976INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
8977{
8978 return RETURN_OK;
8979}
8980
8981
8982INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
8983{
8984 int i=0;
8985 char *temp;
8986 char temp1[128] = {0};
8987 char temp_output[128] = {0};
8988 char temp_TransmitRates[128] = {0};
8989 struct params params={'\0'};
8990 char config_file[MAX_BUF_SIZE] = {0};
8991 wifi_band band = wifi_index_to_band(wlanIndex);
8992
8993 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8994 if(NULL == output)
8995 return RETURN_ERR;
8996 strcpy(temp_TransmitRates,output);
8997
8998 for(i=0;i<strlen(temp_TransmitRates);i++)
8999 {
9000 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
9001 {
9002 continue;
9003 }
9004 else
9005 {
9006 return RETURN_ERR;
9007 }
9008 }
9009 strcpy(temp_output,"");
9010 temp = strtok(temp_TransmitRates,",");
9011 while(temp!=NULL)
9012 {
9013 strcpy(temp1,temp);
9014 if(band == band_5)
9015 {
9016 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
9017 {
9018 return RETURN_ERR;
9019 }
9020 }
9021
9022 if(strcmp(temp,"5.5")==0)
9023 {
9024 strcpy(temp1,"55");
9025 }
9026 else
9027 {
9028 strcat(temp1,"0");
9029 }
9030 strcat(temp_output,temp1);
9031 temp = strtok(NULL,",");
9032 if(temp!=NULL)
9033 {
9034 strcat(temp_output," ");
9035 }
9036 }
9037 strcpy(output,temp_output);
9038
9039 params.name = "supported_rates";
9040 params.value = output;
9041
9042 wifi_dbg_printf("\n%s:",__func__);
9043 wifi_dbg_printf("params.value=%s\n",params.value);
9044 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
9045 wifi_hostapdWrite(config_file,&params,1);
9046 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9047
9048 return RETURN_OK;
9049}
9050
9051
9052static char *sncopy(char *dst, int dst_sz, const char *src)
9053{
9054 if (src && dst && dst_sz > 0) {
9055 strncpy(dst, src, dst_sz);
9056 dst[dst_sz - 1] = '\0';
9057 }
9058 return dst;
9059}
9060
9061static int util_get_sec_chan_offset(int channel, const char* ht_mode)
9062{
9063 if (0 == strcmp(ht_mode, "HT40") ||
9064 0 == strcmp(ht_mode, "HT80") ||
9065 0 == strcmp(ht_mode, "HT160")) {
9066 switch (channel) {
9067 case 1 ... 7:
9068 case 36:
9069 case 44:
9070 case 52:
9071 case 60:
9072 case 100:
9073 case 108:
9074 case 116:
9075 case 124:
9076 case 132:
9077 case 140:
9078 case 149:
9079 case 157:
9080 return 1;
9081 case 8 ... 13:
9082 case 40:
9083 case 48:
9084 case 56:
9085 case 64:
9086 case 104:
9087 case 112:
9088 case 120:
9089 case 128:
9090 case 136:
9091 case 144:
9092 case 153:
9093 case 161:
9094 return -1;
9095 default:
9096 return -EINVAL;
9097 }
9098 }
9099
9100 return -EINVAL;
9101}
9102
9103static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
9104{
9105 int idx = channel%8;
9106 if (0 == strcmp(ht_mode, "HT40") ||
9107 0 == strcmp(ht_mode, "HT80") ||
9108 0 == strcmp(ht_mode, "HT160")) {
9109 switch (idx) {
9110 case 1:
9111 return 1;
9112 case 5:
9113 return -1;
9114 default:
9115 return -EINVAL;
9116 }
9117 }
9118
9119 return -EINVAL;
9120}
9121static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
9122{
9123 if (NULL == hw_mode) return;
9124
9125 if (0 == strcmp(hw_mode, "ac"))
9126 sncopy(bw_mode, bw_mode_len, "ht vht");
9127
9128 if (0 == strcmp(hw_mode, "n"))
9129 sncopy(bw_mode, bw_mode_len, "ht");
9130
9131 return;
9132}
9133
9134static int util_chan_to_freq(int chan)
9135{
9136 if (chan == 14)
9137 return 2484;
9138 else if (chan < 14)
9139 return 2407 + chan * 5;
9140 else if (chan >= 182 && chan <= 196)
9141 return 4000 + chan * 5;
9142 else
9143 return 5000 + chan * 5;
9144 return 0;
9145}
9146
9147static int util_6G_chan_to_freq(int chan)
9148{
9149 if (chan)
9150 return 5950 + chan * 5;
9151 else
9152 return 0;
developer69b61b02023-03-07 17:17:44 +08009153
developer72fb0bb2023-01-11 09:46:29 +08009154}
9155const int *util_unii_5g_chan2list(int chan, int width)
9156{
9157 static const int lists[] = {
9158 // <width>, <chan1>, <chan2>..., 0,
9159 20, 36, 0,
9160 20, 40, 0,
9161 20, 44, 0,
9162 20, 48, 0,
9163 20, 52, 0,
9164 20, 56, 0,
9165 20, 60, 0,
9166 20, 64, 0,
9167 20, 100, 0,
9168 20, 104, 0,
9169 20, 108, 0,
9170 20, 112, 0,
9171 20, 116, 0,
9172 20, 120, 0,
9173 20, 124, 0,
9174 20, 128, 0,
9175 20, 132, 0,
9176 20, 136, 0,
9177 20, 140, 0,
9178 20, 144, 0,
9179 20, 149, 0,
9180 20, 153, 0,
9181 20, 157, 0,
9182 20, 161, 0,
9183 20, 165, 0,
9184 40, 36, 40, 0,
9185 40, 44, 48, 0,
9186 40, 52, 56, 0,
9187 40, 60, 64, 0,
9188 40, 100, 104, 0,
9189 40, 108, 112, 0,
9190 40, 116, 120, 0,
9191 40, 124, 128, 0,
9192 40, 132, 136, 0,
9193 40, 140, 144, 0,
9194 40, 149, 153, 0,
9195 40, 157, 161, 0,
9196 80, 36, 40, 44, 48, 0,
9197 80, 52, 56, 60, 64, 0,
9198 80, 100, 104, 108, 112, 0,
9199 80, 116, 120, 124, 128, 0,
9200 80, 132, 136, 140, 144, 0,
9201 80, 149, 153, 157, 161, 0,
9202 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
9203 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
9204 -1 // final delimiter
9205 };
9206 const int *start;
9207 const int *p;
9208
9209 for (p = lists; *p != -1; p++) {
9210 if (*p == width) {
9211 for (start = ++p; *p != 0; p++) {
9212 if (*p == chan)
9213 return start;
9214 }
9215 }
9216 // move to the end of channel list of given width
9217 while (*p != 0) {
9218 p++;
9219 }
9220 }
9221
9222 return NULL;
9223}
9224
9225static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
9226{
9227 if (NULL == ht_mode)
9228 return 0;
9229
9230 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
9231 const int *chans = util_unii_5g_chan2list(channel, width);
9232 int sum = 0;
9233 int cnt = 0;
9234
9235 if (NULL == chans)
9236 return 0;
9237
9238 while (*chans) {
9239 sum += *chans;
9240 cnt++;
9241 chans++;
9242 }
9243 if (cnt == 0)
9244 return 0;
9245 return sum / cnt;
9246}
9247
9248static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
9249{
9250 if (NULL == ht_mode)
9251 return 0;
9252
9253 int width = strtol((ht_mode + 2), NULL, 10);
9254
9255 int idx = 0 ;
9256 int centerchan = 0;
9257 int chan_ofs = 1;
9258
9259 if (width == 40){
9260 idx = ((channel/4) + chan_ofs)%2;
9261 switch (idx) {
9262 case 0:
9263 centerchan = (channel - 2);
9264 break;
9265 case 1:
9266 centerchan = (channel + 2);
developer69b61b02023-03-07 17:17:44 +08009267 break;
developer72fb0bb2023-01-11 09:46:29 +08009268 default:
9269 return -EINVAL;
9270 }
9271 }else if (width == 80){
developer69b61b02023-03-07 17:17:44 +08009272 idx = ((channel/4) + chan_ofs)%4;
developer72fb0bb2023-01-11 09:46:29 +08009273 switch (idx) {
9274 case 0:
9275 centerchan = (channel - 6);
9276 break;
9277 case 1:
9278 centerchan = (channel + 6);
9279 break;
9280 case 2:
9281 centerchan = (channel + 2);
9282 break;
9283 case 3:
9284 centerchan = (channel - 2);
9285 break;
9286 default:
9287 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +08009288 }
developer72fb0bb2023-01-11 09:46:29 +08009289 }else if (width == 160){
9290 switch (channel) {
9291 case 1 ... 29:
9292 centerchan = 15;
9293 break;
9294 case 33 ... 61:
9295 centerchan = 47;
9296 break;
9297 case 65 ... 93:
9298 centerchan = 79;
9299 break;
9300 case 97 ... 125:
9301 centerchan = 111;
9302 break;
9303 case 129 ... 157:
9304 centerchan = 143;
9305 break;
9306 case 161 ... 189:
9307 centerchan = 175;
9308 break;
9309 case 193 ... 221:
9310 centerchan = 207;
9311 break;
9312 default:
9313 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +08009314 }
developer72fb0bb2023-01-11 09:46:29 +08009315 }
9316 return centerchan;
9317}
9318static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
9319{
9320 BOOL onlyG, onlyN, onlyA;
9321 CHAR tmp[64];
9322 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
9323 if (ret == RETURN_OK) {
9324 sncopy(hw_mode, hw_mode_size, tmp);
9325 }
9326 return ret;
9327}
9328
9329INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
9330{
9331 // Sample commands:
9332 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
9333 // hostapd_cli -i wifi0 chan_switch 30 2437
9334 char cmd[MAX_CMD_SIZE] = {0};
9335 char buf[MAX_BUF_SIZE] = {0};
9336 int freq = 0, ret = 0;
9337 char center_freq1_str[32] = ""; // center_freq1=%d
9338 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
9339 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
9340 char hw_mode[16] = ""; // n|ac
9341 char bw_mode[16] = ""; // ht|ht vht
9342 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
9343 char interface_name[16] = {0};
9344 int sec_chan_offset;
9345 int width;
9346 char config_file[64] = {0};
9347 BOOL stbcEnable = FALSE;
9348 char *ext_str = "None";
9349 wifi_band band = band_invalid;
9350 int center_chan = 0;
9351 int center_freq1 = 0;
9352
9353 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
9354
9355 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
9356 return RETURN_ERR;
9357
9358 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9359
9360 band = wifi_index_to_band(radioIndex);
9361
9362 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
9363
9364 // Get radio mode HT20|HT40|HT80 etc.
9365 if (channel){
9366 if (band == band_6){
9367 freq = util_6G_chan_to_freq(channel);
9368 }else{
9369 freq = util_chan_to_freq(channel);
9370 }
9371 snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
9372
9373 // Provide bandwith if specified
9374 if (channel_width_MHz > 20) {
9375 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
9376 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
9377 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
9378
9379 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
9380 }else if (channel_width_MHz == 20){
9381 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
9382 }
9383
9384
9385 if (channel_width_MHz > 20) {
9386 if (band == band_6){
9387 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
9388 if(center_chan){
9389 center_freq1 = util_6G_chan_to_freq(center_chan);
9390 }
9391 }else{
9392 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
9393 if(center_chan){
9394 center_freq1 = util_chan_to_freq(center_chan);
9395 }
9396 }
developer69b61b02023-03-07 17:17:44 +08009397
developer72fb0bb2023-01-11 09:46:29 +08009398 if (center_freq1)
9399 snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +08009400
developer72fb0bb2023-01-11 09:46:29 +08009401 }
9402
9403 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
9404 if (band == band_6){
9405 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
9406 }else{
9407 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
9408 }
9409 if (sec_chan_offset != -EINVAL)
9410 snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
9411
9412 // Only the first AP, other are hanging on the same radio
9413 int apIndex = radioIndex;
developerf6a87542023-05-16 15:47:28 +08009414 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s chan_switch %d %d %s %s %s",
developer72fb0bb2023-01-11 09:46:29 +08009415 interface_name, csa_beacon_count, freq,
developerf6a87542023-05-16 15:47:28 +08009416 sec_chan_offset_str, center_freq1_str, opt_chan_info_str);
9417 wifi_dbg_printf("execute: '%s'\n", cmd);
9418 ret = _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009419 wifi_reloadAp(radioIndex);
9420
9421 ret = wifi_setRadioChannel(radioIndex, channel);
9422 if (ret != RETURN_OK) {
9423 fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__);
9424 return RETURN_ERR;
9425 }
9426
9427 if (sec_chan_offset == 1) ext_str = "Above";
9428 else if (sec_chan_offset == -1) ext_str = "Below";
9429
9430 wifi_setRadioCenterChannel(radioIndex, center_chan);
9431
9432 } else {
9433 if (channel_width_MHz > 20)
9434 ext_str = "Above";
9435 }
9436
9437 wifi_setRadioExtChannel(radioIndex, ext_str);
9438
9439 char mhz_str[16];
9440 snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
9441 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
9442
9443 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9444
9445 return RETURN_OK;
9446}
9447
9448INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
9449{
9450 int index = -1;
9451 wifi_neighbor_ap2_t *scan_array = NULL;
9452 char cmd[256]={0};
9453 char buf[128]={0};
9454 char file_name[32] = {0};
9455 char filter_SSID[32] = {0};
9456 char line[256] = {0};
9457 char interface_name[16] = {0};
9458 char *ret = NULL;
9459 int freq=0;
9460 FILE *f = NULL;
9461 size_t len=0;
9462 int channels_num = 0;
9463 int vht_channel_width = 0;
9464 int get_noise_ret = RETURN_ERR;
9465 bool filter_enable = false;
9466 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
9467 int phyId = 0;
9468
9469 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
9470
9471 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
9472 f = fopen(file_name, "r");
9473 if (f != NULL) {
9474 fgets(filter_SSID, sizeof(file_name), f);
9475 if (strlen(filter_SSID) != 0)
9476 filter_enable = true;
9477 fclose(f);
9478 }
9479
9480 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
9481 return RETURN_ERR;
9482
9483 phyId = radio_index_to_phy(radio_index);
9484
9485 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
9486 _syscmd(cmd, buf, sizeof(buf));
9487 channels_num = strtol(buf, NULL, 10);
9488
9489 sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
9490 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
9491 fprintf(stderr, "cmd: %s\n", cmd);
9492 if ((f = popen(cmd, "r")) == NULL) {
9493 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
9494 return RETURN_ERR;
9495 }
developer69b61b02023-03-07 17:17:44 +08009496
developer72fb0bb2023-01-11 09:46:29 +08009497 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
9498 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08009499
developer72fb0bb2023-01-11 09:46:29 +08009500 ret = fgets(line, sizeof(line), f);
9501 while (ret != NULL) {
9502 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +08009503 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
developer72fb0bb2023-01-11 09:46:29 +08009504 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
9505 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
9506
9507 if (!filter_BSS) {
9508 index++;
9509 wifi_neighbor_ap2_t *tmp;
9510 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
9511 if (tmp == NULL) { // no more memory to use
9512 index--;
9513 wifi_dbg_printf("%s: realloc failed\n", __func__);
9514 break;
9515 }
9516 scan_array = tmp;
9517 }
9518 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
9519
9520 filter_BSS = false;
9521 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
9522 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
9523 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
9524 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
9525 } else if (strstr(line, "freq") != NULL) {
9526 sscanf(line," freq: %d", &freq);
9527 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
9528
9529 if (freq >= 2412 && freq <= 2484) {
9530 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
9531 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
9532 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
9533 }
9534 else if (freq >= 5160 && freq <= 5805) {
9535 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
9536 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
9537 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
9538 }
9539
9540 scan_array[index].ap_Noise = 0;
9541 if (get_noise_ret == RETURN_OK) {
9542 for (int i = 0; i < channels_num; i++) {
9543 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
9544 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
9545 break;
9546 }
9547 }
9548 }
9549 } else if (strstr(line, "beacon interval") != NULL) {
9550 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
9551 } else if (strstr(line, "signal") != NULL) {
9552 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
9553 } else if (strstr(line,"SSID") != NULL) {
9554 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
9555 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
9556 filter_BSS = true;
9557 }
9558 } else if (strstr(line, "Supported rates") != NULL) {
9559 char SRate[80] = {0}, *tmp = NULL;
9560 memset(buf, 0, sizeof(buf));
9561 strcpy(SRate, line);
9562 tmp = strtok(SRate, ":");
9563 tmp = strtok(NULL, ":");
9564 strcpy(buf, tmp);
9565 memset(SRate, 0, sizeof(SRate));
9566
9567 tmp = strtok(buf, " \n");
9568 while (tmp != NULL) {
9569 strcat(SRate, tmp);
9570 if (SRate[strlen(SRate) - 1] == '*') {
9571 SRate[strlen(SRate) - 1] = '\0';
9572 }
9573 strcat(SRate, ",");
9574
9575 tmp = strtok(NULL, " \n");
9576 }
9577 SRate[strlen(SRate) - 1] = '\0';
9578 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
9579 } else if (strstr(line, "DTIM") != NULL) {
9580 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
9581 } else if (strstr(line, "VHT capabilities") != NULL) {
9582 strcat(scan_array[index].ap_SupportedStandards, ",ac");
9583 strcpy(scan_array[index].ap_OperatingStandards, "ac");
9584 } else if (strstr(line, "HT capabilities") != NULL) {
9585 strcat(scan_array[index].ap_SupportedStandards, ",n");
9586 strcpy(scan_array[index].ap_OperatingStandards, "n");
9587 } else if (strstr(line, "VHT operation") != NULL) {
9588 ret = fgets(line, sizeof(line), f);
9589 sscanf(line," * channel width: %d", &vht_channel_width);
9590 if(vht_channel_width == 1) {
9591 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
9592 } else {
9593 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
9594 }
9595 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
9596 continue;
9597 } else if (strstr(line, "HT operation") != NULL) {
9598 ret = fgets(line, sizeof(line), f);
9599 sscanf(line," * secondary channel offset: %s", &buf);
9600 if (!strcmp(buf, "above")) {
9601 //40Mhz +
9602 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
9603 }
9604 else if (!strcmp(buf, "below")) {
9605 //40Mhz -
9606 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
9607 } else {
9608 //20Mhz
9609 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
9610 }
9611 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
9612 continue;
9613 } else if (strstr(line, "HE capabilities") != NULL) {
9614 strcat(scan_array[index].ap_SupportedStandards, ",ax");
9615 strcpy(scan_array[index].ap_OperatingStandards, "ax");
9616 ret = fgets(line, sizeof(line), f);
9617 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
9618 if (strstr(line, "HE40/2.4GHz") != NULL)
9619 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
9620 else
9621 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
9622 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
9623 if (strstr(line, "HE80/5GHz") != NULL) {
9624 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
9625 ret = fgets(line, sizeof(line), f);
9626 } else
9627 continue;
9628 if (strstr(line, "HE160/5GHz") != NULL)
9629 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
9630 }
9631 continue;
9632 } else if (strstr(line, "WPA") != NULL) {
9633 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
9634 } else if (strstr(line, "RSN") != NULL) {
9635 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
9636 } else if (strstr(line, "Group cipher") != NULL) {
9637 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
9638 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
9639 strcpy(scan_array[index].ap_EncryptionMode, "AES");
9640 }
9641 }
9642 ret = fgets(line, sizeof(line), f);
9643 }
9644
9645 if (!filter_BSS) {
9646 *output_array_size = index + 1;
9647 } else {
9648 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
9649 *output_array_size = index;
9650 }
9651 *neighbor_ap_array = scan_array;
9652 pclose(f);
9653 free(channels_noise_arr);
9654 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9655 return RETURN_OK;
9656}
9657
9658INT wifi_getApAssociatedDeviceStats(
9659 INT apIndex,
9660 mac_address_t *clientMacAddress,
9661 wifi_associated_dev_stats_t *associated_dev_stats,
9662 u64 *handle)
9663{
9664 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
9665 char interface_name[50] = {0};
9666 char cmd[1024] = {0};
9667 char mac_str[18] = {0};
9668 char *key = NULL;
9669 char *val = NULL;
9670 FILE *f = NULL;
9671 char *line = NULL;
9672 size_t len = 0;
9673
9674 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
9675 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
9676 return RETURN_ERR;
9677 }
9678
9679 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
9680 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
9681 if((f = popen(cmd, "r")) == NULL) {
9682 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
9683 return RETURN_ERR;
9684 }
9685
9686 while ((getline(&line, &len, f)) != -1) {
9687 key = strtok(line,":");
9688 val = strtok(NULL,":");
9689
9690 if(!strncmp(key,"rx bytes",8))
9691 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
9692 if(!strncmp(key,"tx bytes",8))
9693 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
9694 if(!strncmp(key,"rx packets",10))
9695 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
9696 if(!strncmp(key,"tx packets",10))
9697 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
9698 if(!strncmp(key,"tx retries",10))
9699 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
9700 if(!strncmp(key,"tx failed",9))
9701 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
9702 if(!strncmp(key,"rx drop misc",13))
9703 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
9704 if(!strncmp(key,"rx bitrate",10)) {
9705 val = strtok(val, " ");
9706 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
9707 }
9708 if(!strncmp(key,"tx bitrate",10)) {
9709 val = strtok(val, " ");
9710 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
9711 }
9712 }
9713 free(line);
9714 pclose(f);
9715 return RETURN_OK;
9716}
9717
9718INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
9719{
developer7e4a2a62023-04-06 19:56:03 +08009720 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009721 char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0};
9722
developer7e4a2a62023-04-06 19:56:03 +08009723 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
9724
developer72fb0bb2023-01-11 09:46:29 +08009725 if (NULL == output_string)
9726 return RETURN_ERR;
9727
9728 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9729 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08009730
9731 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08009732 _syscmd(cmd, buf, sizeof(buf));
9733
9734 //size of SSID name restricted to value less than 32 bytes
9735 snprintf(output_string, 32, "%s", buf);
developer7e4a2a62023-04-06 19:56:03 +08009736 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009737
9738 return RETURN_OK;
9739}
9740
9741INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
9742{
developer7e4a2a62023-04-06 19:56:03 +08009743 char cmd[MAX_CMD_SIZE] = {0};
9744 char buf[MAX_BUF_SIZE] = {0};
9745 char inf_name[IF_NAME_SIZE] = {0};
9746 char policy = 0;
developer72fb0bb2023-01-11 09:46:29 +08009747
9748 if (!output_filterMode)
9749 return RETURN_ERR;
9750
developer7e4a2a62023-04-06 19:56:03 +08009751 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9752 return RETURN_ERR;
9753
9754 /* mwctl get acl policy */
9755 snprintf(cmd, sizeof(cmd), "mwctl %s acl show_all | grep policy | cut -d '=' -f2 | tr -d '\\n'", inf_name);
9756 _syscmd(cmd, buf, sizeof(buf));
9757
9758
9759 policy = atoi(buf);
9760
9761 if (policy < 0 || policy > 2) {
9762 printf("%s:get wrong acl policy!!!\n", __func__);
9763 *output_filterMode = 0;
9764 return RETURN_ERR;
9765 } else
9766 *output_filterMode = policy;
9767
developer72fb0bb2023-01-11 09:46:29 +08009768
9769 return RETURN_OK;
9770}
9771
9772INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
9773{
9774 FILE *fp = NULL;
9775 char str[MAX_BUF_SIZE] = {0};
9776 int wificlientindex = 0 ;
9777 int count = 0;
9778 int signalstrength = 0;
9779 int arr[MACADDRESS_SIZE] = {0};
9780 unsigned char mac[MACADDRESS_SIZE] = {0};
9781 UINT wifi_count = 0;
9782 char virtual_interface_name[MAX_BUF_SIZE] = {0};
9783 char pipeCmd[MAX_CMD_SIZE] = {0};
9784
9785 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9786 *output_array_size = 0;
9787 *associated_dev_array = NULL;
9788 char interface_name[50] = {0};
9789
9790 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
9791 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
9792 return RETURN_ERR;
9793 }
9794
9795 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
9796 fp = popen(pipeCmd, "r");
9797 if (fp == NULL)
9798 {
9799 printf("Failed to run command inside function %s\n",__FUNCTION__ );
9800 return RETURN_ERR;
9801 }
9802
9803 /* Read the output a line at a time - output it. */
9804 fgets(str, sizeof(str)-1, fp);
9805 wifi_count = (unsigned int) atoi ( str );
9806 *output_array_size = wifi_count;
9807 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
9808 pclose(fp);
9809
9810 if(wifi_count == 0)
9811 {
9812 return RETURN_OK;
9813 }
9814 else
9815 {
9816 wifi_associated_dev2_t* temp = NULL;
9817 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
9818 *associated_dev_array = temp;
9819 if(temp == NULL)
9820 {
9821 printf("Error Statement. Insufficient memory \n");
9822 return RETURN_ERR;
9823 }
9824
9825 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
9826 system(pipeCmd);
9827
9828 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
9829 if(fp == NULL)
9830 {
9831 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
9832 return RETURN_ERR;
9833 }
9834 fclose(fp);
9835
9836 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
9837 fp = popen(pipeCmd, "r");
9838 if(fp)
9839 {
9840 for(count =0 ; count < wifi_count; count++)
9841 {
9842 fgets(str, MAX_BUF_SIZE, fp);
9843 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9844 {
9845 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9846 {
9847 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9848
9849 }
9850 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9851 wifi_dbg_printf("MAC %d = %X:%X:%X:%X:%X:%X \n", count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]);
9852 }
9853 temp[count].cli_AuthenticationState = 1; //TODO
9854 temp[count].cli_Active = 1; //TODO
9855 }
9856 pclose(fp);
9857 }
9858
9859 //Updating RSSI per client
9860 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
9861 fp = popen(pipeCmd, "r");
9862 if(fp)
9863 {
9864 pclose(fp);
9865 }
9866 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
9867 if(fp)
9868 {
9869 for(count =0 ; count < wifi_count ;count++)
9870 {
9871 fgets(str, MAX_BUF_SIZE, fp);
9872 signalstrength = atoi(str);
9873 temp[count].cli_RSSI = signalstrength;
9874 }
9875 pclose(fp);
9876 }
9877
9878
9879 //LastDataDownlinkRate
9880 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
9881 fp = popen(pipeCmd, "r");
9882 if (fp)
9883 {
9884 pclose(fp);
9885 }
9886 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
9887 if (fp)
9888 {
9889 for (count = 0; count < wifi_count; count++)
9890 {
9891 fgets(str, MAX_BUF_SIZE, fp);
9892 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
9893 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
9894 }
9895 pclose(fp);
9896 }
9897
9898 //LastDataUplinkRate
9899 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
9900 fp = popen(pipeCmd, "r");
9901 if (fp)
9902 {
9903 pclose(fp);
9904 }
9905 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
9906 if (fp)
9907 {
9908 for (count = 0; count < wifi_count; count++)
9909 {
9910 fgets(str, MAX_BUF_SIZE, fp);
9911 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
9912 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
9913 }
9914 pclose(fp);
9915 }
9916 }
9917 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9918 return RETURN_OK;
9919
9920}
9921
9922INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
9923{
9924#if 0
9925 /*char buf[1024] = {0};
9926 sprintf(cmd, "ifconfig %s ", interface_name);
9927 _syscmd(cmd, buf, sizeof(buf));*/
9928
9929 output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters.
9930 output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters.
9931 output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface.
9932 output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface.
9933
9934 output_struct->ssid_RetransCount = 0; //The total number of transmitted packets which were retransmissions. Two retransmissions of the same packet results in this counter incrementing by two.
9935 output_struct->ssid_FailedRetransCount = 0; //The number of packets that were not transmitted successfully due to the number of retransmission attempts exceeding an 802.11 retry limit. This parameter is based on dot11FailedCount from [802.11-2012].
9936 output_struct->ssid_RetryCount = 0; //The number of packets that were successfully transmitted after one or more retransmissions. This parameter is based on dot11RetryCount from [802.11-2012].
9937 output_struct->ssid_MultipleRetryCount = 0; //The number of packets that were successfully transmitted after more than one retransmission. This parameter is based on dot11MultipleRetryCount from [802.11-2012].
9938 output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012].
9939 output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac.
9940
9941 output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors.
9942 output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
9943 output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
9944 output_struct->ssid_UnicastPacketsReceived = 2; //The total number of received packets, delivered by this layer to a higher layer, which were not addressed to a multicast or broadcast address at this layer.
9945 output_struct->ssid_DiscardedPacketsSent = 1; //The total number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space.
9946 output_struct->ssid_DiscardedPacketsReceived = 1; //The total number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being delivered. One possible reason for discarding such a packet could be to free up buffer space.
9947 output_struct->ssid_MulticastPacketsSent = 10; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a multicast address at this layer, including those that were discarded or not sent.
9948 output_struct->ssid_MulticastPacketsReceived = 0; //The total number of received packets, delivered by this layer to a higher layer, which were addressed to a multicast address at this layer.
9949 output_struct->ssid_BroadcastPacketsSent = 0; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a broadcast address at this layer, including those that were discarded or not sent.
9950 output_struct->ssid_BroadcastPacketsRecevied = 1; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a broadcast address at this layer, including those that were discarded or not sent.
9951 output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol.
9952#endif
9953
9954 FILE *fp = NULL;
9955 char interface_name[50] = {0};
9956 char pipeCmd[128] = {0};
9957 char str[256] = {0};
9958 wifi_ssidTrafficStats2_t *out = output_struct;
9959
9960 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
9961 if (!output_struct)
9962 return RETURN_ERR;
9963
9964 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
9965 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
9966 return RETURN_ERR;
9967 sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name);
9968
9969 fp = popen(pipeCmd, "r");
9970 if (fp == NULL) {
9971 fprintf(stderr, "%s: popen failed\n", __func__);
9972 return RETURN_ERR;
9973 }
9974 fgets(str, sizeof(str), fp);
9975 pclose(fp);
9976
9977 if (strlen(str) == 0) // interface not exist
9978 return RETURN_OK;
9979
9980 sscanf(str, "%*[^:]: %lu %lu %lu %lu %* %* %* %* %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
9981 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
9982
9983 memset(str, 0, sizeof(str));
9984 sprintf(pipeCmd, "tail -n1 /proc/net/netstat");
9985 fp = popen(pipeCmd, "r");
9986 if (fp == NULL) {
9987 fprintf(stderr, "%s: popen failed\n", __func__);
9988 return RETURN_ERR;
9989 }
9990 fgets(str, sizeof(str), fp);
9991
9992 sscanf(str, "%*[^:]: %* %* %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
9993 &out->ssid_BroadcastPacketsSent);
9994 pclose(fp);
9995
9996 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
9997 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
9998
9999 // Not supported
10000 output_struct->ssid_RetransCount = 0;
10001 output_struct->ssid_FailedRetransCount = 0;
10002 output_struct->ssid_RetryCount = 0;
10003 output_struct->ssid_MultipleRetryCount = 0;
10004 output_struct->ssid_ACKFailureCount = 0;
10005 output_struct->ssid_AggregatedPacketCount = 0;
10006
10007 return RETURN_OK;
10008}
10009
10010//Enables or disables device isolation. A value of true means that the devices connected to the Access Point are isolated from all other devices within the home network (as is typically the case for a Wireless Hotspot).
10011INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
10012{
10013 char output_val[16]={'\0'};
10014 char config_file[MAX_BUF_SIZE] = {0};
10015
10016 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10017 if (!output)
10018 return RETURN_ERR;
10019 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
10020 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
10021
10022 if( strcmp(output_val,"1") == 0 )
10023 *output = TRUE;
10024 else
10025 *output = FALSE;
10026 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10027
10028 return RETURN_OK;
10029}
10030
10031INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
10032{
10033 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10034 char str[MAX_BUF_SIZE]={'\0'};
10035 char string[MAX_BUF_SIZE]={'\0'};
10036 char cmd[MAX_CMD_SIZE]={'\0'};
10037 char *ch;
10038 char config_file[MAX_BUF_SIZE] = {0};
10039 struct params params;
10040
10041 if(enable == TRUE)
10042 strcpy(string,"1");
10043 else
10044 strcpy(string,"0");
10045
10046 params.name = "ap_isolate";
10047 params.value = string;
10048
10049 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
10050 wifi_hostapdWrite(config_file,&params,1);
10051 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10052
10053 return RETURN_OK;
10054}
10055
10056INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
10057{
developera1255e42023-05-13 17:45:02 +080010058 char mgmtpwr_file[32] = {0};
10059 char cmd[64] = {0};
10060 char buf[32]={0};
10061
developer72fb0bb2023-01-11 09:46:29 +080010062 if (NULL == output_dBm)
10063 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080010064 snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
10065 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
10066 _syscmd(cmd, buf, sizeof(buf));
10067 if (strlen(buf) > 0)
10068 *output_dBm = strtol(buf, NULL, 10);
10069 else
10070 *output_dBm = 23;
developer72fb0bb2023-01-11 09:46:29 +080010071 return RETURN_OK;
10072}
10073
10074INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
10075{
developera1255e42023-05-13 17:45:02 +080010076 char interface_name[16] = {0};
10077 char cmd[128]={0};
10078 char buf[128]={0};
10079 char mgmt_pwr_file[128]={0};
10080 FILE *f = NULL;
10081
10082 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10083
10084 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
10085 return RETURN_ERR;
10086 snprintf(cmd, sizeof(cmd), "mwctl dev %s set pwr mgmt_frame_pwr=%d", interface_name, dBm);
10087 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) {
10088 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
10089 return RETURN_ERR;
10090 }
10091 snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
10092 f = fopen(mgmt_pwr_file, "w");
10093 if (f == NULL) {
10094 fprintf(stderr, "%s: fopen failed\n", __func__);
10095 return RETURN_ERR;
10096 }
10097 fprintf(f, "%d", dBm);
10098 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080010099 return RETURN_OK;
10100}
10101INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
10102{
10103 return RETURN_OK;
10104}
10105INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
10106{
10107 return RETURN_OK;
10108}
10109INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
10110{
10111 return RETURN_OK;
10112}
10113INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
10114{
10115 return RETURN_OK;
10116}
10117INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
10118{
10119 char config_file[MAX_BUF_SIZE] = {0};
10120 struct params list;
10121
10122 list.name = "bss_transition";
10123 list.value = activate?"1":"0";
10124 snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10125 wifi_hostapdWrite(config_file, &list, 1);
10126
10127 return RETURN_OK;
10128}
10129wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
10130
10131void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
10132{
10133 return;
10134}
10135
10136INT wifi_setApCsaDeauth(INT apIndex, INT mode)
10137{
10138 // TODO Implement me!
10139 return RETURN_OK;
10140}
10141
10142INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
10143{
10144 char file_name[128] = {0};
10145 char buf[128] = {0};
10146 FILE *f = NULL;
10147 int max_num_radios = 0;
10148
10149 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10150
10151 wifi_getMaxRadioNumber(&max_num_radios);
10152 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
10153 for (int index = 0; index < max_num_radios; index++) {
10154 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
10155 f = fopen(file_name, "w");
10156 if (f == NULL)
10157 return RETURN_ERR;
10158 // For mode == 0 is to disable filter, just don't write to the file.
10159 if (mode)
10160 fprintf(f, "%s", essid);
10161
10162 fclose(f);
10163 }
10164 } else { // special case, need to set AP's SSID as filter for each radio.
10165 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
10166 f = fopen(file_name, "w");
10167 if (f == NULL)
10168 return RETURN_ERR;
10169
10170 // For mode == 0 is to disable filter, just don't write to the file.
10171 if (mode)
10172 fprintf(f, "%s", essid);
10173
10174 fclose(f);
10175 }
10176
10177 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10178 return RETURN_OK;
10179}
10180
10181INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
10182{
10183 // TODO Implement me!
10184 //Apply wifi_pushRadioChannel() instantly
10185 return RETURN_ERR;
10186}
10187
10188INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
10189{
10190 // TODO Implement me!
10191 return RETURN_OK;
10192}
10193
10194#ifdef HAL_NETLINK_IMPL
10195static int tidStats_callback(struct nl_msg *msg, void *arg) {
10196 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10197 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10198 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
10199 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
10200 int rem , tid_index = 0;
10201
10202 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
10203 wifi_associated_dev_tid_entry_t *stats_entry;
10204
10205 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
10206 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
10207 };
10208 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
10209 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
10210 };
10211
10212 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10213 genlmsg_attrlen(gnlh, 0), NULL);
10214
10215
10216 if (!tb[NL80211_ATTR_STA_INFO]) {
10217 fprintf(stderr, "station stats missing!\n");
10218 return NL_SKIP;
10219 }
10220
10221 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
10222 tb[NL80211_ATTR_STA_INFO],
10223 stats_policy)) {
10224 fprintf(stderr, "failed to parse nested attributes!\n");
10225 return NL_SKIP;
10226 }
10227
10228 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
10229 {
10230 stats_entry = &out->tid_array[tid_index];
10231
10232 stats_entry->tid = tid_index;
10233 stats_entry->ac = _tid_ac_index_get[tid_index];
10234
10235 if(sinfo[NL80211_STA_INFO_TID_STATS])
10236 {
10237 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
10238 printf("failed to parse nested stats attributes!");
10239 return NL_SKIP;
10240 }
10241 }
10242 if(stats_info[NL80211_TID_STATS_TX_MSDU])
10243 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
10244
10245 if(tid_index < (PS_MAX_TID - 1))
10246 tid_index++;
10247 }
10248 //ToDo: sum_time_ms, ewma_time_ms
10249 return NL_SKIP;
10250}
10251#endif
10252
10253INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
10254{
10255#ifdef HAL_NETLINK_IMPL
10256 Netlink nl;
10257 char if_name[10];
10258 char interface_name[16] = {0};
10259
10260 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10261 return RETURN_ERR;
10262
10263 snprintf(if_name, sizeof(if_name), "%s", interface_name);
10264
10265 nl.id = initSock80211(&nl);
10266
10267 if (nl.id < 0) {
10268 fprintf(stderr, "Error initializing netlink \n");
10269 return -1;
10270 }
10271
10272 struct nl_msg* msg = nlmsg_alloc();
10273
10274 if (!msg) {
10275 fprintf(stderr, "Failed to allocate netlink message.\n");
10276 nlfree(&nl);
10277 return -2;
10278 }
10279
10280 genlmsg_put(msg,
10281 NL_AUTO_PORT,
10282 NL_AUTO_SEQ,
10283 nl.id,
10284 0,
10285 0,
10286 NL80211_CMD_GET_STATION,
10287 0);
10288
10289 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
10290 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
10291 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
10292 nl_send_auto(nl.socket, msg);
10293 nl_recvmsgs(nl.socket, nl.cb);
10294 nlmsg_free(msg);
10295 nlfree(&nl);
10296 return RETURN_OK;
10297#else
10298//iw implementation
10299#define TID_STATS_FILE "/tmp/tid_stats_file.txt"
10300#define TOTAL_MAX_LINES 50
10301
10302 char buf[256] = {'\0'}; /* or other suitable maximum line size */
10303 char if_name[32] = {0};
10304 FILE *fp=NULL;
10305 char pipeCmd[1024]= {'\0'};
10306 int lines,tid_index=0;
10307 char mac_addr[20] = {'\0'};
10308
10309 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
10310 return RETURN_ERR;
10311
10312 wifi_associated_dev_tid_entry_t *stats_entry;
10313
10314 strcpy(mac_addr,clientMacAddress);
10315
10316 snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name);
10317 fp= popen(pipeCmd,"r");
10318 if(fp == NULL)
10319 {
10320 perror("popen for station dump failed\n");
10321 return RETURN_ERR;
10322 }
10323 pclose(fp);
10324
10325 snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1");
10326 fp=popen(pipeCmd,"r");
10327 if(fp == NULL)
10328 {
10329 perror("popen for grep station failed\n");
10330 return RETURN_ERR;
10331 }
10332 else if(fgets(buf,sizeof(buf),fp) != NULL)
10333 lines=atoi(buf);
10334 else
10335 {
10336 pclose(fp);
10337 fprintf(stderr,"No devices are connected \n");
10338 return RETURN_ERR;
10339 }
10340 pclose(fp);
10341
10342 if(lines == 1)
10343 lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output
10344
10345 for(tid_index=0; tid_index<PS_MAX_TID; tid_index++)
10346 {
10347 stats_entry = &tid_stats->tid_array[tid_index];
10348 stats_entry->tid = tid_index;
10349
10350 snprintf(pipeCmd, sizeof(pipeCmd),"cat "TID_STATS_FILE" | awk '/%s/ {for(i=0; i<=%d; i++) {getline; print}}' | grep -F -A%d 'MSDU' | awk '{print $3}' | tail -1",mac_addr,lines,tid_index+2);
10351
10352 fp=popen(pipeCmd,"r");
10353 if(fp ==NULL)
10354 {
10355 perror("Failed to read from tid file \n");
10356 return RETURN_ERR;
10357 }
10358 else if(fgets(buf,sizeof(buf),fp) != NULL)
10359 stats_entry->num_msdus = atol(buf);
10360
10361 pclose(fp);
10362 stats_entry->ac = _tid_ac_index_get[tid_index];
10363// TODO:
10364// ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus
10365// ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval
10366 }
10367 return RETURN_OK;
10368#endif
10369}
10370
10371
10372INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
10373{
10374 char interface_name[16] = {0};
10375 char cmd[128]={0};
10376 char buf[128]={0};
10377 int freq = 0;
10378
10379 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10380
10381 // full mode is used to scan all channels.
10382 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
10383 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
10384 ieee80211_channel_to_frequency(chan_list[0], &freq);
10385
10386 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10387 return RETURN_ERR;
10388
10389 if (freq)
10390 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
10391 else
10392 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
10393
10394 _syscmd(cmd, buf, sizeof(buf));
10395 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10396
10397 return RETURN_OK;
10398}
10399
10400
10401INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
10402{
10403 // TODO Implement me!
10404 return RETURN_ERR;
10405}
10406
10407INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
10408{
10409 // TODO Implement me!
10410 return RETURN_ERR;
10411}
10412
10413INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
10414{
10415 // TODO Implement me!
10416 return RETURN_ERR;
10417}
10418
10419INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
10420{
10421 // TODO Implement me!
10422 return RETURN_ERR;
10423}
10424
10425INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
10426{
10427 // TODO Implement me!
10428 return RETURN_ERR;
10429}
10430
10431INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
10432{
10433 // TODO Implement me!
10434 return RETURN_ERR;
10435}
10436
10437INT wifi_steering_eventUnregister(void)
10438{
10439 // TODO Implement me!
10440 return RETURN_ERR;
10441}
10442
10443INT wifi_delApAclDevices(INT apIndex)
10444{
developer7e4a2a62023-04-06 19:56:03 +080010445 char cmd[MAX_CMD_SIZE] = {0};
10446 char buf[MAX_BUF_SIZE] = {0};
10447 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010448
developer7e4a2a62023-04-06 19:56:03 +080010449 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
10450 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010451
developer7e4a2a62023-04-06 19:56:03 +080010452 /* mwctl acl clear all stas */
10453 snprintf(cmd, sizeof(cmd), "mwctl %s acl clear_all", inf_name);
10454 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010455
10456 return RETURN_OK;
10457}
10458
10459#ifdef HAL_NETLINK_IMPL
10460static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
10461 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10462 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10463 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
10464 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
10465 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
10466 char mac_addr[20],dev[20];
10467
10468 nla_parse(tb,
10469 NL80211_ATTR_MAX,
10470 genlmsg_attrdata(gnlh, 0),
10471 genlmsg_attrlen(gnlh, 0),
10472 NULL);
10473
10474 if(!tb[NL80211_ATTR_STA_INFO]) {
10475 fprintf(stderr, "sta stats missing!\n");
10476 return NL_SKIP;
10477 }
10478
10479 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
10480 fprintf(stderr, "failed to parse nested attributes!\n");
10481 return NL_SKIP;
10482 }
10483 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
10484
10485 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
10486
10487 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
10488 fprintf(stderr, "failed to parse nested rate attributes!");
10489 return NL_SKIP;
10490 }
10491
10492 if(sinfo[NL80211_STA_INFO_TID_STATS])
10493 {
10494 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
10495 printf("failed to parse nested stats attributes!");
10496 return NL_SKIP;
10497 }
10498 }
10499
10500 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
10501 {
10502 printf("Type is VHT\n");
10503 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
10504 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
10505
10506 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
10507 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
10508 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
10509 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
10510 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
10511 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
10512 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
10513 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
10514 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
10515 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
10516 }
10517 else
10518 {
10519 printf(" OFDM or CCK \n");
10520 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
10521 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
10522 }
10523
10524 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
10525 if(rinfo[NL80211_RATE_INFO_MCS])
10526 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
10527 }
10528 if(sinfo[NL80211_STA_INFO_RX_BYTES64])
10529 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
10530 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
10531 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
10532
10533 if(stats_info[NL80211_TID_STATS_RX_MSDU])
10534 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
10535
10536 if (sinfo[NL80211_STA_INFO_SIGNAL])
10537 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
10538 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
10539 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
10540 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
10541 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
10542 //rssi_array need to be filled
10543 return NL_SKIP;
10544}
10545#endif
10546
10547INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
10548{
10549#ifdef HAL_NETLINK_IMPL
10550 Netlink nl;
10551 char if_name[32];
10552 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
10553 return RETURN_ERR;
10554
10555 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
10556
10557 if (*output_array_size <= 0)
10558 return RETURN_OK;
10559
10560 nl.id = initSock80211(&nl);
10561
10562 if (nl.id < 0) {
10563 fprintf(stderr, "Error initializing netlink \n");
10564 return 0;
10565 }
10566
10567 struct nl_msg* msg = nlmsg_alloc();
10568
10569 if (!msg) {
10570 fprintf(stderr, "Failed to allocate netlink message.\n");
10571 nlfree(&nl);
10572 return 0;
10573 }
10574
10575 genlmsg_put(msg,
10576 NL_AUTO_PORT,
10577 NL_AUTO_SEQ,
10578 nl.id,
10579 0,
10580 0,
10581 NL80211_CMD_GET_STATION,
10582 0);
10583
10584 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
10585 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
10586 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
10587 nl_send_auto(nl.socket, msg);
10588 nl_recvmsgs(nl.socket, nl.cb);
10589 nlmsg_free(msg);
10590 nlfree(&nl);
10591 return RETURN_OK;
10592#else
10593 //TODO Implement me
10594 return RETURN_OK;
10595#endif
10596}
10597
10598#ifdef HAL_NETLINK_IMPL
10599static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
10600 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10601 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10602 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
10603 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
10604 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
10605 char mac_addr[20],dev[20];
10606
10607 nla_parse(tb,
10608 NL80211_ATTR_MAX,
10609 genlmsg_attrdata(gnlh, 0),
10610 genlmsg_attrlen(gnlh, 0),
10611 NULL);
10612
10613 if(!tb[NL80211_ATTR_STA_INFO]) {
10614 fprintf(stderr, "sta stats missing!\n");
10615 return NL_SKIP;
10616 }
10617
10618 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
10619 fprintf(stderr, "failed to parse nested attributes!\n");
10620 return NL_SKIP;
10621 }
10622
10623 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
10624
10625 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
10626
10627 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
10628 fprintf(stderr, "failed to parse nested rate attributes!");
10629 return NL_SKIP;
10630 }
10631
10632 if(sinfo[NL80211_STA_INFO_TID_STATS])
10633 {
10634 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
10635 printf("failed to parse nested stats attributes!");
10636 return NL_SKIP;
10637 }
10638 }
10639 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
10640 {
10641 printf("Type is VHT\n");
10642 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
10643 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
10644
10645 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
10646 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
10647 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
10648 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
10649 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
10650 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
10651 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
10652 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
10653 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
10654 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
10655 }
10656 else
10657 {
10658 printf(" OFDM or CCK \n");
10659 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
10660 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
10661 }
10662
10663 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
10664 if(rinfo[NL80211_RATE_INFO_MCS])
10665 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
10666 }
10667
10668 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
10669 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
10670 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
10671 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
10672
10673 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
10674 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
10675 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
10676
10677 if(stats_info[NL80211_TID_STATS_TX_MSDU])
10678 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
10679
10680 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
10681 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
10682
10683 if(sinfo[NL80211_STA_INFO_TX_FAILED])
10684 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->attempts = nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS]) + nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED]);
10685
10686 return NL_SKIP;
10687}
10688#endif
10689
10690INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
10691{
10692#ifdef HAL_NETLINK_IMPL
10693 Netlink nl;
10694 char if_name[10];
10695 char interface_name[16] = {0};
10696 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10697 return RETURN_ERR;
10698
10699 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
10700
10701 if (*output_array_size <= 0)
10702 return RETURN_OK;
10703
10704 snprintf(if_name, sizeof(if_name), "%s", interface_name);
10705
10706 nl.id = initSock80211(&nl);
10707
10708 if(nl.id < 0) {
10709 fprintf(stderr, "Error initializing netlink \n");
10710 return 0;
10711 }
10712
10713 struct nl_msg* msg = nlmsg_alloc();
10714
10715 if(!msg) {
10716 fprintf(stderr, "Failed to allocate netlink message.\n");
10717 nlfree(&nl);
10718 return 0;
10719 }
10720
10721 genlmsg_put(msg,
10722 NL_AUTO_PORT,
10723 NL_AUTO_SEQ,
10724 nl.id,
10725 0,
10726 0,
10727 NL80211_CMD_GET_STATION,
10728 0);
10729
10730 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
10731 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
10732 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
10733 nl_send_auto(nl.socket, msg);
10734 nl_recvmsgs(nl.socket, nl.cb);
10735 nlmsg_free(msg);
10736 nlfree(&nl);
10737 return RETURN_OK;
10738#else
10739 //TODO Implement me
10740 return RETURN_OK;
10741#endif
10742}
10743
10744INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
10745{
10746 // TODO Implement me!
10747 char buf[MAX_BUF_SIZE] = {0};
10748 char config_file[MAX_BUF_SIZE] = {0};
10749
10750 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10751 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
10752 *activate = (strncmp("1",buf,1) == 0);
10753
10754 return RETURN_OK;
10755}
10756
10757INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
10758{
10759 char config_file[MAX_BUF_SIZE] = {0};
10760 struct params list;
10761
10762 list.name = "rrm_neighbor_report";
10763 list.value = activate?"1":"0";
10764 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
10765 wifi_hostapdWrite(config_file, &list, 1);
10766
10767 return RETURN_OK;
10768}
10769
10770INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
10771{
10772 char buf[32] = {0};
10773 char config_file[MAX_BUF_SIZE] = {0};
10774
10775 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
10776 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
10777 *activate = (strncmp("1",buf,1) == 0);
10778
10779 return RETURN_OK;
10780}
10781#undef HAL_NETLINK_IMPL
10782#ifdef HAL_NETLINK_IMPL
10783static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
10784 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10785 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10786 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
10787 char dev[20];
10788 int freq =0 ;
10789 static int i=0;
10790
10791 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
10792
10793 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
10794 };
10795
10796 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
10797
10798 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
10799
10800 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
10801 fprintf(stderr, "survey data missing!\n");
10802 return NL_SKIP;
10803 }
10804
10805 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
10806 {
10807 fprintf(stderr, "failed to parse nested attributes!\n");
10808 return NL_SKIP;
10809 }
10810
10811
10812 if(out[0].array_size == 1 )
10813 {
10814 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
10815 {
10816 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
10817 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
10818 out[0].ch_number = ieee80211_frequency_to_channel(freq);
10819
10820 if (sinfo[NL80211_SURVEY_INFO_NOISE])
10821 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
10822 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
10823 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
10824 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
10825 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
10826 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
10827 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
10828 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
10829 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
10830 if (sinfo[NL80211_SURVEY_INFO_TIME])
10831 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
10832 return NL_STOP;
10833 }
10834 }
10835 else
10836 {
10837 if ( i <= out[0].array_size )
10838 {
10839 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
10840 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
10841 out[i].ch_number = ieee80211_frequency_to_channel(freq);
10842
10843 if (sinfo[NL80211_SURVEY_INFO_NOISE])
10844 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
10845 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
10846 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
10847 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
10848 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
10849 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
10850 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
10851 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
10852 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
10853 if (sinfo[NL80211_SURVEY_INFO_TIME])
10854 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
10855 }
10856 }
10857
10858 i++;
10859 return NL_SKIP;
10860}
10861#endif
10862
10863static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
10864{
10865 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
10866 FILE *fp;
10867
10868 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
10869 {
10870 printf("Creating Frequency-Channel Map\n");
10871 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
10872 }
10873 snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
10874 if((fp = popen(command, "r")))
10875 {
10876 fgets(output, sizeof(output), fp);
10877 *freqMHz = atoi(output);
10878 pclose(fp);
10879 }
10880
10881 return 0;
10882}
10883
10884static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz)
10885{
10886 int freqMHz = -1;
10887 char cmd[MAX_CMD_SIZE] = {'\0'};
10888 char interface_name[16] = {0};
10889
10890 ieee80211_channel_to_frequency(channel, &freqMHz);
10891 if (freqMHz == -1) {
10892 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
10893 return -1;
10894 }
10895
10896 wifi_GetInterfaceName(radioIndex, interface_name);
10897 if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) {
10898 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
10899 radioIndex, freqMHz);
10900 return -1;
10901 }
10902
10903 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
10904 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
10905 return -1;
10906 }
10907
10908 return 0;
10909}
10910
10911static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
10912{
10913 const char *ptr = buf;
10914 char *key = NULL;
10915 char *val = NULL;
10916 char line[256] = { '\0' };
10917
10918 while (ptr = get_line_from_str_buf(ptr, line)) {
10919 if (strstr(line, "Frequency")) continue;
10920
10921 key = strtok(line, ":");
10922 val = strtok(NULL, " ");
10923 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
10924
10925 if (!strcmp(key, "noise")) {
10926 sscanf(val, "%d", &stats->ch_noise);
10927 if (stats->ch_noise == 0) {
10928 // Workaround for missing noise information.
10929 // Assume -95 for 2.4G and -103 for 5G
10930 if (radioIndex == 0) stats->ch_noise = -95;
10931 if (radioIndex == 1) stats->ch_noise = -103;
10932 }
10933 }
10934 else if (!strcmp(key, "channel active time")) {
10935 sscanf(val, "%llu", &stats->ch_utilization_total);
10936 }
10937 else if (!strcmp(key, "channel busy time")) {
10938 sscanf(val, "%llu", &stats->ch_utilization_busy);
10939 }
10940 else if (!strcmp(key, "channel receive time")) {
10941 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
10942 }
10943 else if (!strcmp(key, "channel transmit time")) {
10944 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
10945 }
10946 };
10947
10948 return 0;
10949}
10950
10951INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
10952{
10953 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10954#ifdef HAL_NETLINK_IMPL
10955 Netlink nl;
10956 wifi_channelStats_t_loc local[array_size];
10957 char if_name[32];
10958
10959 local[0].array_size = array_size;
10960
10961 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
10962 return RETURN_ERR;
10963
10964 nl.id = initSock80211(&nl);
10965
10966 if (nl.id < 0) {
10967 fprintf(stderr, "Error initializing netlink \n");
10968 return -1;
10969 }
10970
10971 struct nl_msg* msg = nlmsg_alloc();
10972
10973 if (!msg) {
10974 fprintf(stderr, "Failed to allocate netlink message.\n");
10975 nlfree(&nl);
10976 return -2;
10977 }
10978
10979 genlmsg_put(msg,
10980 NL_AUTO_PORT,
10981 NL_AUTO_SEQ,
10982 nl.id,
10983 0,
10984 NLM_F_DUMP,
10985 NL80211_CMD_GET_SURVEY,
10986 0);
10987
10988 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
10989 nl_send_auto(nl.socket, msg);
10990 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
10991 nl_recvmsgs(nl.socket, nl.cb);
10992 nlmsg_free(msg);
10993 nlfree(&nl);
10994 //Copying the Values
10995 for(int i=0;i<array_size;i++)
10996 {
10997 input_output_channelStats_array[i].ch_number = local[i].ch_number;
10998 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
10999 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
11000 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
11001 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
11002 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
11003 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
11004 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
11005 }
11006#else
11007 ULONG channel = 0;
11008 int i;
11009 int number_of_channels = array_size;
11010 char buf[512];
11011 INT ret;
11012 wifi_channelStats_t tmp_stats;
11013
11014 if (number_of_channels == 0) {
11015 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
11016 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
11017 return RETURN_ERR;
11018 }
11019 number_of_channels = 1;
11020 input_output_channelStats_array[0].ch_number = channel;
11021 }
11022
11023 for (i = 0; i < number_of_channels; i++) {
11024
11025 input_output_channelStats_array[i].ch_noise = 0;
11026 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
11027 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
11028 input_output_channelStats_array[i].ch_utilization_busy = 0;
11029 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
11030 input_output_channelStats_array[i].ch_utilization_total = 0;
11031
11032 memset(buf, 0, sizeof(buf));
11033 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
11034 return RETURN_ERR;
11035 }
11036 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
11037 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
11038 return RETURN_ERR;
11039 }
11040
11041 // XXX: fake missing 'self' counter which is not available in iw survey output
11042 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
11043 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
11044
11045 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
11046 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
11047 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
11048 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
11049 input_output_channelStats_array[i].ch_utilization_total *= 1000;
11050
11051 wifi_dbg_printf("%s: ch_number=%d ch_noise=%d total=%llu busy=%llu busy_rx=%llu busy_tx=%llu busy_self=%llu busy_ext=%llu\n",
11052 __func__,
11053 input_output_channelStats_array[i].ch_number,
11054 input_output_channelStats_array[i].ch_noise,
11055 input_output_channelStats_array[i].ch_utilization_total,
11056 input_output_channelStats_array[i].ch_utilization_busy,
11057 input_output_channelStats_array[i].ch_utilization_busy_rx,
11058 input_output_channelStats_array[i].ch_utilization_busy_tx,
11059 input_output_channelStats_array[i].ch_utilization_busy_self,
11060 input_output_channelStats_array[i].ch_utilization_busy_ext);
11061 }
11062#endif
11063 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11064 return RETURN_OK;
11065}
11066#define HAL_NETLINK_IMPL
11067
11068/* Hostapd events */
11069
11070#ifndef container_of
11071#define offset_of(st, m) ((size_t)&(((st *)0)->m))
11072#define container_of(ptr, type, member) \
11073 ((type *)((char *)ptr - offset_of(type, member)))
11074#endif /* container_of */
11075
11076struct ctrl {
11077 char sockpath[128];
11078 char sockdir[128];
11079 char bss[IFNAMSIZ];
11080 char reply[4096];
11081 int ssid_index;
11082 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
11083 void (*overrun)(struct ctrl *ctrl);
11084 struct wpa_ctrl *wpa;
11085 unsigned int ovfl;
11086 size_t reply_len;
11087 int initialized;
11088 ev_timer retry;
11089 ev_timer watchdog;
11090 ev_stat stat;
11091 ev_io io;
11092};
11093static wifi_newApAssociatedDevice_callback clients_connect_cb;
11094static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
11095static struct ctrl wpa_ctrl[MAX_APS];
11096static int initialized;
11097
11098static unsigned int ctrl_get_drops(struct ctrl *ctrl)
11099{
11100 char cbuf[256] = {};
11101 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
11102 struct cmsghdr *cmsg;
11103 unsigned int ovfl = ctrl->ovfl;
11104 unsigned int drop;
11105
11106 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
11107 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
11108 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
11109 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
11110
11111 drop = ovfl - ctrl->ovfl;
11112 ctrl->ovfl = ovfl;
11113
11114 return drop;
11115}
11116
11117static void ctrl_close(struct ctrl *ctrl)
11118{
11119 if (ctrl->io.cb)
11120 ev_io_stop(EV_DEFAULT_ &ctrl->io);
11121 if (ctrl->retry.cb)
11122 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
11123 if (!ctrl->wpa)
11124 return;
11125
11126 wpa_ctrl_detach(ctrl->wpa);
11127 wpa_ctrl_close(ctrl->wpa);
11128 ctrl->wpa = NULL;
11129 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
11130}
11131
11132static void ctrl_process(struct ctrl *ctrl)
11133{
11134 const char *str;
11135 int drops;
11136 int level;
11137 int err;
11138
11139 /* Example events:
11140 *
11141 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
11142 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
11143 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
11144 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
11145 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
11146 */
11147 if (!(str = index(ctrl->reply, '>')))
11148 return;
11149 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
11150 return;
11151
11152 str++;
11153
11154 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
11155 if (!(str = index(ctrl->reply, ' ')))
11156 return;
11157 wifi_associated_dev_t sta;
11158 memset(&sta, 0, sizeof(sta));
11159
11160 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
11161 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
11162 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
11163
11164 sta.cli_Active=true;
11165
11166 (clients_connect_cb)(ctrl->ssid_index, &sta);
11167 goto handled;
11168 }
11169
11170 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
11171 if (!(str = index(ctrl->reply, ' ')))
11172 return;
11173
11174 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
11175 goto handled;
11176 }
11177
11178 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
11179 printf("CTRL_WPA: handle TERMINATING event\n");
11180 goto retry;
11181 }
11182
11183 if (strncmp("AP-DISABLED", str, 11) == 0) {
11184 printf("CTRL_WPA: handle AP-DISABLED\n");
11185 goto retry;
11186 }
11187
11188 printf("Event not supported!!\n");
11189
11190handled:
11191
11192 if ((drops = ctrl_get_drops(ctrl))) {
11193 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
11194 if (ctrl->overrun)
11195 ctrl->overrun(ctrl);
11196 }
11197
11198 return;
11199
11200retry:
11201 printf("WPA_CTRL: closing\n");
11202 ctrl_close(ctrl);
11203 printf("WPA_CTRL: retrying from ctrl prcoess\n");
11204 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
11205}
11206
11207static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
11208{
11209 struct ctrl *ctrl = container_of(io, struct ctrl, io);
11210 int err;
11211
11212 memset(ctrl->reply, 0, sizeof(ctrl->reply));
11213 ctrl->reply_len = sizeof(ctrl->reply) - 1;
11214 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
11215 ctrl->reply[ctrl->reply_len] = 0;
11216 if (err < 0) {
11217 if (errno == EAGAIN || errno == EWOULDBLOCK)
11218 return;
11219 ctrl_close(ctrl);
11220 ev_timer_again(EV_A_ &ctrl->retry);
11221 return;
11222 }
11223
11224 ctrl_process(ctrl);
11225}
11226
11227static int ctrl_open(struct ctrl *ctrl)
11228{
11229 int fd;
11230
11231 if (ctrl->wpa)
11232 return 0;
11233
11234 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
11235 if (!ctrl->wpa)
11236 goto err;
11237
11238 if (wpa_ctrl_attach(ctrl->wpa) < 0)
11239 goto err_close;
11240
11241 fd = wpa_ctrl_get_fd(ctrl->wpa);
11242 if (fd < 0)
11243 goto err_detach;
11244
11245 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
11246 goto err_detach;
11247
11248 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
11249 ev_io_start(EV_DEFAULT_ &ctrl->io);
11250
11251 return 0;
11252
11253err_detach:
11254 wpa_ctrl_detach(ctrl->wpa);
11255err_close:
11256 wpa_ctrl_close(ctrl->wpa);
11257err:
11258 ctrl->wpa = NULL;
11259 return -1;
11260}
11261
11262static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
11263{
11264 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
11265
11266 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
11267 ctrl_open(ctrl);
11268}
11269
11270static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
11271{
11272 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
11273
11274 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
11275 if (ctrl_open(ctrl) == 0) {
11276 printf("WPA_CTRL: retry successful\n");
11277 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
11278 }
11279}
11280
11281int ctrl_enable(struct ctrl *ctrl)
11282{
11283 if (ctrl->wpa)
11284 return 0;
11285
11286 if (!ctrl->stat.cb) {
11287 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
11288 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
11289 }
11290
11291 if (!ctrl->retry.cb) {
11292 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
11293 }
11294
11295 return ctrl_open(ctrl);
11296}
11297
11298static void
11299ctrl_msg_cb(char *buf, size_t len)
11300{
11301 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
11302
11303 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
11304 ctrl_process(ctrl);
11305}
11306
11307static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
11308{
11309 int err;
11310
11311 if (!ctrl->wpa)
11312 return -1;
11313 if (*reply_len < 2)
11314 return -1;
11315
11316 (*reply_len)--;
11317 ctrl->reply_len = sizeof(ctrl->reply);
11318 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
11319 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
11320 if (err < 0)
11321 return err;
11322
11323 if (ctrl->reply_len > *reply_len)
11324 ctrl->reply_len = *reply_len;
11325
11326 *reply_len = ctrl->reply_len;
11327 memcpy(reply, ctrl->reply, *reply_len);
11328 reply[*reply_len - 1] = 0;
11329 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
11330 return 0;
11331}
11332
11333static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
11334{
11335 const char *pong = "PONG";
11336 const char *ping = "PING";
11337 char reply[1024];
11338 size_t len = sizeof(reply);
11339 int err;
11340 ULONG s, snum;
11341 INT ret;
11342 BOOL status;
11343
11344 printf("WPA_CTRL: watchdog cb\n");
11345
11346 ret = wifi_getSSIDNumberOfEntries(&snum);
11347 if (ret != RETURN_OK) {
11348 printf("%s: failed to get SSID count", __func__);
11349 return;
11350 }
11351
11352 if (snum > MAX_APS) {
11353 printf("more ssid than supported! %lu\n", snum);
11354 return;
11355 }
11356
11357 for (s = 0; s < snum; s++) {
11358 if (wifi_getApEnable(s, &status) != RETURN_OK) {
11359 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
11360 continue;
11361 }
11362 if (status == false) continue;
11363
11364 memset(reply, 0, sizeof(reply));
11365 len = sizeof(reply);
11366 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
11367 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
11368 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
11369 continue;
11370
11371 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
11372 ctrl_close(&wpa_ctrl[s]);
11373 printf("WPA_CTRL: ev_timer_again %lu\n", s);
11374 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
11375 }
11376}
11377
11378static int init_wpa()
11379{
11380 int ret = 0, i = 0;
11381 ULONG s, snum;
11382
11383 ret = wifi_getSSIDNumberOfEntries(&snum);
11384 if (ret != RETURN_OK) {
11385 printf("%s: failed to get SSID count", __func__);
11386 return RETURN_ERR;
11387 }
11388
11389 if (snum > MAX_APS) {
11390 printf("more ssid than supported! %lu\n", snum);
11391 return RETURN_ERR;
11392 }
11393
11394 for (s = 0; s < snum; s++) {
11395 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
11396 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
11397 wpa_ctrl[s].ssid_index = s;
11398 ctrl_enable(&wpa_ctrl[s]);
11399 }
11400
11401 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
11402 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
11403
11404 initialized = 1;
11405 printf("WPA_CTRL: initialized\n");
11406
11407 return RETURN_OK;
11408}
11409
11410void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
11411{
11412 clients_connect_cb = callback_proc;
11413 if (!initialized)
11414 init_wpa();
11415}
11416
11417void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
11418{
11419 clients_disconnect_cb = callback_proc;
11420 if (!initialized)
11421 init_wpa();
11422}
11423
11424INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
11425{
11426 // TODO Implement me!
11427 return RETURN_ERR;
11428}
11429
11430INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
11431{
11432 // TODO Implement me!
11433 return RETURN_ERR;
11434}
11435
11436INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
11437{
11438 int i;
developer59fda4f2023-05-16 15:47:38 +080011439 char cmd[256];
11440 char channel_numbers_buf[256];
11441 char dfs_state_buf[256];
11442 char line[256];
developer72fb0bb2023-01-11 09:46:29 +080011443 const char *ptr;
11444
developer59fda4f2023-05-16 15:47:38 +080011445 memset(cmd, 0, sizeof(cmd));
11446 memset(channel_numbers_buf, 0, sizeof(channel_numbers_buf));
11447 memset(line, 0, sizeof(line));
11448 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
11449 memset(outputMap, 0, outputMapSize); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080011450
developer59fda4f2023-05-16 15:47:38 +080011451 if (radioIndex == 0) { // 2.4G - all allowed
11452 if (outputMapSize < 11) {
11453 wifi_dbg_printf("%s: outputMapSize too small (%d)\n", __FUNCTION__, outputMapSize);
11454 return RETURN_ERR;
11455 }
developer72fb0bb2023-01-11 09:46:29 +080011456
developer59fda4f2023-05-16 15:47:38 +080011457 for (i = 0; i < 11; i++) {
11458 outputMap[i].ch_number = i + 1;
11459 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
11460 }
developer72fb0bb2023-01-11 09:46:29 +080011461
developer59fda4f2023-05-16 15:47:38 +080011462 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011463 }
11464
developer59fda4f2023-05-16 15:47:38 +080011465 if (radioIndex == 1) { // 5G
11466// Example output of iw list:
11467//
11468// Frequencies:
11469// * 5180 MHz [36] (17.0 dBm)
11470// * 5200 MHz [40] (17.0 dBm)
11471// * 5220 MHz [44] (17.0 dBm)
11472// * 5240 MHz [48] (17.0 dBm)
11473// * 5260 MHz [52] (23.0 dBm) (radar detection)
11474// DFS state: usable (for 78930 sec)
11475// DFS CAC time: 60000 ms
11476// * 5280 MHz [56] (23.0 dBm) (radar detection)
11477// DFS state: usable (for 78930 sec)
11478// DFS CAC time: 60000 ms
11479// * 5300 MHz [60] (23.0 dBm) (radar detection)
11480// DFS state: usable (for 78930 sec)
11481// DFS CAC time: 60000 ms
11482// * 5320 MHz [64] (23.0 dBm) (radar detection)
11483// DFS state: usable (for 78930 sec)
11484// DFS CAC time: 60000 ms
11485// * 5500 MHz [100] (disabled)
11486// * 5520 MHz [104] (disabled)
11487// * 5540 MHz [108] (disabled)
11488// * 5560 MHz [112] (disabled)
11489//
11490// Below command should fetch channel numbers of each enabled channel in 5GHz band:
11491 if (sprintf(cmd,"iw list | grep MHz | tr -d '\\t' | grep -v disabled | tr -d '*' | grep '^ 5' | awk '{print $3}' | tr -d '[]'") < 0) {
11492 wifi_dbg_printf("%s: failed to build iw list command\n", __FUNCTION__);
developer72fb0bb2023-01-11 09:46:29 +080011493 return RETURN_ERR;
11494 }
11495
developer59fda4f2023-05-16 15:47:38 +080011496 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
developer72fb0bb2023-01-11 09:46:29 +080011497 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
11498 return RETURN_ERR;
11499 }
11500
developer59fda4f2023-05-16 15:47:38 +080011501 ptr = channel_numbers_buf;
11502 i = 0;
11503 while (ptr = get_line_from_str_buf(ptr, line)) {
11504 if (i >= outputMapSize) {
11505 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
11506 return RETURN_ERR;
11507 }
11508 sscanf(line, "%d", &outputMap[i].ch_number);
developer72fb0bb2023-01-11 09:46:29 +080011509
developer59fda4f2023-05-16 15:47:38 +080011510 memset(cmd, 0, sizeof(cmd));
11511 // Below command should fetch string for DFS state (usable, available or unavailable)
11512 // Example line: "DFS state: usable (for 78930 sec)"
11513 if (sprintf(cmd,"iw list | grep -A 2 '\\[%d\\]' | tr -d '\\t' | grep 'DFS state' | awk '{print $3}' | tr -d '\\n'", outputMap[i].ch_number) < 0) {
11514 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
11515 return RETURN_ERR;
11516 }
11517
11518 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
11519 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
11520 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
11521 return RETURN_ERR;
11522 }
11523
11524 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
11525
11526 if (!strcmp(dfs_state_buf, "usable")) {
11527 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
11528 } else if (!strcmp(dfs_state_buf, "available")) {
11529 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
11530 } else if (!strcmp(dfs_state_buf, "unavailable")) {
11531 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
11532 } else {
11533 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
11534 }
11535 i++;
developer72fb0bb2023-01-11 09:46:29 +080011536 }
developer72fb0bb2023-01-11 09:46:29 +080011537
developer59fda4f2023-05-16 15:47:38 +080011538 return RETURN_OK;
11539 }
developer40ba1762023-05-13 11:03:49 +080011540
developer72fb0bb2023-01-11 09:46:29 +080011541 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
11542 return RETURN_ERR;
11543}
11544
11545INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
11546{
11547 // TODO Implement me!
11548 return RETURN_ERR;
11549}
11550
11551INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
11552{
11553 return RETURN_OK;
11554}
11555
11556INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
11557{
11558 // TODO Implement me!
11559 return RETURN_ERR;
11560}
11561
11562INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
11563{
11564 // TODO API refrence Implementaion is present on RPI hal
11565 return RETURN_ERR;
11566}
11567
11568INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
11569{
developera1255e42023-05-13 17:45:02 +080011570/*
developer72fb0bb2023-01-11 09:46:29 +080011571 char interface_name[16] = {0};
11572 char cmd[128]={'\0'};
11573 char buf[128]={'\0'};
11574 char *support;
11575 int maximum_tx = 0, current_tx = 0;
developera1255e42023-05-13 17:45:02 +080011576*/ ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080011577
11578 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11579 if(txpwr_pcntg == NULL)
11580 return RETURN_ERR;
11581
developera1255e42023-05-13 17:45:02 +080011582 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
11583 *txpwr_pcntg = pwr_percentage;
11584/* if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +080011585 return RETURN_ERR;
11586
11587 // Get the maximum tx power of the device
11588 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
11589 _syscmd(cmd, buf, sizeof(buf));
11590 maximum_tx = strtol(buf, NULL, 10);
11591
11592 // Get the current tx power
11593 memset(cmd, 0, sizeof(cmd));
11594 memset(buf, 0, sizeof(buf));
11595 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
11596 _syscmd(cmd, buf, sizeof(buf));
11597 current_tx = strtol(buf, NULL, 10);
11598
11599 // Get the power supported list and find the current power percentage in supported list
11600 memset(buf, 0, sizeof(buf));
11601 wifi_getRadioTransmitPowerSupported(apIndex, buf);
11602 support = strtok(buf, ",");
11603 while(true)
11604 {
11605 if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal.
11606 *txpwr_pcntg = 100;
11607 wifi_dbg_printf("current power is not in supported list\n");
11608 return RETURN_OK;
11609 }
11610 int tmp = maximum_tx*strtol(support, NULL, 10)/100;
11611 if (tmp == current_tx) {
11612 *txpwr_pcntg = strtol(support, NULL, 10);
11613 break;
11614 }
11615 support = strtok(NULL, ",");
11616 }
developera1255e42023-05-13 17:45:02 +080011617*/
developer72fb0bb2023-01-11 09:46:29 +080011618 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11619 return RETURN_OK;
11620}
11621
11622INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
11623{
11624 // TODO precac feature.
11625 struct params params = {0};
11626 char config_file[128] = {0};
11627
11628 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11629
11630 params.name = "enable_background_radar";
11631 params.value = enable?"1":"0";
11632 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
11633 wifi_hostapdWrite(config_file, &params, 1);
11634 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
11635
11636 /* TODO precac feature */
11637
11638 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11639 return RETURN_OK;
11640}
11641
11642INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
11643{
11644 char config_file[128] = {0};
11645 char buf[64] = {0};
11646
11647 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11648 if (NULL == enable || NULL == precac)
11649 return RETURN_ERR;
11650
11651 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
11652 wifi_hostapdRead(config_file, "enable_background_radar", buf, sizeof(buf));
11653 if (strncmp(enable, "1", 1) == 0)
11654 *enable = true;
11655 else
11656 *enable = false;
11657
11658 /* TODO precac feature */
11659
11660 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11661 return RETURN_OK;
11662}
11663
11664INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
11665{
11666 *supported = TRUE;
11667 return RETURN_OK;
11668}
11669
11670INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
11671{
developera1255e42023-05-13 17:45:02 +080011672 UCHAR dat_file[64] = {0};
11673 wifi_band band = band_invalid;
11674 char cmd[128] = {0};
11675 char buf[256] = {0};
11676 char ofdmabuf[32] = {'\0'};
11677 char mimobuf[32] = {'\0'};
11678 char new_ofdmabuf[32] = {'\0'};
11679 char new_mimobuf[32] = {'\0'};
11680 struct params params[2];
11681 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
11682 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
11683 UCHAR bss_cnt = 0;
11684 UCHAR val_cnt = 0;
11685 char *token = NULL;
developer72fb0bb2023-01-11 09:46:29 +080011686
developera1255e42023-05-13 17:45:02 +080011687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11688 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
11689 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
11690 printf("%s:mu_type input Error", __func__);
11691 return RETURN_ERR;
11692 }
11693 band = wifi_index_to_band(radio_index);
11694 if (band == band_invalid) {
11695 printf("%s:Band Error\n", __func__);
11696 return RETURN_ERR;
11697 }
11698 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
11699 /*get current value in dat file*/
11700 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
11701 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
11702 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
11703 get_bssnum_byindex(radio_index, &bss_cnt);
11704 val_cnt = 2*bss_cnt - 1;
11705 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
11706 if ((val_cnt >= sizeof(new_ofdmabuf))
11707 || (val_cnt >= sizeof(new_mimobuf))) {
11708 printf("%s:bss cnt Error", __func__, bss_cnt);
11709 return RETURN_ERR;
11710 }
11711 /*translate set value*/
11712 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
11713 strncpy(new_ofdmabuf, str_zero, val_cnt);
11714 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080011715 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080011716 strncpy(new_ofdmabuf, str_one, val_cnt);
11717 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080011718 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080011719 strncpy(new_ofdmabuf, str_zero, val_cnt);
11720 strncpy(new_mimobuf, str_one, val_cnt);
11721 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
11722 strncpy(new_ofdmabuf, str_one, val_cnt);
11723 strncpy(new_mimobuf, str_one, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080011724 }
developera1255e42023-05-13 17:45:02 +080011725 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
11726 /*same value, not operation*/
11727 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
11728 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
11729 printf("%s:Reduntant value\n", __func__);
11730 return RETURN_OK;
11731 }
11732 /*modify dat file to new file*/
11733 params[0].name="MuOfdmaDlEnable";
11734 params[0].value=new_ofdmabuf;
11735 params[1].name="MuMimoDlEnable";
11736 params[1].value=new_mimobuf;
11737 wifi_datfileWrite(dat_file, params, 2);
11738 /*hostapd control restarp ap to take effect on these new value*/
11739 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080011740 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11741 return RETURN_OK;
11742}
11743
11744INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
11745{
11746 struct params params={0};
11747 char config_file[64] = {0};
11748 char buf[64] = {0};
11749 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080011750 UCHAR dat_file[64] = {0};
11751 wifi_band band = band_invalid;
11752 char ofdmabuf[32] = {'\0'};
11753 char mimobuf[32] = {'\0'};
11754 char *token = NULL;
11755 UCHAR ofdma = 0;
11756 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080011757
11758 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11759
11760 if (mu_type == NULL)
11761 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080011762 band = wifi_index_to_band(radio_index);
11763 if (band == band_invalid) {
11764 printf("%s:Band Error\n", __func__);
11765 return RETURN_ERR;
11766 }
11767 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
11768 /*get current value in dat file*/
11769 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
11770 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080011771
developera1255e42023-05-13 17:45:02 +080011772 token = strtok(ofdmabuf, ";");
11773 ofdma = strtol(token, NULL, 10);
11774 token = strtok(mimobuf, ";");
11775 mimo = strtol(token, NULL, 10);
11776 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
11777 if ((ofdma == 1) && (mimo == 1))
11778 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
11779 else if ((ofdma == 0) && (mimo == 1))
11780 *mu_type = WIFI_DL_MU_TYPE_MIMO;
11781 else if ((ofdma == 1) && (mimo == 0))
11782 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
11783 else
11784 *mu_type = WIFI_DL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080011785 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11786 return RETURN_OK;
11787}
11788
11789INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
11790{
11791 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developera1255e42023-05-13 17:45:02 +080011792 UCHAR dat_file[64] = {0};
11793 wifi_band band = band_invalid;
11794 char cmd[128] = {0};
11795 char buf[256] = {0};
11796 char ofdmabuf[32] = {'\0'};
11797 char mimobuf[32] = {'\0'};
11798 char new_ofdmabuf[32] = {'\0'};
11799 char new_mimobuf[32] = {'\0'};
11800 struct params params[2];
11801 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
11802 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
11803 UCHAR bss_cnt = 0;
11804 UCHAR val_cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080011805
developera1255e42023-05-13 17:45:02 +080011806 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11807 band = wifi_index_to_band(radio_index);
11808 if (band == band_invalid) {
11809 printf("%s:Band Error\n", __func__);
11810 return RETURN_ERR;
11811 }
11812 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
11813 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
11814 printf("%s:mu_type input Error\n", __func__);
11815 return RETURN_ERR;
11816 }
11817 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
11818 /*get current value in dat file*/
11819 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
11820 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
11821 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
11822 get_bssnum_byindex(radio_index, &bss_cnt);
11823 val_cnt = 2*bss_cnt - 1;
11824 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
11825 if ((val_cnt >= sizeof(new_ofdmabuf))
11826 || (val_cnt >= sizeof(new_mimobuf))) {
11827 printf("%s:bss cnt Error\n", __func__, val_cnt);
11828 return RETURN_ERR;
11829 }
11830 /*translate set value*/
11831 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
11832 strncpy(new_ofdmabuf, str_zero, val_cnt);
11833 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080011834 }
developera1255e42023-05-13 17:45:02 +080011835 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
11836 strncpy(new_ofdmabuf, str_one, val_cnt);
11837 strncpy(new_mimobuf, str_zero, val_cnt);
11838 }
11839 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
11840 /*same value, not operation*/
11841 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
11842 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
11843 printf("%s:Reduntant value\n", __func__);
11844 return RETURN_OK;
11845 }
11846 /*modify dat file to new file*/
11847 params[0].name="MuOfdmaUlEnable";
11848 params[0].value=new_ofdmabuf;
11849 params[1].name="MuMimoUlEnable";
11850 params[1].value=new_mimobuf;
11851 wifi_datfileWrite(dat_file, params, 2);
11852 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080011853 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11854 return RETURN_OK;
11855}
11856
11857INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
11858{
11859 struct params params={0};
11860 char config_file[64] = {0};
11861 char buf[64] = {0};
11862 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080011863 UCHAR dat_file[64] = {0};
11864 wifi_band band = band_invalid;
11865 char ofdmabuf[32] = {'\0'};
11866 char mimobuf[32] = {'\0'};
11867 char *token = NULL;
11868 UCHAR ofdma = 0;
11869 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080011870
11871 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11872
11873 if (mu_type == NULL)
11874 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080011875 band = wifi_index_to_band(radio_index);
11876 if (band == band_invalid) {
11877 printf("%s:Band Error", __func__);
11878 return RETURN_ERR;
11879 }
11880 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
11881 /*get current value in dat file*/
11882 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
11883 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080011884
developera1255e42023-05-13 17:45:02 +080011885 token = strtok(ofdmabuf, ";");
11886 ofdma = strtol(token, NULL, 10);
11887 token = strtok(mimobuf, ";");
11888 mimo = strtol(token, NULL, 10);
11889 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
11890 if ((ofdma == 1) && (mimo == 0))
11891 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
11892 else
11893 *mu_type = WIFI_UL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080011894 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11895 return RETURN_OK;
11896}
11897
11898
11899INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
11900{
11901 char cmd[128] = {0};
11902 char buf[256] = {0};
11903 char config_file[64] = {0};
11904 char GI[8] = {0};
11905 int mode_map = 0;
11906 FILE *f = NULL;
11907 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080011908 char dat_file[64] = {'\0'};
11909 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080011910
11911 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11912
11913 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
11914 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
11915 return RETURN_ERR;
11916 }
developera1255e42023-05-13 17:45:02 +080011917 /*sanity check*/
11918 if (((guard_interval == wifi_guard_interval_1600)
11919 || (guard_interval == wifi_guard_interval_3200))
11920 && (mode_map & (WIFI_MODE_BE | WIFI_MODE_AX) == 0)) {
11921 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
11922 return RETURN_ERR;
11923 }
developer72fb0bb2023-01-11 09:46:29 +080011924 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
11925 band = wifi_index_to_band(radio_index);
11926
11927 // Hostapd are not supported HE mode GI 1600, 3200 ns.
11928 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
11929 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
11930 _syscmd(cmd, buf, sizeof(buf));
11931 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
11932 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
11933 if (strstr(buf, "[SHORT-GI-") == NULL) {
11934 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
11935 _syscmd(cmd, buf, sizeof(buf));
11936 }
11937 if (band == band_5) {
11938 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
11939 if (strstr(buf, "[SHORT-GI-") == NULL) {
11940 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
11941 _syscmd(cmd, buf, sizeof(buf));
11942 }
11943 }
11944 }
developera1255e42023-05-13 17:45:02 +080011945 /*wifi_reloadAp(radio_index);
11946 caller "wifi_setRadioOperatingParameters" have done this step.
11947 */
11948 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
11949 if (guard_interval == wifi_guard_interval_400) {
11950 params[0].name = "HT_GI";
11951 params[0].value = "1";
11952 params[1].name = "VHT_SGI";
11953 params[1].value = "1";
11954 wifi_datfileWrite(dat_file, params, 2);
developer72fb0bb2023-01-11 09:46:29 +080011955 strcpy(GI, "0.4");
developera1255e42023-05-13 17:45:02 +080011956 } else {
11957 params[0].name = "HT_GI";
11958 params[0].value = "0";
11959 params[1].name = "VHT_SGI";
11960 params[1].value = "0";
11961 /*should enable FIXED_HE_GI_SUPPORT in driver*/
11962 params[2].name = "FgiFltf";
11963 if (guard_interval == wifi_guard_interval_800) {
11964 params[2].value = "800";
11965 strcpy(GI, "0.8");
11966 } else if (guard_interval == wifi_guard_interval_1600) {
11967 params[2].value = "1600";
11968 strcpy(GI, "1.6");
11969 } else if (guard_interval == wifi_guard_interval_3200) {
11970 params[2].value = "3200";
11971 strcpy(GI, "3.2");
11972 } else if (guard_interval == wifi_guard_interval_auto) {
11973 params[2].value = "0";
11974 strcpy(GI, "auto");
11975 }
11976 wifi_datfileWrite(dat_file, params, 3);
11977 }
developer72fb0bb2023-01-11 09:46:29 +080011978 // Record GI for get GI function
11979 snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
11980 f = fopen(buf, "w");
11981 if (f == NULL)
11982 return RETURN_ERR;
11983 fprintf(f, "%s", GI);
11984 fclose(f);
11985 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11986 return RETURN_OK;
11987}
11988
11989INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
11990{
11991 char buf[32] = {0};
11992 char cmd[64] = {0};
11993
11994 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11995
11996 if (guard_interval == NULL)
11997 return RETURN_ERR;
11998
developera1255e42023-05-13 17:45:02 +080011999 snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
developer72fb0bb2023-01-11 09:46:29 +080012000 _syscmd(cmd, buf, sizeof(buf));
12001
12002 if (strncmp(buf, "0.4", 3) == 0)
12003 *guard_interval = wifi_guard_interval_400;
12004 else if (strncmp(buf, "0.8", 3) == 0)
12005 *guard_interval = wifi_guard_interval_800;
12006 else if (strncmp(buf, "1.6", 3) == 0)
12007 *guard_interval = wifi_guard_interval_1600;
12008 else if (strncmp(buf, "3.2", 3) == 0)
12009 *guard_interval = wifi_guard_interval_3200;
12010 else
12011 *guard_interval = wifi_guard_interval_auto;
12012
12013 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12014 return RETURN_OK;
12015}
12016
12017INT wifi_setBSSColor(INT radio_index, UCHAR color)
12018{
12019 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12020 struct params params = {0};
12021 char config_file[128] = {0};
12022 char bss_color[4] ={0};
12023
developera1255e42023-05-13 17:45:02 +080012024 if (color < 1 || color > 63) {
12025 wifi_dbg_printf("color value is err:%d.\n", color);
12026 return RETURN_ERR;
12027 }
developer72fb0bb2023-01-11 09:46:29 +080012028 params.name = "he_bss_color";
12029 snprintf(bss_color, sizeof(bss_color), "%hhu", color);
12030 params.value = bss_color;
12031 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
12032 wifi_hostapdWrite(config_file, &params, 1);
developera1255e42023-05-13 17:45:02 +080012033 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
12034 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080012035
developer72fb0bb2023-01-11 09:46:29 +080012036 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12037 return RETURN_OK;
12038}
12039
12040INT wifi_getBSSColor(INT radio_index, UCHAR *color)
12041{
12042 char config_file[128] = {0};
12043 char buf[64] = {0};
12044 char temp_output[128] = {'\0'};
12045
12046 wifi_dbg_printf("\nFunc=%s\n", __func__);
12047 if (NULL == color)
12048 return RETURN_ERR;
12049
12050 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
12051 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
12052
12053 if(strlen(buf) > 0) {
12054 snprintf(temp_output, sizeof(temp_output), "%s", buf);
12055 } else {
12056 snprintf(temp_output, sizeof(temp_output), "1"); // default value
12057 }
12058
12059 *color = (UCHAR)strtoul(temp_output, NULL, 10);
12060 wifi_dbg_printf("\noutput_string=%s\n", color);
12061
12062 return RETURN_OK;
12063}
12064
12065/* multi-psk support */
12066INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
12067{
12068 char cmd[256];
12069 char interface_name[16] = {0};
12070
12071 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12072 return RETURN_ERR;
12073
12074 sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
12075 interface_name,
12076 mac[0],
12077 mac[1],
12078 mac[2],
12079 mac[3],
12080 mac[4],
12081 mac[5]
12082 );
12083 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
12084 _syscmd(cmd, key->wifi_keyId, 64);
12085
12086
12087 return RETURN_OK;
12088}
12089
12090INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
12091{
12092 char interface_name[16] = {0};
12093 FILE *fd = NULL;
12094 char fname[100];
12095 char cmd[128] = {0};
12096 char out[64] = {0};
12097 wifi_key_multi_psk_t * key = NULL;
12098 if(keysNumber < 0)
12099 return RETURN_ERR;
12100
12101 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
12102 fd = fopen(fname, "w");
12103 if (!fd) {
12104 return RETURN_ERR;
12105 }
12106 key= (wifi_key_multi_psk_t *) keys;
12107 for(int i=0; i<keysNumber; ++i, key++) {
12108 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
12109 }
12110 fclose(fd);
12111
12112 //reload file
12113 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12114 return RETURN_ERR;
12115 sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
12116 _syscmd(cmd, out, 64);
12117 return RETURN_OK;
12118}
12119
12120INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
12121{
12122 FILE *fd = NULL;
12123 char fname[100];
12124 char * line = NULL;
12125 char * pos = NULL;
12126 size_t len = 0;
12127 ssize_t read = 0;
12128 INT ret = RETURN_OK;
12129 wifi_key_multi_psk_t *keys_it = NULL;
12130
12131 if (keysNumber < 1) {
12132 return RETURN_ERR;
12133 }
12134
12135 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
12136 fd = fopen(fname, "r");
12137 if (!fd) {
12138 return RETURN_ERR;
12139 }
12140
12141 if (keys == NULL) {
12142 ret = RETURN_ERR;
12143 goto close;
12144 }
12145
12146 keys_it = keys;
12147 while ((read = getline(&line, &len, fd)) != -1) {
12148 //Strip trailing new line if present
12149 if (read > 0 && line[read-1] == '\n') {
12150 line[read-1] = '\0';
12151 }
12152
12153 if(strcmp(line,"keyid=")) {
12154 sscanf(line, "keyid=%s", &(keys_it->wifi_keyId));
12155 if (!(pos = index(line, ' '))) {
12156 ret = RETURN_ERR;
12157 goto close;
12158 }
12159 pos++;
12160 //Here should be 00:00:00:00:00:00
12161 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
12162 printf("Not supported MAC: %s\n", pos);
12163 }
12164 if (!(pos = index(pos, ' '))) {
12165 ret = RETURN_ERR;
12166 goto close;
12167 }
12168 pos++;
12169
12170 //The rest is PSK
12171 snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
12172 keys_it++;
12173
12174 if(--keysNumber <= 0)
12175 break;
12176 }
12177 }
12178
12179close:
12180 free(line);
12181 fclose(fd);
12182 return ret;
12183}
12184/* end of multi-psk support */
12185
12186INT wifi_setNeighborReports(UINT apIndex,
12187 UINT numNeighborReports,
12188 wifi_NeighborReport_t *neighborReports)
12189{
12190 char cmd[256] = { 0 };
12191 char hex_bssid[13] = { 0 };
12192 char bssid[18] = { 0 };
12193 char nr[256] = { 0 };
12194 char ssid[256];
12195 char hex_ssid[256];
12196 char interface_name[16] = {0};
12197 INT ret;
12198
12199 /*rmeove all neighbors*/
12200 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
12201 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12202 return RETURN_ERR;
12203 sprintf(cmd, "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",interface_name,interface_name);
12204 system(cmd);
12205
12206 for(unsigned int i = 0; i < numNeighborReports; i++)
12207 {
12208 memset(ssid, 0, sizeof(ssid));
12209 ret = wifi_getSSIDName(apIndex, ssid);
12210 if (ret != RETURN_OK)
12211 return RETURN_ERR;
12212
12213 memset(hex_ssid, 0, sizeof(hex_ssid));
12214 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
12215 sprintf(hex_ssid + k,"%02x", ssid[j]);
12216
12217 snprintf(hex_bssid, sizeof(hex_bssid),
12218 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
12219 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
12220 snprintf(bssid, sizeof(bssid),
12221 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
12222 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
12223
12224 snprintf(nr, sizeof(nr),
12225 "%s" // bssid
12226 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
12227 "%02hhx" // operclass
12228 "%02hhx" // channel
12229 "%02hhx", // phy_mode
12230 hex_bssid,
12231 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
12232 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
12233 neighborReports[i].opClass,
12234 neighborReports[i].channel,
12235 neighborReports[i].phyTable);
12236
12237 snprintf(cmd, sizeof(cmd),
12238 "hostapd_cli set_neighbor "
12239 "%s " // bssid
12240 "ssid=%s " // ssid
12241 "nr=%s " // nr
12242 "-i %s",
12243 bssid,hex_ssid,nr, interface_name);
12244
12245 if (WEXITSTATUS(system(cmd)) != 0)
12246 {
12247 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
12248 }
12249 }
12250
12251 return RETURN_OK;
12252}
12253
12254INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
12255{
12256 return RETURN_OK;
12257}
12258
12259#ifdef _WIFI_HAL_TEST_
12260int main(int argc,char **argv)
12261{
12262 int index;
12263 INT ret=0;
12264 char buf[1024]="";
12265
12266 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12267 if(argc<3)
12268 {
12269 if(argc==2)
12270 {
12271 if(!strcmp(argv[1], "init"))
12272 return wifi_init();
12273 if(!strcmp(argv[1], "reset"))
12274 return wifi_reset();
12275 if(!strcmp(argv[1], "wifi_getHalVersion"))
12276 {
12277 char buffer[64];
12278 if(wifi_getHalVersion(buffer)==RETURN_OK)
12279 printf("Version: %s\n", buffer);
12280 else
12281 printf("Error in wifi_getHalVersion\n");
12282 return RETURN_OK;
12283 }
12284 }
12285 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
12286 exit(-1);
12287 }
12288
12289 index = atoi(argv[2]);
12290 if(strstr(argv[1], "wifi_getApName")!=NULL)
12291 {
12292 wifi_getApName(index,buf);
12293 printf("Ap name is %s \n",buf);
12294 return 0;
12295 }
developer0f10c772023-05-16 21:43:39 +080012296 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
12297 {
12298 int mode = 0;
12299
12300 wifi_getRadioMode(index, buf, &mode);
12301 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
12302 return 0;
12303 }
developer72fb0bb2023-01-11 09:46:29 +080012304 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
12305 {
12306 BOOL b = FALSE;
12307 BOOL *output_bool = &b;
12308 wifi_getRadioAutoChannelEnable(index,output_bool);
12309 printf("Channel enabled = %d \n",b);
12310 return 0;
12311 }
12312 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
12313 {
12314 wifi_getApWpaEncryptionMode(index,buf);
12315 printf("encryption enabled = %s\n",buf);
12316 return 0;
12317 }
12318 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
12319 {
12320 BOOL b = FALSE;
12321 BOOL *output_bool = &b;
12322 wifi_getApSsidAdvertisementEnable(index,output_bool);
12323 printf("advertisment enabled = %d\n",b);
12324 return 0;
12325 }
12326 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
12327 {
12328 if(argc <= 3 )
12329 {
12330 printf("Insufficient arguments \n");
12331 exit(-1);
12332 }
12333
12334 char sta[20] = {'\0'};
12335 ULLONG handle= 0;
12336 strcpy(sta,argv[3]);
12337 mac_address_t st;
12338 mac_addr_aton(st,sta);
12339
12340 wifi_associated_dev_tid_stats_t tid_stats;
12341 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
12342 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
12343 printf(" tid=%d \t ac=%d \t num_msdus=%lld \n" ,tid_stats.tid_array[tid_index].tid,tid_stats.tid_array[tid_index].ac,tid_stats.tid_array[tid_index].num_msdus);
12344 }
12345
12346 if(strstr(argv[1], "getApEnable")!=NULL) {
12347 BOOL enable;
12348 ret=wifi_getApEnable(index, &enable);
12349 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
12350 }
12351 else if(strstr(argv[1], "setApEnable")!=NULL) {
12352 BOOL enable = atoi(argv[3]);
12353 ret=wifi_setApEnable(index, enable);
12354 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
12355 }
12356 else if(strstr(argv[1], "getApStatus")!=NULL) {
developer69b61b02023-03-07 17:17:44 +080012357 char status[64];
developer72fb0bb2023-01-11 09:46:29 +080012358 ret=wifi_getApStatus(index, status);
12359 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
12360 }
12361 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
12362 {
12363 wifi_getSSIDNameStatus(index,buf);
12364 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
12365 return 0;
12366 }
12367 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
12368 wifi_ssidTrafficStats2_t stats={0};
12369 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
12370 printf("%s %d: returns %d\n", argv[1], index, ret);
12371 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
12372 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
12373 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
12374 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
12375 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
12376 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
12377 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
12378 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
12379 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
12380 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
12381 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
12382 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
12383 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
12384 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
12385 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
12386 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
12387 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
12388 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
12389 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
12390 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
12391 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
12392 }
12393 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
12394 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
12395 UINT array_size=0;
12396 UINT i=0;
12397 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
12398 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080012399 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080012400 printf(" neighbor %d:\n", i);
12401 printf(" ap_SSID =%s\n", pt->ap_SSID);
12402 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
12403 printf(" ap_Mode =%s\n", pt->ap_Mode);
12404 printf(" ap_Channel =%d\n", pt->ap_Channel);
12405 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
12406 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
12407 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
12408 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
12409 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
12410 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
12411 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
12412 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
12413 printf(" ap_Noise =%d\n", pt->ap_Noise);
12414 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
12415 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
12416 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
developer69b61b02023-03-07 17:17:44 +080012417 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
developer72fb0bb2023-01-11 09:46:29 +080012418 }
12419 if(neighbor_ap_array)
12420 free(neighbor_ap_array); //make sure to free the list
12421 }
12422 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
12423 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
12424 UINT array_size=0;
12425 UINT i=0;
12426 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
12427 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080012428 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080012429 printf(" associated_dev %d:\n", i);
12430 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
12431 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
12432 printf(" cli_SNR =%d\n", pt->cli_SNR);
12433 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
12434 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
12435 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
12436 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
12437 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
12438 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
12439 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
12440 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
12441 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
12442 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
12443 }
12444 if(associated_dev_array)
12445 free(associated_dev_array); //make sure to free the list
12446 }
12447
12448 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
12449 {
12450#define MAX_ARRAY_SIZE 64
12451 int i, array_size;
12452 char *p, *ch_str;
12453 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
12454
12455 if(argc != 5)
12456 {
12457 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
12458 exit(-1);
12459 }
12460 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
12461
12462 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
12463 {
12464 strtok_r(ch_str, ",", &p);
12465 input_output_channelStats_array[i].ch_number = atoi(ch_str);
12466 }
12467 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
12468 if(!array_size)
12469 array_size=1;//Need to print current channel statistics
12470 for(i=0; i<array_size; i++)
12471 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
12472 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
12473 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
12474 input_output_channelStats_array[i].ch_number,\
12475 input_output_channelStats_array[i].ch_noise,\
12476 input_output_channelStats_array[i].ch_utilization_busy_rx,\
12477 input_output_channelStats_array[i].ch_utilization_busy_tx,\
12478 input_output_channelStats_array[i].ch_utilization_busy,\
12479 input_output_channelStats_array[i].ch_utilization_busy_ext,\
12480 input_output_channelStats_array[i].ch_utilization_total);
12481 }
12482
12483 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
12484 {
12485 if(argc <= 3 )
12486 {
12487 printf("Insufficient arguments \n");
12488 exit(-1);
12489 }
12490 char mac_addr[20] = {'\0'};
12491 wifi_device_t output_struct;
12492 int dev_index = atoi(argv[3]);
12493
12494 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
12495 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
12496 printf("wifi_devMacAddress=%s \t wifi_devAssociatedDeviceAuthentiationState=%d \t, wifi_devSignalStrength=%d \t,wifi_devTxRate=%d \t, wifi_devRxRate =%d \t\n ", mac_addr,output_struct.wifi_devAssociatedDeviceAuthentiationState,output_struct.wifi_devSignalStrength,output_struct.wifi_devTxRate,output_struct.wifi_devRxRate);
12497 }
12498
12499 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
12500 {
12501 if (argc <= 3)
12502 {
12503 printf("Insufficient arguments\n");
12504 exit(-1);
12505 }
12506 char args[256];
12507 wifi_NeighborReport_t *neighborReports;
12508
12509 neighborReports = calloc(argc - 2, sizeof(neighborReports));
12510 if (!neighborReports)
12511 {
12512 printf("Failed to allocate memory");
12513 exit(-1);
12514 }
12515
12516 for (int i = 3; i < argc; ++i)
12517 {
12518 char *val;
12519 int j = 0;
12520 memset(args, 0, sizeof(args));
12521 strncpy(args, argv[i], sizeof(args));
12522 val = strtok(args, ";");
12523 while (val != NULL)
12524 {
12525 if (j == 0)
12526 {
12527 mac_addr_aton(neighborReports[i - 3].bssid, val);
12528 } else if (j == 1)
12529 {
12530 neighborReports[i - 3].info = strtol(val, NULL, 16);
12531 } else if (j == 2)
12532 {
12533 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
12534 } else if (j == 3)
12535 {
12536 neighborReports[i - 3].channel = strtol(val, NULL, 16);
12537 } else if (j == 4)
12538 {
12539 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
12540 } else {
12541 printf("Insufficient arguments]n\n");
12542 exit(-1);
12543 }
12544 val = strtok(NULL, ";");
12545 j++;
12546 }
12547 }
12548
12549 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
12550 if (ret != RETURN_OK)
12551 {
12552 printf("wifi_setNeighborReports ret = %d", ret);
12553 exit(-1);
12554 }
12555 }
12556 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
12557 {
12558 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
12559 printf("%s.\n", buf);
12560 else
12561 printf("Error returned\n");
12562 }
12563 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
12564 {
12565 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
12566 printf("%s.\n", buf);
12567 else
12568 printf("Error returned\n");
12569 }
12570 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
12571 {
12572 if (argc <= 2)
12573 {
12574 printf("Insufficient arguments\n");
12575 exit(-1);
12576 }
12577 char buf[64]= {'\0'};
12578 wifi_getRadioOperatingChannelBandwidth(index,buf);
12579 printf("Current bandwidth is %s \n",buf);
12580 return 0;
12581 }
12582 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
12583 {
12584 if (argc <= 5)
12585 {
12586 printf("Insufficient arguments\n");
12587 exit(-1);
12588 }
12589 UINT channel = atoi(argv[3]);
12590 UINT width = atoi(argv[4]);
12591 UINT beacon = atoi(argv[5]);
12592 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
12593 printf("Result = %d", ret);
12594 }
12595
12596 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12597 return 0;
12598}
12599
12600#endif
12601
12602#ifdef WIFI_HAL_VERSION_3
12603
12604INT BitMapToTransmitRates(UINT bitMap, char *BasicRate)
12605{
12606 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12607 if (bitMap & WIFI_BITRATE_1MBPS)
12608 strcat(BasicRate, "1,");
12609 if (bitMap & WIFI_BITRATE_2MBPS)
12610 strcat(BasicRate, "2,");
12611 if (bitMap & WIFI_BITRATE_5_5MBPS)
12612 strcat(BasicRate, "5.5,");
12613 if (bitMap & WIFI_BITRATE_6MBPS)
12614 strcat(BasicRate, "6,");
12615 if (bitMap & WIFI_BITRATE_9MBPS)
12616 strcat(BasicRate, "9,");
12617 if (bitMap & WIFI_BITRATE_11MBPS)
12618 strcat(BasicRate, "11,");
12619 if (bitMap & WIFI_BITRATE_12MBPS)
12620 strcat(BasicRate, "12,");
12621 if (bitMap & WIFI_BITRATE_18MBPS)
12622 strcat(BasicRate, "18,");
12623 if (bitMap & WIFI_BITRATE_24MBPS)
12624 strcat(BasicRate, "24,");
12625 if (bitMap & WIFI_BITRATE_36MBPS)
12626 strcat(BasicRate, "36,");
12627 if (bitMap & WIFI_BITRATE_48MBPS)
12628 strcat(BasicRate, "48,");
12629 if (bitMap & WIFI_BITRATE_54MBPS)
12630 strcat(BasicRate, "54,");
12631 if (strlen(BasicRate) != 0) // remove last comma
12632 BasicRate[strlen(BasicRate) - 1] = '\0';
12633 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12634 return RETURN_OK;
12635}
12636
12637INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
12638{
12639 UINT BitMap = 0;
12640 char *rate;
12641
12642 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12643 rate = strtok(BasicRatesList, ",");
12644 while(rate != NULL)
12645 {
12646 if (strcmp(rate, "1") == 0)
12647 BitMap |= WIFI_BITRATE_1MBPS;
12648 else if (strcmp(rate, "2") == 0)
12649 BitMap |= WIFI_BITRATE_2MBPS;
12650 else if (strcmp(rate, "5.5") == 0)
12651 BitMap |= WIFI_BITRATE_5_5MBPS;
12652 else if (strcmp(rate, "6") == 0)
12653 BitMap |= WIFI_BITRATE_6MBPS;
12654 else if (strcmp(rate, "9") == 0)
12655 BitMap |= WIFI_BITRATE_9MBPS;
12656 else if (strcmp(rate, "11") == 0)
12657 BitMap |= WIFI_BITRATE_11MBPS;
12658 else if (strcmp(rate, "12") == 0)
12659 BitMap |= WIFI_BITRATE_12MBPS;
12660 else if (strcmp(rate, "18") == 0)
12661 BitMap |= WIFI_BITRATE_18MBPS;
12662 else if (strcmp(rate, "24") == 0)
12663 BitMap |= WIFI_BITRATE_24MBPS;
12664 else if (strcmp(rate, "36") == 0)
12665 BitMap |= WIFI_BITRATE_36MBPS;
12666 else if (strcmp(rate, "48") == 0)
12667 BitMap |= WIFI_BITRATE_48MBPS;
12668 else if (strcmp(rate, "54") == 0)
12669 BitMap |= WIFI_BITRATE_54MBPS;
12670 rate = strtok(NULL, ",");
12671 }
12672 *basicRateBitMap = BitMap;
12673 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12674 return RETURN_OK;
12675}
12676
12677// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
12678INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
12679{
12680 char buf[128] = {0};
12681 char cmd[128] = {0};
12682 char config_file[64] = {0};
12683 int bandwidth;
12684 int set_mode = 0;
12685 wifi_radio_operationParam_t current_param;
12686
12687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12688
12689 multiple_set = TRUE;
12690 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
12691 fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__);
12692 return RETURN_ERR;
12693 }
12694 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
12695 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
12696 fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__);
12697 return RETURN_ERR;
12698 }
12699 }
12700
12701 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
12702 bandwidth = 20;
12703 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
12704 bandwidth = 40;
12705 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
12706 bandwidth = 80;
12707 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
12708 bandwidth = 160;
12709 if (operationParam->autoChannelEnabled){
12710 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
12711 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
12712 return RETURN_ERR;
12713 }
developer69b61b02023-03-07 17:17:44 +080012714 }else{
developer72fb0bb2023-01-11 09:46:29 +080012715 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
12716 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
12717 return RETURN_ERR;
12718 }
12719 }
12720
12721 if (current_param.variant != operationParam->variant) {
12722 // Two different definition bit map, so need to check every bit.
12723 if (operationParam->variant & WIFI_80211_VARIANT_A)
12724 set_mode |= WIFI_MODE_A;
12725 if (operationParam->variant & WIFI_80211_VARIANT_B)
12726 set_mode |= WIFI_MODE_B;
12727 if (operationParam->variant & WIFI_80211_VARIANT_G)
12728 set_mode |= WIFI_MODE_G;
12729 if (operationParam->variant & WIFI_80211_VARIANT_N)
12730 set_mode |= WIFI_MODE_N;
12731 if (operationParam->variant & WIFI_80211_VARIANT_AC)
12732 set_mode |= WIFI_MODE_AC;
12733 if (operationParam->variant & WIFI_80211_VARIANT_AX)
12734 set_mode |= WIFI_MODE_AX;
12735 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
12736 memset(buf, 0, sizeof(buf));
developer0f10c772023-05-16 21:43:39 +080012737 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080012738 fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__);
12739 return RETURN_ERR;
12740 }
12741 }
12742 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
12743 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
12744 fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__);
12745 return RETURN_ERR;
12746 }
12747 }
12748 if (current_param.beaconInterval != operationParam->beaconInterval) {
12749 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
12750 fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__);
12751 return RETURN_ERR;
12752 }
12753 }
12754 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
12755 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf);
12756 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
12757 fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__);
12758 return RETURN_ERR;
12759 }
12760 }
12761 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
12762 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
12763 fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__);
12764 return RETURN_ERR;
12765 }
12766 }
12767 if (current_param.guardInterval != operationParam->guardInterval) {
12768 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
12769 fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__);
12770 return RETURN_ERR;
12771 }
12772 }
12773 if (current_param.transmitPower != operationParam->transmitPower) {
12774 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
12775 fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__);
12776 return RETURN_ERR;
12777 }
12778 }
12779 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
12780 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
12781 fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__);
12782 return RETURN_ERR;
12783 }
12784 }
12785 if (current_param.obssCoex != operationParam->obssCoex) {
12786 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
12787 fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__);
12788 return RETURN_ERR;
12789 }
12790 }
12791 if (current_param.stbcEnable != operationParam->stbcEnable) {
12792 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
12793 fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__);
12794 return RETURN_ERR;
12795 }
12796 }
12797 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
12798 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
12799 fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__);
12800 return RETURN_ERR;
12801 }
12802 }
12803
12804 // if enable is true, then restart the radio
12805 wifi_setRadioEnable(index, FALSE);
12806 if (operationParam->enable == TRUE)
12807 wifi_setRadioEnable(index, TRUE);
12808 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12809
12810 return RETURN_OK;
12811}
12812
12813INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
12814{
12815 char band[64] = {0};
12816 char buf[256] = {0};
12817 char config_file[64] = {0};
12818 char cmd[128] = {0};
12819 int ret = RETURN_ERR;
12820 int mode = 0;
12821 ULONG channel = 0;
12822 BOOL enabled = FALSE;
12823
12824 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12825 printf("Entering %s index = %d\n", __func__, (int)index);
12826
12827 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
12828 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
12829 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
12830 {
12831 fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__);
12832 return RETURN_ERR;
12833 }
12834 operationParam->enable = enabled;
12835
12836 memset(band, 0, sizeof(band));
12837 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
12838 {
12839 fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__);
12840 return RETURN_ERR;
12841 }
12842
12843 if (!strcmp(band, "2.4GHz"))
12844 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
12845 else if (!strcmp(band, "5GHz"))
12846 operationParam->band = WIFI_FREQUENCY_5_BAND;
12847 else if (!strcmp(band, "6GHz"))
12848 operationParam->band = WIFI_FREQUENCY_6_BAND;
12849 else
12850 {
12851 fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
12852 band);
12853 }
12854
12855 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
12856 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
12857 operationParam->channel = 0;
12858 operationParam->autoChannelEnabled = TRUE;
12859 } else {
12860 operationParam->channel = strtol(buf, NULL, 10);
12861 operationParam->autoChannelEnabled = FALSE;
12862 }
12863
12864 memset(buf, 0, sizeof(buf));
12865 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
12866 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__);
12867 return RETURN_ERR;
12868 }
12869 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
12870 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
12871 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
12872 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
12873 else
12874 {
12875 fprintf(stderr, "Unknown channel bandwidth: %s\n", buf);
12876 return false;
12877 }
12878
12879 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
12880 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
12881 return RETURN_ERR;
12882 }
12883 // Two different definition bit map, so need to check every bit.
12884 if (mode & WIFI_MODE_A)
12885 operationParam->variant |= WIFI_80211_VARIANT_A;
12886 if (mode & WIFI_MODE_B)
12887 operationParam->variant |= WIFI_80211_VARIANT_B;
12888 if (mode & WIFI_MODE_G)
12889 operationParam->variant |= WIFI_80211_VARIANT_G;
12890 if (mode & WIFI_MODE_N)
12891 operationParam->variant |= WIFI_80211_VARIANT_N;
12892 if (mode & WIFI_MODE_AC)
12893 operationParam->variant |= WIFI_80211_VARIANT_AC;
12894 if (mode & WIFI_MODE_AX)
12895 operationParam->variant |= WIFI_80211_VARIANT_AX;
12896 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
12897 fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__);
12898 return RETURN_ERR;
12899 }
12900 if (wifi_getApDTIMInterval(index, &operationParam->dtimPeriod) != RETURN_OK) {
12901 fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__);
12902 return RETURN_ERR;
12903 }
12904 if (wifi_getRadioBeaconPeriod(index, &operationParam->dtimPeriod) != RETURN_OK) {
12905 fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__);
12906 return RETURN_ERR;
12907 }
12908
12909 memset(buf, 0, sizeof(buf));
12910 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
12911 fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__);
12912 return RETURN_ERR;
12913 }
12914 TransmitRatesToBitMap(buf, &operationParam->basicDataTransmitRates);
12915
12916 memset(buf, 0, sizeof(buf));
12917 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
12918 fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__);
12919 return RETURN_ERR;
12920 }
12921 TransmitRatesToBitMap(buf, &operationParam->operationalDataTransmitRates);
12922
12923 memset(buf, 0, sizeof(buf));
12924 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
12925 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
12926
12927 if (wifi_getGuardInterval(index, &operationParam->guardInterval) != RETURN_OK) {
12928 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
12929 return RETURN_ERR;
12930 }
developera1255e42023-05-13 17:45:02 +080012931 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&operationParam->transmitPower) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080012932 fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__);
12933 return RETURN_ERR;
12934 }
12935
12936 memset(buf, 0, sizeof(buf));
12937 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
12938 if (strcmp(buf, "-1") == 0) {
12939 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
12940 operationParam->ctsProtection = FALSE;
12941 } else {
12942 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
12943 operationParam->ctsProtection = TRUE;
12944 }
12945
12946 memset(buf, 0, sizeof(buf));
12947 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
12948 if (strcmp(buf, "0") == 0)
12949 operationParam->obssCoex = FALSE;
12950 else
12951 operationParam->obssCoex = TRUE;
12952
12953 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
12954 _syscmd(cmd, buf, sizeof(buf));
12955 if (strlen(buf) != 0)
12956 operationParam->stbcEnable = TRUE;
12957 else
12958 operationParam->stbcEnable = FALSE;
12959
12960 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
12961 fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__);
12962 return RETURN_ERR;
12963 }
12964
12965 // Below value is hardcoded
12966
12967 operationParam->numSecondaryChannels = 0;
12968 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
12969 operationParam->channelSecondary[i] = 0;
12970 }
12971 operationParam->csa_beacon_count = 15;
12972 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
12973
12974 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12975 return RETURN_OK;
12976}
12977
12978static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
12979{
12980 int max_radio_num = 0;
12981
12982 wifi_getMaxRadioNumber(&max_radio_num);
12983 if (radioIndex >= max_radio_num) {
12984 fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex);
12985 return RETURN_ERR;
12986 }
12987
12988 return (arrayIndex * max_radio_num) + radioIndex;
12989}
12990
developer96b38512023-02-22 11:17:45 +080012991static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
12992{
12993 int max_radio_num = 0;
12994
12995 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
12996 return -1;
12997
12998 wifi_getMaxRadioNumber(&max_radio_num);
12999
13000 (*radioIndex) = vapIndex % max_radio_num;
13001 (*arrayIndex) = vapIndex / max_radio_num;
13002
13003 return 0;
13004}
13005
13006
developer72fb0bb2023-01-11 09:46:29 +080013007wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
13008 if (strncmp(beaconRate, "1Mbps", 5) == 0)
13009 return WIFI_BITRATE_1MBPS;
13010 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
13011 return WIFI_BITRATE_2MBPS;
13012 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
13013 return WIFI_BITRATE_5_5MBPS;
13014 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
13015 return WIFI_BITRATE_6MBPS;
13016 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
13017 return WIFI_BITRATE_9MBPS;
13018 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
13019 return WIFI_BITRATE_11MBPS;
13020 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
13021 return WIFI_BITRATE_12MBPS;
13022 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
13023 return WIFI_BITRATE_18MBPS;
13024 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
13025 return WIFI_BITRATE_24MBPS;
13026 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
13027 return WIFI_BITRATE_36MBPS;
13028 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
13029 return WIFI_BITRATE_48MBPS;
13030 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
13031 return WIFI_BITRATE_54MBPS;
13032 return WIFI_BITRATE_DEFAULT;
13033}
13034
13035INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str)
13036{
13037 if (beacon == WIFI_BITRATE_1MBPS)
13038 strcpy(beacon_str, "1Mbps");
13039 else if (beacon == WIFI_BITRATE_2MBPS)
13040 strcpy(beacon_str, "2Mbps");
13041 else if (beacon == WIFI_BITRATE_5_5MBPS)
13042 strcpy(beacon_str, "5.5Mbps");
13043 else if (beacon == WIFI_BITRATE_6MBPS)
13044 strcpy(beacon_str, "6Mbps");
13045 else if (beacon == WIFI_BITRATE_9MBPS)
13046 strcpy(beacon_str, "9Mbps");
13047 else if (beacon == WIFI_BITRATE_11MBPS)
13048 strcpy(beacon_str, "11Mbps");
13049 else if (beacon == WIFI_BITRATE_12MBPS)
13050 strcpy(beacon_str, "12Mbps");
13051 else if (beacon == WIFI_BITRATE_18MBPS)
13052 strcpy(beacon_str, "18Mbps");
13053 else if (beacon == WIFI_BITRATE_24MBPS)
13054 strcpy(beacon_str, "24Mbps");
13055 else if (beacon == WIFI_BITRATE_36MBPS)
13056 strcpy(beacon_str, "36Mbps");
13057 else if (beacon == WIFI_BITRATE_48MBPS)
13058 strcpy(beacon_str, "48Mbps");
13059 else if (beacon == WIFI_BITRATE_54MBPS)
13060 strcpy(beacon_str, "54Mbps");
13061 return RETURN_OK;
13062}
13063
13064INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
13065{
13066 INT mode = 0;
13067 INT ret = -1;
13068 INT output = 0;
13069 int i = 0;
13070 int vap_index = 0;
13071 BOOL enabled = FALSE;
13072 char buf[256] = {0};
13073 wifi_vap_security_t security = {0};
13074 map->num_vaps = 5; // Hardcoded
13075
13076 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13077 printf("Entering %s index = %d\n", __func__, (int)index);
13078
13079 for (i = 0; i < 5; i++)
13080 {
13081 map->vap_array[i].radio_index = index;
13082
13083 vap_index = array_index_to_vap_index(index, i);
13084 if (vap_index < 0)
13085 return RETURN_ERR;
13086
13087 strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME);
13088
13089 map->vap_array[i].vap_index = vap_index;
13090
13091 memset(buf, 0, sizeof(buf));
13092 ret = wifi_getApName(vap_index, buf);
13093 if (ret != RETURN_OK) {
13094 printf("%s: wifi_getApName return error\n", __func__);
13095 return RETURN_ERR;
13096 }
13097 snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
13098
13099 memset(buf, 0, sizeof(buf));
13100 ret = wifi_getSSIDName(vap_index, buf);
13101 if (ret != RETURN_OK) {
13102 printf("%s: wifi_getSSIDName return error\n", __func__);
13103 return RETURN_ERR;
13104 }
13105 snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
13106
13107 ret = wifi_getSSIDEnable(vap_index, &enabled);
13108 if (ret != RETURN_OK) {
13109 printf("%s: wifi_getSSIDEnable return error\n", __func__);
13110 return RETURN_ERR;
13111 }
13112 map->vap_array[i].u.bss_info.enabled = enabled;
13113
13114 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
13115 if (ret != RETURN_OK) {
13116 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
13117 return RETURN_ERR;
13118 }
13119 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080013120
developer72fb0bb2023-01-11 09:46:29 +080013121 ret = wifi_getApIsolationEnable(vap_index, &enabled);
13122 if (ret != RETURN_OK) {
13123 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
13124 return RETURN_ERR;
13125 }
13126 map->vap_array[i].u.bss_info.isolation = enabled;
13127
13128 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
13129 if (ret != RETURN_OK) {
13130 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
13131 return RETURN_ERR;
13132 }
13133 map->vap_array[i].u.bss_info.bssMaxSta = output;
13134
13135 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
13136 if (ret != RETURN_OK) {
13137 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
13138 return RETURN_ERR;
13139 }
13140 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
13141
13142 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
13143 if (ret != RETURN_OK) {
13144 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
13145 return RETURN_ERR;
13146 }
13147 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
13148
13149 ret = wifi_getApSecurity(vap_index, &security);
13150 if (ret != RETURN_OK) {
13151 printf("%s: wifi_getApSecurity return error\n", __func__);
13152 return RETURN_ERR;
13153 }
13154 map->vap_array[i].u.bss_info.security = security;
13155
13156 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
13157 if (ret != RETURN_OK) {
13158 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
13159 return RETURN_ERR;
13160 }
developer69b61b02023-03-07 17:17:44 +080013161 if (mode == 0)
developer72fb0bb2023-01-11 09:46:29 +080013162 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
developer69b61b02023-03-07 17:17:44 +080013163 else
developer72fb0bb2023-01-11 09:46:29 +080013164 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
developer69b61b02023-03-07 17:17:44 +080013165 if (mode == 1)
developer72fb0bb2023-01-11 09:46:29 +080013166 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
developer69b61b02023-03-07 17:17:44 +080013167 else if (mode == 2)
developer72fb0bb2023-01-11 09:46:29 +080013168 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
13169
13170 ret = wifi_getApWmmEnable(vap_index, &enabled);
13171 if (ret != RETURN_OK) {
13172 printf("%s: wifi_getApWmmEnable return error\n", __func__);
13173 return RETURN_ERR;
13174 }
13175 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
13176
13177 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
13178 if (ret != RETURN_OK) {
13179 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
13180 return RETURN_ERR;
13181 }
13182 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
13183
13184 memset(buf, 0, sizeof(buf));
13185 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
13186 if (ret != RETURN_OK) {
13187 printf("%s: wifi_getApBeaconRate return error\n", __func__);
13188 return RETURN_ERR;
13189 }
13190 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
13191
13192 memset(buf, 0, sizeof(buf));
13193 ret = wifi_getBaseBSSID(vap_index, buf);
13194 if (ret != RETURN_OK) {
13195 printf("%s: wifi_getBaseBSSID return error\n", __func__);
13196 return RETURN_ERR;
13197 }
13198 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
13199 &map->vap_array[i].u.bss_info.bssid[0],
13200 &map->vap_array[i].u.bss_info.bssid[1],
13201 &map->vap_array[i].u.bss_info.bssid[2],
13202 &map->vap_array[i].u.bss_info.bssid[3],
13203 &map->vap_array[i].u.bss_info.bssid[4],
13204 &map->vap_array[i].u.bss_info.bssid[5]);
13205 // fprintf(stderr, "%s index %d: mac: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", __func__, vap_index, map->vap_array[i].u.bss_info.bssid[0], map->vap_array[i].u.bss_info.bssid[1], map->vap_array[i].u.bss_info.bssid[2], map->vap_array[i].u.bss_info.bssid[3], map->vap_array[i].u.bss_info.bssid[4], map->vap_array[i].u.bss_info.bssid[5]);
13206
13207 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
13208 if (ret != RETURN_OK) {
13209 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
13210 return RETURN_ERR;
13211 }
13212 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
13213
13214 // TODO: wps, noack
13215 }
13216 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13217 return RETURN_OK;
13218}
13219
13220void checkVapStatus(int apIndex, bool *enable)
13221{
13222 char if_name[16] = {0};
13223 char cmd[128] = {0};
13224 char buf[128] = {0};
13225
13226 *enable = FALSE;
13227 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
13228 return;
13229
13230 snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
13231 _syscmd(cmd, buf, sizeof(buf));
13232 if (strlen(buf) > 0)
13233 *enable = TRUE;
13234 return;
13235}
13236
13237static int prepareInterface(UINT apIndex, char *new_interface)
13238{
13239 char cur_interface[16] = {0};
13240 char config_file[128] = {0};
developer8a3bbbf2023-03-15 17:47:23 +080013241 char cmd[MAX_CMD_SIZE] = {0};
13242 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013243 int max_radio_num = 0;
13244 int radioIndex = -1;
13245 int phyIndex = -1;
developer8a3bbbf2023-03-15 17:47:23 +080013246 struct params params;
developer72fb0bb2023-01-11 09:46:29 +080013247
13248 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
13249 wifi_hostapdRead(config_file, "interface", cur_interface, sizeof(cur_interface));
13250
13251 if (strncmp(cur_interface, new_interface, sizeof(cur_interface)) != 0) {
developer8a3bbbf2023-03-15 17:47:23 +080013252 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +080013253 radioIndex = apIndex % max_radio_num;
13254 phyIndex = radio_index_to_phy(radioIndex);
13255 // disable and del old interface, then add new interface
13256 wifi_setApEnable(apIndex, FALSE);
developer8a3bbbf2023-03-15 17:47:23 +080013257
13258 params.name = "interface";
13259 params.value = new_interface;
13260 wifi_hostapdWrite(config_file, &params, 1);
13261
13262 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyIndex, config_file);
13263 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080013264 }
developer8a3bbbf2023-03-15 17:47:23 +080013265
developer72fb0bb2023-01-11 09:46:29 +080013266 // update the vap status file
13267 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=1' %s", cur_interface, new_interface, VAP_STATUS_FILE);
13268 _syscmd(cmd, buf, sizeof(buf));
13269 return RETURN_OK;
13270}
13271
13272INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
13273{
13274 char interface_name[16] = {0};
13275 unsigned int i;
13276 wifi_vap_info_t *vap_info = NULL;
13277 int acl_mode;
13278 int ret = 0;
13279 char *sec_str = NULL;
13280 char buf[256] = {0};
13281 char cmd[128] = {0};
13282 char config_file[64] = {0};
13283 char bssid[32] = {0};
13284 char psk_file[64] = {0};
13285 bool enable = FALSE;
13286
13287 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13288 printf("Entering %s index = %d\n", __func__, (int)index);
13289 for (i = 0; i < map->num_vaps; i++)
13290 {
13291 multiple_set = TRUE;
13292 vap_info = &map->vap_array[i];
13293
13294 // Check vap status file to enable multiple ap if the system boot.
13295 checkVapStatus(vap_info->vap_index, &enable);
13296 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
13297 continue;
13298
13299 fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
13300
13301 if (wifi_getApEnable(vap_info->vap_index, &enable) != RETURN_OK)
13302 enable = FALSE;
13303
13304 // multi-ap first up need to copy current radio config
13305 if (vap_info->radio_index != vap_info->vap_index && enable == FALSE) {
13306 snprintf(cmd, sizeof(cmd), "cp %s%d.conf %s%d.conf", CONFIG_PREFIX, vap_info->radio_index, CONFIG_PREFIX, vap_info->vap_index);
13307 _syscmd(cmd, buf, sizeof(buf));
13308 if (strlen(vap_info->vap_name) == 0) // default name of the interface is wifiX
13309 snprintf(vap_info->vap_name, 16, "wifi%d", vap_info->vap_index);
13310 } else {
13311 // Check whether the interface name is valid or this ap change it.
13312 int apIndex = -1;
13313 wifi_getApIndexFromName(vap_info->vap_name, &apIndex);
13314 if (apIndex != -1 && apIndex != vap_info->vap_index)
13315 continue;
13316 prepareInterface(vap_info->vap_index, vap_info->vap_name);
13317 }
13318
13319 struct params params[3];
13320 params[0].name = "interface";
13321 params[0].value = vap_info->vap_name;
13322 mac_addr_ntoa(bssid, vap_info->u.bss_info.bssid);
13323 params[1].name = "bssid";
13324 params[1].value = bssid;
13325 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
13326 params[2].name = "wpa_psk_file";
13327 params[2].value = psk_file;
13328
13329 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
13330 wifi_hostapdWrite(config_file, params, 3);
13331
13332 snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
13333 _syscmd(cmd, buf, sizeof(buf));
13334
13335 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
13336 if (ret != RETURN_OK) {
13337 fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__);
13338 return RETURN_ERR;
13339 }
13340
13341 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
13342 if (ret != RETURN_OK) {
13343 fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__);
13344 return RETURN_ERR;
13345 }
13346
13347 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
13348 if (ret != RETURN_OK) {
13349 fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__);
13350 return RETURN_ERR;
13351 }
13352
13353 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
13354 if (ret != RETURN_OK) {
13355 fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__);
13356 return RETURN_ERR;
13357 }
13358
13359 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
13360 if (ret != RETURN_OK) {
13361 fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__);
13362 return RETURN_ERR;
13363 }
13364
13365 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
13366 if (ret != RETURN_OK) {
13367 fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__);
13368 return RETURN_ERR;
13369 }
13370
13371 if (vap_info->u.bss_info.mac_filter_enable == false){
13372 acl_mode = 0;
13373 }else {
13374 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
13375 acl_mode = 2;
13376 snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
13377 _syscmd(cmd, buf, sizeof(buf));
13378 }else{
13379 acl_mode = 1;
13380 }
13381 }
13382
13383 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
13384 if (ret != RETURN_OK) {
13385 fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__);
13386 return RETURN_ERR;
13387 }
13388
13389 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
13390 if (ret != RETURN_OK) {
13391 fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__);
13392 return RETURN_ERR;
13393 }
13394
developer0f10c772023-05-16 21:43:39 +080013395 memset(buf, 0, sizeof(buf));
13396 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf);
13397 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
13398 if (ret != RETURN_OK) {
13399 fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__);
13400 return RETURN_ERR;
13401 }
developer72fb0bb2023-01-11 09:46:29 +080013402
13403 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
13404 if (ret != RETURN_OK) {
13405 fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__);
13406 return RETURN_ERR;
13407 }
13408
developer72fb0bb2023-01-11 09:46:29 +080013409 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
13410 if (ret != RETURN_OK) {
13411 fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__);
13412 return RETURN_ERR;
13413 }
13414
developer23e71282023-01-18 10:25:19 +080013415 wifi_setApEnable(vap_info->vap_index, FALSE);
13416 wifi_setApEnable(vap_info->vap_index, TRUE);
13417 multiple_set = FALSE;
13418
13419 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
developer72fb0bb2023-01-11 09:46:29 +080013420 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
13421 if (ret != RETURN_OK) {
13422 fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__);
13423 return RETURN_ERR;
13424 }
13425
13426 // TODO mgmtPowerControl, interworking, wps
13427 }
13428 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13429 return RETURN_OK;
13430}
13431
13432int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
13433{
13434 char *token, *next;
13435 const char s[2] = ",";
13436 int count =0;
13437
13438 /* get the first token */
13439 token = strtok_r(pchannels, s, &next);
13440
13441 /* walk through other tokens */
13442 while( token != NULL && count < MAX_CHANNELS) {
13443 chlistptr->channels_list[count++] = atoi(token);
13444 token = strtok_r(NULL, s, &next);
13445 }
13446
13447 return count;
13448}
13449
13450static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
13451{
13452 INT status;
13453 wifi_channels_list_t *chlistp;
13454 CHAR output_string[64];
13455 CHAR pchannels[128];
13456 CHAR interface_name[16] = {0};
13457 wifi_band band;
13458
13459 if(rcap == NULL)
13460 {
13461 return RETURN_ERR;
13462 }
13463
13464 rcap->numSupportedFreqBand = 1;
13465 band = wifi_index_to_band(radioIndex);
13466
13467 if (band == band_2_4)
13468 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
13469 else if (band == band_5)
13470 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
13471 else if (band == band_6)
13472 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
13473
13474 chlistp = &(rcap->channel_list[0]);
13475 memset(pchannels, 0, sizeof(pchannels));
13476
13477 /* possible number of radio channels */
13478 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
13479 {
13480 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
13481 }
13482 /* Number of channels and list*/
13483 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
13484
13485 /* autoChannelSupported */
13486 /* always ON with wifi_getRadioAutoChannelSupported */
13487 rcap->autoChannelSupported = TRUE;
13488
13489 /* DCSSupported */
13490 /* always ON with wifi_getRadioDCSSupported */
13491 rcap->DCSSupported = TRUE;
13492
13493 /* zeroDFSSupported - TBD */
13494 rcap->zeroDFSSupported = FALSE;
13495
13496 /* Supported Country List*/
13497 memset(output_string, 0, sizeof(output_string));
13498 status = wifi_getRadioCountryCode(radioIndex, output_string);
13499 if( status != 0 ) {
13500 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
13501 return RETURN_ERR;
13502 } else {
13503 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
13504 }
13505 if(!strcmp(output_string,"US")){
13506 rcap->countrySupported[0] = wifi_countrycode_US;
13507 rcap->countrySupported[1] = wifi_countrycode_CA;
13508 } else if (!strcmp(output_string,"CA")) {
13509 rcap->countrySupported[0] = wifi_countrycode_CA;
13510 rcap->countrySupported[1] = wifi_countrycode_US;
13511 } else {
13512 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
13513 }
13514
13515 rcap->numcountrySupported = 2;
13516
13517 /* csi */
13518 rcap->csi.maxDevices = 8;
13519 rcap->csi.soudingFrameSupported = TRUE;
13520
13521 wifi_GetInterfaceName(radioIndex, interface_name);
13522 snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
13523
13524 /* channelWidth - all supported bandwidths */
13525 int i=0;
13526 rcap->channelWidth[i] = 0;
13527 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
13528 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
13529 WIFI_CHANNELBANDWIDTH_40MHZ);
13530
13531 }
13532 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
13533 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
13534 WIFI_CHANNELBANDWIDTH_40MHZ |
13535 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
13536 }
13537
13538
13539 /* mode - all supported variants */
13540 // rcap->mode[i] = WIFI_80211_VARIANT_H;
13541 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
13542 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
13543 }
13544 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
13545 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
13546 }
13547 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
13548 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
13549 }
13550 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
13551 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
13552
13553 /* supportedBitRate - all supported bitrates */
13554 rcap->supportedBitRate[i] = 0;
13555 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
13556 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
13557 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
13558 }
13559 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) | rcap->band[i] & (WIFI_FREQUENCY_6_BAND )) {
13560 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
13561 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
13562 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
13563 }
13564
13565
13566 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
13567 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
13568 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
13569 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
13570 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
13571 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
13572 rcap->cipherSupported = 0;
13573 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
13574 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
13575
13576 return RETURN_OK;
13577}
13578
13579INT wifi_getHalCapability(wifi_hal_capability_t *cap)
13580{
13581 INT status = 0, radioIndex = 0;
13582 char cmd[MAX_BUF_SIZE] = {0}, output[MAX_BUF_SIZE] = {0};
13583 int iter = 0;
13584 unsigned int j = 0;
13585 int max_num_radios;
13586 wifi_interface_name_idex_map_t *iface_info = NULL;
13587
13588 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13589
13590 memset(cap, 0, sizeof(wifi_hal_capability_t));
13591
13592 /* version */
13593 cap->version.major = WIFI_HAL_MAJOR_VERSION;
13594 cap->version.minor = WIFI_HAL_MINOR_VERSION;
13595
13596 /* number of radios platform property */
13597 wifi_getMaxRadioNumber(&max_num_radios);
13598 cap->wifi_prop.numRadios = max_num_radios;
13599
13600 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
13601 {
13602 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
13603 if (status != 0) {
13604 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
13605 return RETURN_ERR;
13606 }
13607
13608 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
13609 {
13610 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
13611 {
13612 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
13613 return RETURN_ERR;
13614 }
13615 iface_info = &cap->wifi_prop.interface_map[iter];
13616 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
13617 iface_info->rdk_radio_index = radioIndex;
13618 memset(output, 0, sizeof(output));
13619 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
13620 {
13621 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
13622 }
13623 // TODO: bridge name
13624 // TODO: vlan id
13625 // TODO: primary
13626 iface_info->index = array_index_to_vap_index(radioIndex, j);
13627 memset(output, 0, sizeof(output));
13628 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
13629 {
13630 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
13631 }
13632 iter++;
13633 }
13634 }
13635
13636 cap->BandSteeringSupported = FALSE;
13637 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13638 return RETURN_OK;
13639}
13640
13641INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
13642{
13643 struct params h_config={0};
13644 char config_file[64] = {0};
13645
13646 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
13647
13648 h_config.name = "okc";
13649 h_config.value = okc_enable?"1":"0";
13650
13651 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
13652 wifi_hostapdWrite(config_file, &h_config, 1);
13653 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
13654
13655 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
13656 return RETURN_OK;
13657}
13658
13659INT wifi_setSAEMFP(int ap_index, BOOL enable)
13660{
13661 struct params h_config={0};
13662 char config_file[64] = {0};
13663 char buf[128] = {0};
13664
13665 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
13666
13667 h_config.name = "sae_require_mfp";
13668 h_config.value = enable?"1":"0";
13669
13670 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
13671 wifi_hostapdWrite(config_file, &h_config, 1);
13672 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
13673
13674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
13675 return RETURN_OK;
13676}
13677
13678INT wifi_setSAEpwe(int ap_index, int sae_pwe)
13679{
13680 struct params h_config={0};
13681 char config_file[64] = {0};
13682 char buf[128] = {0};
13683
13684 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
13685
13686 h_config.name = "sae_pwe";
13687 snprintf(buf, sizeof(buf), "%d", sae_pwe);
13688 h_config.value = buf;
13689
13690 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
13691 wifi_hostapdWrite(config_file, &h_config, 1);
13692 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
13693
13694 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
13695 return RETURN_OK;
13696}
13697
13698INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
13699{
13700 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
13701 struct params h_config={0};
13702 char config_file[64] = {0};
13703
13704 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
13705
13706 h_config.name = "wpa_disable_eapol_key_retries";
13707 h_config.value = disable_EAPOL_retries?"1":"0";
13708
13709 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
13710 wifi_hostapdWrite(config_file, &h_config, 1);
13711 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
13712
13713 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
13714 return RETURN_OK;
13715}
13716
13717INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
13718{
13719 char buf[128] = {0};
13720 char config_file[128] = {0};
developere5750452023-05-15 16:46:42 +080013721 char cmd[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013722 char password[64] = {0};
13723 char mfp[32] = {0};
13724 char wpa_mode[32] = {0};
13725 BOOL okc_enable = FALSE;
13726 BOOL sae_MFP = FALSE;
13727 BOOL disable_EAPOL_retries = TRUE;
13728 int sae_pwe = 0;
13729 struct params params = {0};
13730 wifi_band band = band_invalid;
13731
13732 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13733
13734 multiple_set = TRUE;
13735 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
13736 if (security->mode == wifi_security_mode_none) {
13737 strcpy(wpa_mode, "None");
13738 } else if (security->mode == wifi_security_mode_wpa_personal)
13739 strcpy(wpa_mode, "WPA-Personal");
13740 else if (security->mode == wifi_security_mode_wpa2_personal)
13741 strcpy(wpa_mode, "WPA2-Personal");
13742 else if (security->mode == wifi_security_mode_wpa_wpa2_personal)
13743 strcpy(wpa_mode, "WPA-WPA2-Personal");
13744 else if (security->mode == wifi_security_mode_wpa_enterprise)
13745 strcpy(wpa_mode, "WPA-Enterprise");
13746 else if (security->mode == wifi_security_mode_wpa2_enterprise)
13747 strcpy(wpa_mode, "WPA2-Enterprise");
13748 else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise)
13749 strcpy(wpa_mode, "WPA-WPA2-Enterprise");
13750 else if (security->mode == wifi_security_mode_wpa3_personal) {
13751 strcpy(wpa_mode, "WPA3-Personal");
13752 okc_enable = TRUE;
13753 sae_MFP = TRUE;
13754 sae_pwe = 2;
13755 disable_EAPOL_retries = FALSE;
13756 } else if (security->mode == wifi_security_mode_wpa3_transition) {
13757 strcpy(wpa_mode, "WPA3-Personal-Transition");
13758 okc_enable = TRUE;
13759 sae_MFP = TRUE;
13760 sae_pwe = 2;
13761 disable_EAPOL_retries = FALSE;
13762 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
13763 strcpy(wpa_mode, "WPA3-Enterprise");
13764 sae_MFP = TRUE;
13765 sae_pwe = 2;
13766 disable_EAPOL_retries = FALSE;
developerd01e3e82023-04-26 19:10:38 +080013767 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer3086e2f2023-01-17 09:40:01 +080013768 strcpy(wpa_mode, "OWE");
13769 sae_MFP = TRUE;
13770 sae_pwe = 2;
13771 disable_EAPOL_retries = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080013772 }
13773
13774 band = wifi_index_to_band(ap_index);
13775 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
13776 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
13777 return RETURN_ERR;
13778 }
13779
13780 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
13781 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
13782 wifi_setSAEMFP(ap_index, sae_MFP);
13783 wifi_setSAEpwe(ap_index, sae_pwe);
13784 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
13785
developerd01e3e82023-04-26 19:10:38 +080013786 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
developere5750452023-05-15 16:46:42 +080013787 if (security->u.key.type == wifi_security_key_type_psk || security->u.key.type == wifi_security_key_type_pass || security->u.key.type == wifi_security_key_type_psk_sae) {
13788 int key_len = strlen(security->u.key.key);
13789 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
13790 if (key_len == 64) { // set wpa_psk
13791 strncpy(password, security->u.key.key, 64); // 64 characters
13792 password[64] = '\0';
13793 wifi_setApSecurityPreSharedKey(ap_index, password);
13794 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
13795 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
13796 strncpy(password, security->u.key.key, 63);
13797 password[63] = '\0';
13798 wifi_setApSecurityKeyPassphrase(ap_index, password);
13799 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
13800 } else
13801 return RETURN_ERR;
13802 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080013803 }
13804 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
13805 params.name = "sae_password";
13806 params.value = security->u.key.key;
13807 wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +080013808 } else { // remove sae_password
13809 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
13810 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080013811 }
13812 }
13813
13814 if (security->mode != wifi_security_mode_none) {
13815 memset(&params, 0, sizeof(params));
13816 params.name = "wpa_pairwise";
13817 if (security->encr == wifi_encryption_tkip)
13818 params.value = "TKIP";
13819 else if (security->encr == wifi_encryption_aes)
13820 params.value = "CCMP";
13821 else if (security->encr == wifi_encryption_aes_tkip)
13822 params.value = "TKIP CCMP";
13823 wifi_hostapdWrite(config_file, &params, 1);
13824 }
13825
13826 if (security->mfp == wifi_mfp_cfg_disabled)
13827 strcpy(mfp, "Disabled");
13828 else if (security->mfp == wifi_mfp_cfg_optional)
13829 strcpy(mfp, "Optional");
13830 else if (security->mfp == wifi_mfp_cfg_required)
13831 strcpy(mfp, "Required");
13832 wifi_setApSecurityMFPConfig(ap_index, mfp);
13833
13834 memset(&params, 0, sizeof(params));
13835 params.name = "transition_disable";
13836 if (security->wpa3_transition_disable == TRUE)
13837 params.value = "0x01";
13838 else
13839 params.value = "0x00";
13840 wifi_hostapdWrite(config_file, &params, 1);
13841
13842 memset(&params, 0, sizeof(params));
13843 params.name = "wpa_group_rekey";
13844 snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
13845 params.value = buf;
13846 wifi_hostapdWrite(config_file, &params, 1);
13847
13848 memset(&params, 0, sizeof(params));
13849 params.name = "wpa_strict_rekey";
13850 params.value = security->strict_rekey?"1":"0";
13851 wifi_hostapdWrite(config_file, &params, 1);
13852
13853 memset(&params, 0, sizeof(params));
13854 params.name = "wpa_pairwise_update_count";
developere5750452023-05-15 16:46:42 +080013855 if (security->eapol_key_retries == 0)
13856 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developer72fb0bb2023-01-11 09:46:29 +080013857 snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
13858 params.value = buf;
13859 wifi_hostapdWrite(config_file, &params, 1);
13860
13861 memset(&params, 0, sizeof(params));
13862 params.name = "disable_pmksa_caching";
13863 params.value = security->disable_pmksa_caching?"1":"0";
13864 wifi_hostapdWrite(config_file, &params, 1);
13865
developer23e71282023-01-18 10:25:19 +080013866 if (multiple_set == FALSE) {
13867 wifi_setApEnable(ap_index, FALSE);
13868 wifi_setApEnable(ap_index, TRUE);
13869 }
developer72fb0bb2023-01-11 09:46:29 +080013870
13871 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13872
13873 return RETURN_OK;
13874}
13875
13876INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
13877{
13878 char buf[256] = {0};
13879 char config_file[128] = {0};
13880 int disable = 0;
developere5750452023-05-15 16:46:42 +080013881 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080013882
13883 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13884 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
13885 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
13886 security->mode = wifi_security_mode_none;
13887 if (strlen(buf) != 0) {
13888 if (!strcmp(buf, "WPA-Personal"))
13889 security->mode = wifi_security_mode_wpa_personal;
13890 else if (!strcmp(buf, "WPA2-Personal"))
13891 security->mode = wifi_security_mode_wpa2_personal;
13892 else if (!strcmp(buf, "WPA-WPA2-Personal"))
13893 security->mode = wifi_security_mode_wpa_wpa2_personal;
13894 else if (!strcmp(buf, "WPA-Enterprise"))
13895 security->mode = wifi_security_mode_wpa_enterprise;
13896 else if (!strcmp(buf, "WPA2-Enterprise"))
13897 security->mode = wifi_security_mode_wpa2_enterprise;
13898 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
13899 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
13900 else if (!strcmp(buf, "WPA3-Personal"))
13901 security->mode = wifi_security_mode_wpa3_personal;
13902 else if (!strcmp(buf, "WPA3-Personal-Transition"))
13903 security->mode = wifi_security_mode_wpa3_transition;
13904 else if (!strcmp(buf, "WPA3-Enterprise"))
13905 security->mode = wifi_security_mode_wpa3_enterprise;
developer3086e2f2023-01-17 09:40:01 +080013906 else if (!strcmp(buf, "OWE"))
developerd01e3e82023-04-26 19:10:38 +080013907 security->mode = wifi_security_mode_enhanced_open;
developer72fb0bb2023-01-11 09:46:29 +080013908 }
13909
13910 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
13911 if (security->mode == wifi_security_mode_none)
13912 security->encr = wifi_encryption_none;
13913 else {
13914 if (strcmp(buf, "TKIP") == 0)
13915 security->encr = wifi_encryption_tkip;
13916 else if (strcmp(buf, "CCMP") == 0)
13917 security->encr = wifi_encryption_aes;
13918 else
13919 security->encr = wifi_encryption_aes_tkip;
13920 }
13921
13922 if (security->mode != wifi_encryption_none) {
13923 memset(buf, 0, sizeof(buf));
13924 // wpa3 can use one or both configs as password, so we check sae_password first.
13925 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
developere5750452023-05-15 16:46:42 +080013926 if (strlen(buf) != 0) {
13927 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
13928 security->u.key.type = wifi_security_key_type_sae;
13929 set_sae = TRUE;
13930 strncpy(security->u.key.key, buf, sizeof(buf));
13931 }
13932 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
13933 if (strlen(buf) != 0){
13934 if (set_sae == TRUE)
13935 security->u.key.type = wifi_security_key_type_psk_sae;
13936 else if (strlen(buf) == 64)
13937 security->u.key.type = wifi_security_key_type_psk;
13938 else
13939 security->u.key.type = wifi_security_key_type_pass;
13940 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
developer72fb0bb2023-01-11 09:46:29 +080013941 }
developer72fb0bb2023-01-11 09:46:29 +080013942 security->u.key.key[255] = '\0';
13943 }
13944
13945 memset(buf, 0, sizeof(buf));
13946 wifi_getApSecurityMFPConfig(ap_index, buf);
13947 if (strcmp(buf, "Disabled") == 0)
13948 security->mfp = wifi_mfp_cfg_disabled;
13949 else if (strcmp(buf, "Optional") == 0)
13950 security->mfp = wifi_mfp_cfg_optional;
13951 else if (strcmp(buf, "Required") == 0)
13952 security->mfp = wifi_mfp_cfg_required;
13953
13954 memset(buf, 0, sizeof(buf));
13955 security->wpa3_transition_disable = FALSE;
13956 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
13957 disable = strtol(buf, NULL, 16);
13958 if (disable != 0)
13959 security->wpa3_transition_disable = TRUE;
13960
13961 memset(buf, 0, sizeof(buf));
13962 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
13963 if (strlen(buf) == 0)
13964 security->rekey_interval = 86400;
13965 else
13966 security->rekey_interval = strtol(buf, NULL, 10);
13967
13968 memset(buf, 0, sizeof(buf));
13969 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
13970 if (strlen(buf) == 0)
13971 security->strict_rekey = 1;
13972 else
13973 security->strict_rekey = strtol(buf, NULL, 10);
13974
13975 memset(buf, 0, sizeof(buf));
13976 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
13977 if (strlen(buf) == 0)
13978 security->eapol_key_retries = 4;
13979 else
13980 security->eapol_key_retries = strtol(buf, NULL, 10);
13981
13982 memset(buf, 0, sizeof(buf));
13983 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
13984 if (strlen(buf) == 0)
13985 security->disable_pmksa_caching = FALSE;
13986 else
13987 security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE;
13988
13989 /* TODO
13990 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
13991 */
13992 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
13993 security->eap_identity_req_timeout = 0;
13994 security->eap_identity_req_retries = 0;
13995 security->eap_req_timeout = 0;
13996 security->eap_req_retries = 0;
13997 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13998 return RETURN_OK;
13999}
14000
14001#endif /* WIFI_HAL_VERSION_3 */
14002
14003#ifdef WIFI_HAL_VERSION_3_PHASE2
14004INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
14005{
14006 char interface_name[16] = {0};
14007 char cmd[128] = {0};
14008 char buf[128] = {0};
14009 char *mac_addr = NULL;
14010 BOOL status = FALSE;
14011 size_t len = 0;
14012
14013 if(ap_index > MAX_APS)
14014 return RETURN_ERR;
14015
14016 *output_numDevices = 0;
14017 wifi_getApEnable(ap_index, &status);
14018 if (status == FALSE)
14019 return RETURN_OK;
14020
14021 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
14022 return RETURN_ERR;
14023 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
14024 _syscmd(cmd, buf, sizeof(buf));
14025
14026 mac_addr = strtok(buf, "\n");
14027 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
14028 *output_numDevices = i + 1;
14029 fprintf(stderr, "mac_addr: %s\n", mac_addr);
14030 addr_ptr = output_deviceMacAddressArray[i];
14031 mac_addr_aton(addr_ptr, mac_addr);
14032 mac_addr = strtok(NULL, "\n");
14033 }
14034
14035 return RETURN_OK;
14036}
14037#else
14038INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
14039{
14040 char interface_name[16] = {0};
14041 char cmd[128];
14042 BOOL status = false;
14043
14044 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
14045 return RETURN_ERR;
14046
14047 output_buf[0] = '\0';
14048
14049 wifi_getApEnable(ap_index,&status);
14050 if (!status)
14051 return RETURN_OK;
14052
14053 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
14054 return RETURN_ERR;
14055 sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
14056 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080014057
developer72fb0bb2023-01-11 09:46:29 +080014058 return RETURN_OK;
14059}
14060#endif
14061
14062INT wifi_getProxyArp(INT apIndex, BOOL *enable)
14063{
14064 char output[16]={'\0'};
14065 char config_file[MAX_BUF_SIZE] = {0};
14066
14067 if (!enable)
14068 return RETURN_ERR;
14069
14070 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
14071 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
14072
14073 if (strlen(output) == 0)
14074 *enable = FALSE;
14075 else if (strncmp(output, "1", 1) == 0)
14076 *enable = TRUE;
14077 else
14078 *enable = FALSE;
14079
14080 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
14081 return RETURN_OK;
14082}
14083
14084INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
14085{
14086 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
14087 return RETURN_ERR;
14088 *output_enable=TRUE;
14089 return RETURN_OK;
14090}
14091
14092INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
14093{
14094 char cmd[128] = {0};
14095 char buf[128] = {0};
14096 char line[128] = {0};
14097 size_t len = 0;
14098 FILE *f = NULL;
14099 int index = 0;
14100 int exp = 0;
14101 int mantissa = 0;
14102 int duration = 0;
14103 int radio_index = 0;
14104 int max_radio_num = 0;
14105 uint twt_wake_interval = 0;
14106 int phyId = 0;
14107 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14108
14109 wifi_getMaxRadioNumber(&max_radio_num);
14110
14111 radio_index = ap_index % max_radio_num;
14112
14113 phyId = radio_index_to_phy(radio_index);
14114 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
14115 _syscmd(cmd, buf, sizeof(buf));
14116 *numSessionReturned = strtol(buf, NULL, 10) - 1;
14117 if (*numSessionReturned > maxNumberSessions)
14118 *numSessionReturned = maxNumberSessions;
14119 else if (*numSessionReturned < 1) {
14120 *numSessionReturned = 0;
14121 return RETURN_OK;
14122 }
14123
14124 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
14125 if ((f = popen(cmd, "r")) == NULL) {
14126 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
14127 return RETURN_ERR;
14128 }
14129
14130 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
14131 while((fgets(line, sizeof(line), f)) != NULL) {
14132 char *tmp = NULL;
14133 strcpy(buf, line);
14134 tmp = strtok(buf, " ");
14135 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
14136 tmp = strtok(NULL, " ");
14137 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
14138 tmp = strtok(NULL, " ");
14139 if (strstr(tmp, "t")) {
14140 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
14141 }
14142 if (strstr(tmp, "a")) {
14143 twtSessions[index].twtParameters.operation.announced = TRUE;
14144 }
14145 tmp = strtok(NULL, " ");
14146 exp = strtol(tmp, NULL, 10);
14147 tmp = strtok(NULL, " ");
14148 mantissa = strtol(tmp, NULL, 10);
14149 tmp = strtok(NULL, " ");
14150 duration = strtol(tmp, NULL, 10);
14151
14152 // only implicit supported
14153 twtSessions[index].twtParameters.operation.implicit = TRUE;
14154 // only individual agreement supported
14155 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
14156
14157 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
14158 twt_wake_interval = mantissa * (1 << exp);
14159 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
14160 // Overflow handling
14161 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
14162 } else {
14163 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
14164 }
14165 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
14166 index++;
14167 }
14168
14169 pclose(f);
14170 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14171 return RETURN_OK;
14172}