blob: b11811b8593f58f3f5f2ffb70d8365f6c2f23c78 [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>
developer8dd72532023-05-17 19:58:35 +080057#include <net/if.h>
58#include <unl.h>
59#include "mtk_vendor_nl80211.h"
developer72fb0bb2023-01-11 09:46:29 +080060#endif
61
62#include <ev.h>
63#include <wpa_ctrl.h>
64#include <errno.h>
65#include <time.h>
66#define MAC_ALEN 6
67
68#define MAX_BUF_SIZE 256
69#define MAX_CMD_SIZE 256
70#define IF_NAME_SIZE 16
71#define CONFIG_PREFIX "/nvram/hostapd"
72#define ACL_PREFIX "/nvram/hostapd-acl"
73#define DENY_PREFIX "/nvram/hostapd-deny"
74//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
75#define SOCK_PREFIX "/var/run/hostapd/wifi"
76#define VAP_STATUS_FILE "/nvram/vap-status"
77#define ESSID_FILE "/tmp/essid"
78#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
79#define CHANNEL_STATS_FILE "/tmp/channel_stats"
80#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
81#define VLAN_FILE "/nvram/hostapd.vlan"
82#define PSK_FILE "/nvram/hostapd"
83#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080084#define POWER_PERCENTAGE "/tmp/POWER"
85#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
86/*LOGAN_DAT_FILE: may be different on customer's platform.*/
87#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +080088#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +080089
developer72fb0bb2023-01-11 09:46:29 +080090#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerf6a87542023-05-16 15:47:28 +080091
developer72fb0bb2023-01-11 09:46:29 +080092#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +080093#define BASE_PHY_INDEX 1
94#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +080095
96/*
97 MAX_APS - Number of all AP available in system
98 2x Home AP
99 2x Backhaul AP
100 2x Guest AP
101 2x Secure Onboard AP
102 2x Service AP
103
104*/
105
106
107#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800108
109#define PREFIX_WIFI2G "ra"
110#define PREFIX_WIFI5G "rai"
111#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800112
developer47cc27a2023-05-17 23:09:58 +0800113#define PREFIX_SSID_2G "RDKB_2G"
114#define PREFIX_SSID_5G "RDKB_5G"
115#define PREFIX_SSID_6G "RDKB_6G"
116
developer72fb0bb2023-01-11 09:46:29 +0800117#ifndef RADIO_PREFIX
118#define RADIO_PREFIX "wlan"
119#endif
120
121#define MAX_ASSOCIATED_STA_NUM 2007
122
123//Uncomment to enable debug logs
124//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800125enum {
126 DEBUG_OFF = 0,
127 DEBUG_ERROR = 1,
128 DEBUG_WARN = 2,
129 DEBUG_NOTICE = 3,
130 DEBUG_INFO = 4
131};
132int wifi_debug_level = DEBUG_NOTICE;
133#define wifi_debug(level, fmt, args...) \
134{ \
135 if (level <= wifi_debug_level) \
136 { \
developer2edaf012023-05-24 14:24:53 +0800137 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800138 } \
139}
developer72fb0bb2023-01-11 09:46:29 +0800140
141#ifdef WIFI_DEBUG
142#define wifi_dbg_printf printf
143#define WIFI_ENTRY_EXIT_DEBUG printf
144#else
145#define wifi_dbg_printf(format, args...) printf("")
146#define WIFI_ENTRY_EXIT_DEBUG(format, args...) printf("")
147#endif
148
149#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
150#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
151#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
152#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
153#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
154#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
155#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
156#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
157#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
158#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
159
160#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
161
162#define BW_FNAME "/nvram/bw_file.txt"
163
164#define PS_MAX_TID 16
165
developer96b38512023-02-22 11:17:45 +0800166#define MAX_CARD_INDEX 3
167
developer72fb0bb2023-01-11 09:46:29 +0800168static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
169 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
170 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
171 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
172 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
173 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
174 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
175 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
176 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
177 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
178 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
179 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
180 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
181 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
182 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
183 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
184 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
185};
186
187typedef unsigned long long u64;
188
189/* Enum to define WiFi Bands */
190typedef enum
191{
192 band_invalid = -1,
193 band_2_4 = 0,
194 band_5 = 1,
195 band_6 = 2,
196} wifi_band;
197
developer17038e62023-03-02 14:43:43 +0800198char* wifi_band_str[] = {
199 "2G",
200 "5G",
201 "6G",
202};
203
developer72fb0bb2023-01-11 09:46:29 +0800204typedef enum {
205 WIFI_MODE_A = 0x01,
206 WIFI_MODE_B = 0x02,
207 WIFI_MODE_G = 0x04,
208 WIFI_MODE_N = 0x08,
209 WIFI_MODE_AC = 0x10,
210 WIFI_MODE_AX = 0x20,
developera1255e42023-05-13 17:45:02 +0800211 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800212} wifi_ieee80211_Mode;
213
developerd1824452023-05-18 12:30:04 +0800214typedef enum ht_config_bw{
215 HT_BW_20,
216 HT_BW_40,
217};
218
219typedef enum vht_config_bw{
220 VHT_BW_2040,
221 VHT_BW_80,
222 VHT_BW_160,
223 VHT_BW_8080,
224};
225
226typedef enum eht_config_bw{
227 EHT_BW_20,
228 EHT_BW_40,
229 EHT_BW_80,
230 EHT_BW_160,
231 EHT_BW_320,
232};
233
developer72fb0bb2023-01-11 09:46:29 +0800234#ifdef WIFI_HAL_VERSION_3
235
236// Return number of elements in array
237#ifndef ARRAY_SIZE
238#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
239#endif /* ARRAY_SIZE */
240
241#ifndef ARRAY_AND_SIZE
242#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
243#endif /* ARRAY_AND_SIZE */
244
245#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
246
247typedef struct {
248 int32_t value;
249 int32_t param;
250 intptr_t key;
251 intptr_t data;
252} wifi_secur_list;
253
254static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
255static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
256wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
257wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
258char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
259static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developer47cc27a2023-05-17 23:09:58 +0800260static void wifi_PrepareDefaultHostapdConfigs(void);
261static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800262static void wifi_psk_file_reset_by_radio(char radio_idx);
263static void wifi_dat_file_reset();
264static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800265static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer47cc27a2023-05-17 23:09:58 +0800266
developer49b17232023-05-19 16:35:19 +0800267/*type define the nl80211 call back func*/
268typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
269
270/**
271*struct mtk_nl80211_param
272* init mtk nl80211 using parameters
273* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
274* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
275* @if_idx: the index should match the interface or wiphy.
276* Note: NA
277**/
278struct mtk_nl80211_param {
279 unsigned int sub_cmd;
280 int if_type;
281 int if_idx;
282};
283
284/**
developer121a8e72023-05-22 09:19:39 +0800285*struct mtk_nl80211_cb_data
286* init mtk nl80211 call back parameters
287* @out_buf: store the mtk vendor output msg for wifi hal buffer.
288* @out_len: the output buffer length.
289* Note: NA
290**/
291struct mtk_nl80211_cb_data {
292 char * out_buf;
293 unsigned int out_len;
294};
295
296/**
developer49b17232023-05-19 16:35:19 +0800297*mtk_nl80211_init
298* init mtk nl80211 netlink and init the vendor msg common part.
299* @nl: netlink, just init it.
300* @msg: netlink message will alloc it.
301* the msg send success/fails is not free by app
302* only the nla_put etc api fails should use nlmsg_free.
303* @msg_data: vendor data msg attr pointer.
304* @param: init using interface and sub_cmd parameter.
305*
306*init the netlink context and mtk netlink vendor msg.
307*
308*return:
309* 0: success
310* other: fail
311**/
312
313int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
314 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
315 /*sanity check here*/
316 if (!nl || !param) {
317 (void)fprintf(stderr,
318 "[%s][%d]:nl(0x%lx) or param(0x%lx) is null, error!\n",
319 __func__, __LINE__, nl, param);
320 return -1;
321 }
322 /*if_type check*/
323 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
324 (void)fprintf(stderr,
325 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
326 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
327 return -1;
328 }
329 /*init the nl*/
330 if (unl_genl_init(nl, "nl80211") < 0) {
331 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
332 __func__, __LINE__);
333 return -1;
334 }
335 /*init the msg*/
336 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
337
338 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
339 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
340 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
341 (void)fprintf(stderr,
342 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
343 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
344 goto err;
345 }
346
347 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
348 if (!*msg_data) {
349 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
350 __func__, __LINE__);
351 goto err;
352 }
353
354 return 0;
355err:
developer49b17232023-05-19 16:35:19 +0800356 nlmsg_free(*msg);
357 unl_free(nl);
358 return -1;
359}
360
361/**
362*mtk_nl80211_send
363* set the vendor cmd call back and sent the vendor msg.
364* @nl: netlink.
365* @msg: netlink message.
366* @msg_data: vendor data msg attr pointer.
367* @handler: if the msg have call back shoud add the call back func
368* the event msg will handle by the call back func(exp:get cmd)
369* other set it as NULL(exp:set cmd).
370* @arg:call back func arg parameter.
371*add end of the netlink msg, set the call back and send msg
372*
373*return:
374* 0: success
375* other: fail
376**/
377int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
378 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
379 int ret = 0;
380 /*sanity check*/
381 if (!nl || !msg || !msg_data) {
382 (void)fprintf(stderr,
383 "[%s][%d]:nl(0x%lx),msg(0x%lx) or msg_data(0x%lx) is null, error!\n",
384 __func__, __LINE__, nl, msg, msg_data);
385 return -1;
386 }
387 /*end the msg attr of vendor data*/
388 nla_nest_end(msg, msg_data);
389 /*send the msg and set call back */
390 ret = unl_genl_request(nl, msg, handler, arg);
391 if (ret)
392 (void)fprintf(stderr, "send nl80211 cmd fails\n");
393 return ret;
394}
395
396/**
397*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800398* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800399* @nl: netlink.
400*
developer2edaf012023-05-24 14:24:53 +0800401*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800402*
403*return:
404* 0: success
405**/
406
407int mtk_nl80211_deint(struct unl *nl) {
408 unl_free(nl);
409 return 0;
410}
411
developer72fb0bb2023-01-11 09:46:29 +0800412
413static wifi_secur_list map_security[] =
414{
415 WIFI_ITEM_STR(wifi_security_mode_none, "None"),
416 WIFI_ITEM_STR(wifi_security_mode_wep_64, "WEP-64"),
417 WIFI_ITEM_STR(wifi_security_mode_wep_128, "WEP-128"),
418 WIFI_ITEM_STR(wifi_security_mode_wpa_personal, "WPA-Personal"),
419 WIFI_ITEM_STR(wifi_security_mode_wpa_enterprise, "WPA-Enterprise"),
420 WIFI_ITEM_STR(wifi_security_mode_wpa2_personal, "WPA2-Personal"),
421 WIFI_ITEM_STR(wifi_security_mode_wpa2_enterprise, "WPA2-Enterprise"),
422 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_personal, "WPA-WPA2-Personal"),
423 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_enterprise, "WPA-WPA2-Enterprise"),
424 WIFI_ITEM_STR(wifi_security_mode_wpa3_personal, "WPA3-Personal"),
425 WIFI_ITEM_STR(wifi_security_mode_wpa3_transition, "WPA3-Personal-Transition"),
426 WIFI_ITEM_STR(wifi_security_mode_wpa3_enterprise, "WPA3-Enterprise")
427};
428
429wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
430{
431 wifi_secur_list *item;
432 int i;
433
434 for (item = list,i = 0;i < list_sz; item++, i++) {
435 if ((int)(item->key) == key) {
436 return item;
437 }
438 }
439
440 return NULL;
441}
442
443char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
444{
445 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
446
447 if (!item) {
448 return "";
449 }
450
451 return (char *)(item->data);
452}
453
454wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
455{
456 wifi_secur_list *item;
457 int i;
458
459 for (item = list,i = 0;i < list_sz; item++, i++) {
460 if (strcmp((char *)(item->data), str) == 0) {
461 return item;
462 }
463 }
464
465 return NULL;
466}
467#endif /* WIFI_HAL_VERSION_3 */
468
developer96b38512023-02-22 11:17:45 +0800469
470static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800471char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
472char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
473#define MAX_SSID_LEN 64
474char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800475int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800476
477static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
478static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
479
developer96b38512023-02-22 11:17:45 +0800480
481static int
482get_value(const char *conf_file, const char *param, char *value, int len)
483{
484 FILE *fp;
485 int ret = -1;
486 int param_len = strlen(param);
487 int buf_len;
488 char buf[256];
489
490 fp = fopen(conf_file, "r");
491 if (!fp) {
492 return -1;
493 }
494
495 while (fgets(buf, sizeof(buf), fp)) {
496 buf_len = strlen(buf);
497 if (buf[buf_len - 1] == '\n') {
498 buf_len--;
499 buf[buf_len] = '\0';
500 }
501 if ((buf_len > param_len) &&
502 (strncmp(buf, param, param_len) == 0) &&
503 (buf[param_len] == '=')) {
504
505 if (buf_len == (param_len + 1)) {
506 value[0] = '\0';
507 ret = 0;
508 } else {
509 ret = snprintf(value, len, "%s", buf + (param_len + 1));
510 }
511 fclose(fp);
512 return ret;
513 }
514 }
515 fclose(fp);
516 return -1;
517}
518
519static int
520get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
521{
522 char buf[256];
523 int ret;
524 char *save_ptr = NULL;
525 char *tok = NULL;
526
527 ret = get_value(conf_file, param, buf, sizeof(buf));
528 if (ret < 0)
529 return ret;
530
531 tok = strtok_r(buf, ";", &save_ptr);
532 do {
533 if (idx == 0 || tok == NULL)
534 break;
535 else
536 idx--;
537
538 tok = strtok_r(NULL, ";", &save_ptr);
539 } while (tok != NULL);
540
541 if (tok) {
542 ret = snprintf(value, len, "%s", tok);
543 } else {
544 ret = 0;
545 value[0] = '\0';
546 }
547
548 return ret;
549}
550
551
developer72fb0bb2023-01-11 09:46:29 +0800552#ifdef HAL_NETLINK_IMPL
553typedef struct {
554 int id;
555 struct nl_sock* socket;
556 struct nl_cb* cb;
557} Netlink;
558
559static int mac_addr_aton(unsigned char *mac_addr, char *arg)
560{
561 unsigned int mac_addr_int[6]={};
562 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);
563 mac_addr[0] = mac_addr_int[0];
564 mac_addr[1] = mac_addr_int[1];
565 mac_addr[2] = mac_addr_int[2];
566 mac_addr[3] = mac_addr_int[3];
567 mac_addr[4] = mac_addr_int[4];
568 mac_addr[5] = mac_addr_int[5];
569 return 0;
570}
571
572static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
573{
574 unsigned int mac_addr_int[6]={};
575 mac_addr_int[0] = arg[0];
576 mac_addr_int[1] = arg[1];
577 mac_addr_int[2] = arg[2];
578 mac_addr_int[3] = arg[3];
579 mac_addr_int[4] = arg[4];
580 mac_addr_int[5] = arg[5];
581 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]);
582 return;
583}
584
585static int ieee80211_frequency_to_channel(int freq)
586{
587 /* see 802.11-2007 17.3.8.3.2 and Annex J */
588 if (freq == 2484)
589 return 14;
590 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
591 else if (freq == 5935)
592 return 2;
593 else if (freq < 2484)
594 return (freq - 2407) / 5;
595 else if (freq >= 4910 && freq <= 4980)
596 return (freq - 4000) / 5;
597 else if (freq < 5950)
598 return (freq - 5000) / 5;
599 else if (freq <= 45000) /* DMG band lower limit */
600 /* see 802.11ax D6.1 27.3.23.2 */
601 return (freq - 5950) / 5;
602 else if (freq >= 58320 && freq <= 70200)
603 return (freq - 56160) / 2160;
604 else
605 return 0;
606}
607
608static int initSock80211(Netlink* nl) {
609 nl->socket = nl_socket_alloc();
610 if (!nl->socket) {
611 fprintf(stderr, "Failing to allocate the sock\n");
612 return -ENOMEM;
613 }
614
615 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
616
617 if (genl_connect(nl->socket)) {
618 fprintf(stderr, "Failed to connect\n");
619 nl_close(nl->socket);
620 nl_socket_free(nl->socket);
621 return -ENOLINK;
622 }
623
624 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
625 if (nl->id< 0) {
626 fprintf(stderr, "interface not found.\n");
627 nl_close(nl->socket);
628 nl_socket_free(nl->socket);
629 return -ENOENT;
630 }
631
632 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
633 if ((!nl->cb)) {
634 fprintf(stderr, "Failed to allocate netlink callback.\n");
635 nl_close(nl->socket);
636 nl_socket_free(nl->socket);
637 return ENOMEM;
638 }
639
640 return nl->id;
641}
642
643static int nlfree(Netlink *nl)
644{
645 nl_cb_put(nl->cb);
646 nl_close(nl->socket);
647 nl_socket_free(nl->socket);
648 return 0;
649}
650
651static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
652 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
653 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
654 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
655};
656
657static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
658};
659
660static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
661};
662
663typedef struct _wifi_channelStats_loc {
664 INT array_size;
665 INT ch_number;
666 BOOL ch_in_pool;
667 INT ch_noise;
668 BOOL ch_radar_noise;
669 INT ch_max_80211_rssi;
670 INT ch_non_80211_noise;
671 INT ch_utilization;
672 ULLONG ch_utilization_total;
673 ULLONG ch_utilization_busy;
674 ULLONG ch_utilization_busy_tx;
675 ULLONG ch_utilization_busy_rx;
676 ULLONG ch_utilization_busy_self;
677 ULLONG ch_utilization_busy_ext;
678} wifi_channelStats_t_loc;
679
680typedef struct wifi_device_info {
681 INT wifi_devIndex;
682 UCHAR wifi_devMacAddress[6];
683 CHAR wifi_devIPAddress[64];
684 BOOL wifi_devAssociatedDeviceAuthentiationState;
685 INT wifi_devSignalStrength;
686 INT wifi_devTxRate;
687 INT wifi_devRxRate;
688} wifi_device_info_t;
689
690#endif
691
692//For 5g Alias Interfaces
693static BOOL priv_flag = TRUE;
694static BOOL pub_flag = TRUE;
695static BOOL Radio_flag = TRUE;
696//wifi_setApBeaconRate(1, beaconRate);
697
698BOOL multiple_set = FALSE;
699
700struct params
701{
702 char * name;
703 char * value;
704};
705
706static int _syscmd(char *cmd, char *retBuf, int retBufSize)
707{
708 FILE *f;
709 char *ptr = retBuf;
710 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
711
712 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
713 if((f = popen(cmd, "r")) == NULL) {
714 fprintf(stderr,"\npopen %s error\n", cmd);
715 return RETURN_ERR;
716 }
717
718 while(!feof(f))
719 {
720 *ptr = 0;
721 if(bufSize>=128) {
722 bufbytes=128;
723 } else {
724 bufbytes=bufSize-1;
725 }
726
727 fgets(ptr,bufbytes,f);
728 readbytes=strlen(ptr);
729
730 if(!readbytes)
731 break;
732
733 bufSize-=readbytes;
734 ptr += readbytes;
735 }
736 cmd_ret = pclose(f);
737 retBuf[retBufSize-1]=0;
738 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
739
740 return cmd_ret >> 8;
741}
742
743INT radio_index_to_phy(int radioIndex)
744{
developer17038e62023-03-02 14:43:43 +0800745 /* TODO */
746 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800747}
748
749INT wifi_getMaxRadioNumber(INT *max_radio_num)
750{
751 char cmd[64] = {0};
752 char buf[4] = {0};
753
754 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
755
756 snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
757 _syscmd(cmd, buf, sizeof(buf));
758 *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10);
759
760 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
761
762 return RETURN_OK;
763}
764
developer17038e62023-03-02 14:43:43 +0800765wifi_band radio_index_to_band(int radioIndex)
766{
developer745f0bd2023-03-06 14:32:53 +0800767 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800768}
769
developer72fb0bb2023-01-11 09:46:29 +0800770wifi_band wifi_index_to_band(int apIndex)
771{
772 char cmd[128] = {0};
773 char buf[64] = {0};
774 int nl80211_band = 0;
775 int i = 0;
776 int phyIndex = 0;
777 int radioIndex = 0;
778 int max_radio_num = 0;
779 wifi_band band = band_invalid;
780
781 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
782
783 wifi_getMaxRadioNumber(&max_radio_num);
784 radioIndex = apIndex % max_radio_num;
785 phyIndex = radio_index_to_phy(radioIndex);
786 while(i < 10){
787 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
788 _syscmd(cmd, buf, sizeof(buf));
789 nl80211_band = strtol(buf, NULL, 10);
790 if (nl80211_band == 1)
791 band = band_2_4;
792 else if (nl80211_band == 2)
793 band = band_5;
794 else if (nl80211_band == 4) // band == 3 is 60GHz
795 band = band_6;
796
797 if(band != band_invalid)
798 break;
developer69b61b02023-03-07 17:17:44 +0800799
developer72fb0bb2023-01-11 09:46:29 +0800800 i++;
801 sleep(1);
802 }
803
804 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
805 return band;
806}
807
808static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
809{
developer7e4a2a62023-04-06 19:56:03 +0800810 char cmd[MAX_CMD_SIZE] = {0};
811 char buf[MAX_BUF_SIZE] = {0};
812 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +0800813
developer7e4a2a62023-04-06 19:56:03 +0800814 ret = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
815 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800816
developer7e4a2a62023-04-06 19:56:03 +0800817 if (ret < 0) {
818 printf("%s: snprintf error!", __func__);
819 return -1;
820 }
821
822 ret = _syscmd(cmd, buf, sizeof(buf));
823 if ((ret != 0) && (strlen(buf) == 0)) {
824 printf("%s: _syscmd error!", __func__);
825 return -1;
826 }
827
828 snprintf(output, output_size, "%s", buf);
829
830 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800831}
832
833static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
834{
developer7e4a2a62023-04-06 19:56:03 +0800835 char cmd[MAX_CMD_SIZE] = {0};
836 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +0800837
developer7e4a2a62023-04-06 19:56:03 +0800838 for (int i = 0; i < item_count; i++) {
developer72fb0bb2023-01-11 09:46:29 +0800839 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +0800840 if (strlen(buf) == 0) /*no such item, insert it*/
developera1255e42023-05-13 17:45:02 +0800841 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 +0800842 else /*find the item, update it*/
developer72fb0bb2023-01-11 09:46:29 +0800843 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 +0800844
developer72fb0bb2023-01-11 09:46:29 +0800845 if(_syscmd(cmd, buf, sizeof(buf)))
846 return -1;
847 }
848
developera1255e42023-05-13 17:45:02 +0800849 return 0;
850}
developerfde01262023-05-22 15:15:24 +0800851
developera1255e42023-05-13 17:45:02 +0800852static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
853{
854 char cmd[MAX_CMD_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800855 int ret = 0;
developerfde01262023-05-22 15:15:24 +0800856 int len;
857
858 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
859 if (ret < 0) {
860 printf("%s: snprintf error!", __func__);
861 return -1;
862 }
863
864 ret = _syscmd(cmd, output, output_size);
865 if ((ret != 0) && (strlen(output) == 0)) {
866 printf("%s: _syscmd error!", __func__);
867 return -1;
868 }
developera1255e42023-05-13 17:45:02 +0800869
developerfde01262023-05-22 15:15:24 +0800870 len = strlen(output);
871 if ((len > 0) && (output[len - 1] == '\n')) {
872 output[len - 1] = '\0';
873 }
874
875 return 0;
876}
developera1255e42023-05-13 17:45:02 +0800877
developer3a85ab82023-05-25 11:59:38 +0800878static int wifi_datfileRead2(char *conf_file, int idx, char *param, char *output, int output_size)
developerfde01262023-05-22 15:15:24 +0800879{
880 char cmd[MAX_CMD_SIZE] = {0};
881 int ret = 0;
882 int len;
883
developer3a85ab82023-05-25 11:59:38 +0800884 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s %d", conf_file, param, idx);
developera1255e42023-05-13 17:45:02 +0800885 if (ret < 0) {
886 printf("%s: snprintf error!", __func__);
887 return -1;
888 }
889
developerfde01262023-05-22 15:15:24 +0800890 ret = _syscmd(cmd, output, output_size);
891 if ((ret != 0) && (strlen(output) == 0)) {
developera1255e42023-05-13 17:45:02 +0800892 printf("%s: _syscmd error!", __func__);
893 return -1;
894 }
895
developerfde01262023-05-22 15:15:24 +0800896 len = strlen(output);
897 if ((len > 0) && (output[len - 1] == '\n')) {
898 output[len - 1] = '\0';
899 }
developera1255e42023-05-13 17:45:02 +0800900
developer72fb0bb2023-01-11 09:46:29 +0800901 return 0;
902}
903
developera1255e42023-05-13 17:45:02 +0800904static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
905{
developerfde01262023-05-22 15:15:24 +0800906 int ret;
developera1255e42023-05-13 17:45:02 +0800907 char cmd[MAX_CMD_SIZE] = {0};
908 char buf[MAX_BUF_SIZE] = {0};
909
910 for (int i = 0; i < item_count; i++) {
developerfde01262023-05-22 15:15:24 +0800911 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
912 if (ret < 0) {
913 printf("%s: snprintf error!", __func__);
914 return -1;
915 }
developera1255e42023-05-13 17:45:02 +0800916
917 if(_syscmd(cmd, buf, sizeof(buf)))
918 return -1;
919 }
920
921 return 0;
922}
923
developer3a85ab82023-05-25 11:59:38 +0800924static int wifi_datfileWrite2(char *conf_file, int idx, struct params *list, int item_count)
developerfde01262023-05-22 15:15:24 +0800925{
926 int ret;
927 char cmd[MAX_CMD_SIZE] = {0};
928 char buf[MAX_BUF_SIZE] = {0};
929
930 for (int i = 0; i < item_count; i++) {
developer3a85ab82023-05-25 11:59:38 +0800931 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s %d \"%s\"", conf_file, list[i].name, idx, list[i].value);
developerfde01262023-05-22 15:15:24 +0800932 if (ret < 0) {
933 printf("%s: snprintf error!", __func__);
934 return -1;
935 }
936
937 if(_syscmd(cmd, buf, sizeof(buf)))
938 return -1;
939 }
940
941 return 0;
942}
943
944static int wifi_l1ProfileRead(char *param, char *output, int output_size)
945{
946 char buf[MAX_BUF_SIZE] = {0};
947 int ret;
948
949 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
950 if (!param || !output || (output_size <= 0)) {
951 fprintf(stderr, "%s: invalid parameters", __func__);
952 return RETURN_ERR;
953 }
954
955 ret = wifi_datfileRead(l1profile, param, output, output_size);
956 if (ret != 0) {
957 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, l1profile, ret);
958 return RETURN_ERR;
959 }
960
961 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
962 return RETURN_OK;
963}
964
developer3a85ab82023-05-25 11:59:38 +0800965static int wifi_l1ProfileRead2(char *param, int idx, char *output, int output_size)
966{
967 char buf[MAX_BUF_SIZE] = {0};
968 int ret;
969
970 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
971 if (!param || !output || (output_size <= 0)) {
972 fprintf(stderr, "%s: invalid parameters", __func__);
973 return RETURN_ERR;
974 }
975
976 ret = wifi_datfileRead2(l1profile, idx, param, output, output_size);
977 if (ret != 0) {
978 fprintf(stderr, "%s: wifi_datfileRead2 %s from %s failed, ret:%d", __func__, param, l1profile, ret);
979 return RETURN_ERR;
980 }
981
982 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
983 return RETURN_OK;
984}
985
986
developerfde01262023-05-22 15:15:24 +0800987static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
988{
989 char option[64];
990 char card_profile_path[64];
991 int ret;
992
993 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
994
995 if (!param || !output || (output_size <= 0)) {
996 fprintf(stderr, "%s: invalid parameters", __func__);
997 return RETURN_ERR;
998 }
999
1000 snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
1001 ret = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
1002 if (ret != 0) {
1003 fprintf(stderr, "%s: wifi_l1ProfileRead %s failed, ret:%d", __func__, option, ret);
1004 return RETURN_ERR;
1005 }
1006
1007 ret = wifi_datfileRead(card_profile_path, param, output, output_size);
1008 if (ret != 0) {
1009 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, card_profile_path, ret);
1010 return RETURN_ERR;
1011 }
1012
1013 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1014 return RETURN_OK;
1015}
1016
1017static int wifi_BandProfileRead(int card_idx,
1018 int radio_idx,
1019 char *param,
1020 char *output,
1021 int output_size,
1022 char *default_value)
1023{
1024 char option[64];
1025 char band_profile_path[64];
1026 int ret;
1027
1028 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1029 if (!param || !output || (output_size <= 0)) {
1030 fprintf(stderr, "%s: invalid parameters", __func__);
1031 return RETURN_ERR;
1032 }
1033
1034 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1035 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1036 if (ret != 0) {
1037 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1038 return RETURN_ERR;
1039 }
1040
1041 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1042 if (ret != 0) {
1043 if (default_value) {
1044 snprintf(output, output_size, "%s", default_value);
1045 } else {
1046 output[0] = '\0';
1047 }
1048 }
1049
1050 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1051 return RETURN_OK;
1052}
1053
1054static int wifi_BandProfileRead2(int card_idx,
1055 int radio_idx,
developer3a85ab82023-05-25 11:59:38 +08001056 int idx,
developerfde01262023-05-22 15:15:24 +08001057 char *param,
1058 char *output,
1059 int output_size,
1060 char* default_value)
1061{
1062 char option[64];
1063 char band_profile_path[64];
1064 int ret;
1065
1066 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1067 if (!param || !output || (output_size <= 0)) {
1068 fprintf(stderr, "%s: invalid parameters", __func__);
1069 return RETURN_ERR;
1070 }
1071
1072 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1073 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1074 if (ret != 0) {
1075 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1076 return RETURN_ERR;
1077 }
1078
developer3a85ab82023-05-25 11:59:38 +08001079 ret = wifi_datfileRead2(band_profile_path, idx, param, output, output_size);
developerfde01262023-05-22 15:15:24 +08001080 if (ret != 0) {
1081 if (default_value) {
1082 snprintf(output, output_size, "%s", default_value);
1083 } else {
1084 output[0] = '\0';
1085 }
1086 }
1087
1088 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1089 return RETURN_OK;
1090
1091}
1092
1093static int wifi_BandProfileWrite(int card_idx, int radio_idx, struct params *list, int item_count)
1094{
1095 char option[64];
1096 char band_profile_path[64];
1097 int ret;
1098
1099 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1100
1101 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1102 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1103 if (ret != 0) {
1104 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1105 return RETURN_ERR;
1106 }
1107
1108 for (int i = 0; i < item_count; i++) {
1109 }
1110 ret = wifi_datfileWrite(band_profile_path, list, item_count);
1111 if (ret != 0) {
1112 fprintf(stderr, "%s: wifi_datfileWrite failed, ret:%d", __func__);
1113 return RETURN_ERR;
1114 }
1115
1116 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1117 return RETURN_OK;
1118
1119}
1120
1121static int wifi_BandProfileWrite2(int card_idx,
1122 int radio_idx,
developer3a85ab82023-05-25 11:59:38 +08001123 int idx,
developerfde01262023-05-22 15:15:24 +08001124 struct params *list,
1125 int item_count)
1126{
1127 char option[64];
1128 char band_profile_path[64];
1129 char buf[64];
1130 char buf2[MAX_BUF_SIZE];
1131 int ret;
1132
1133 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1134
1135 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1136 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1137 if (ret != 0) {
1138 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1139 return RETURN_ERR;
1140 }
1141
developer3a85ab82023-05-25 11:59:38 +08001142 ret = wifi_datfileWrite2(band_profile_path, idx, list, item_count);
developerfde01262023-05-22 15:15:24 +08001143 if (ret != 0) {
1144 fprintf(stderr, "%s: wifi_datfileWrite failed, ret:%d", __func__);
1145 return RETURN_ERR;
1146 }
1147
1148 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1149 return RETURN_OK;
1150
1151}
1152
1153
1154
developer72fb0bb2023-01-11 09:46:29 +08001155//For Getting Current Interface Name from corresponding hostapd configuration
1156static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1157{
1158 char config_file[128] = {0};
1159
1160 if (interface_name == NULL)
1161 return RETURN_ERR;
1162
1163 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1164
1165 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1166 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1167 if (strlen(interface_name) == 0)
1168 return RETURN_ERR;
1169
1170 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1171 return RETURN_OK;
1172}
1173
developera1255e42023-05-13 17:45:02 +08001174static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1175{
1176 char interface_name[IF_NAME_SIZE] = {0};
1177 char cmd[MAX_BUF_SIZE]={'\0'};
1178 char buf[MAX_CMD_SIZE]={'\0'};
1179 UCHAR channel = 0;
1180
1181 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1182 return RETURN_ERR;
1183 /*interface name to channel number*/
1184 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1185 _syscmd(cmd, buf, sizeof(buf));
1186 channel = atoi(buf);
1187 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
1188 /*count dev number with the same channel*/
1189 snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1190 _syscmd(cmd, buf, sizeof(buf));
1191 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1192 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1193 return RETURN_OK;
1194}
developer72fb0bb2023-01-11 09:46:29 +08001195
developerd1824452023-05-18 12:30:04 +08001196/* index: radio index or phy index
1197 phy: true-> base phy command
1198 false-> base radio command */
1199static int wifi_mwctlSet(int index, struct params *mwctl, bool phy)
1200{
1201 char cmd[MAX_CMD_SIZE]={'\0'};
1202 char buf[MAX_BUF_SIZE]={'\0'};
1203 char interface_name[16] = {0};
1204
1205 if (phy == TRUE)
1206 snprintf(cmd, sizeof(cmd), "mwctl phy phy%d set %s%s", index, mwctl->name, mwctl->value);
1207 else {
1208 if (wifi_GetInterfaceName(index, interface_name) != RETURN_OK)
1209 return RETURN_ERR;
1210 snprintf(cmd, sizeof(cmd), "mwctl %s set %s%s", interface_name, mwctl->name, mwctl->value);
1211 }
1212 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1213 return RETURN_ERR;
1214
1215 return RETURN_OK;
1216}
1217
developer72fb0bb2023-01-11 09:46:29 +08001218static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1219{
1220 char interface_name[16] = {0};
1221 if (multiple_set == TRUE)
1222 return RETURN_OK;
1223 char cmd[MAX_CMD_SIZE]="", output[32]="";
1224 FILE *fp;
1225 int i;
1226 //NOTE RELOAD should be done in ApplySSIDSettings
1227 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1228 return RETURN_ERR;
1229 for(i=0; i<item_count; i++, list++)
1230 {
developerf6a87542023-05-16 15:47:28 +08001231 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
developer72fb0bb2023-01-11 09:46:29 +08001232 if((fp = popen(cmd, "r"))==NULL)
1233 {
1234 perror("popen failed");
1235 return -1;
1236 }
1237 if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2))
1238 {
1239 pclose(fp);
1240 perror("fgets failed");
1241 return -1;
1242 }
1243 pclose(fp);
1244 }
1245 return 0;
1246}
1247
developer7e4a2a62023-04-06 19:56:03 +08001248static int wifi_quick_reload_ap(int apIndex)
1249{
1250 char interface_name[IF_NAME_SIZE] = {0};
1251 char cmd[MAX_CMD_SIZE] = {0};
1252 char buf[MAX_BUF_SIZE] = {0};
1253
1254 if (multiple_set == TRUE)
1255 return RETURN_OK;
1256
1257 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1258 return RETURN_ERR;
1259
1260 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1261 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1262 return RETURN_ERR;
1263
1264 return RETURN_OK;
1265}
1266
developer72fb0bb2023-01-11 09:46:29 +08001267static int wifi_reloadAp(int apIndex)
1268{
1269 char interface_name[16] = {0};
1270 if (multiple_set == TRUE)
1271 return RETURN_OK;
1272 char cmd[MAX_CMD_SIZE]="";
1273 char buf[MAX_BUF_SIZE]="";
1274
1275 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1276 return RETURN_ERR;
1277 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1278 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1279 return RETURN_ERR;
1280
1281 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
1282 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1283 return RETURN_ERR;
1284
1285 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
1286 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1287 return RETURN_ERR;
1288
1289 return RETURN_OK;
1290}
1291
1292INT File_Reading(CHAR *file, char *Value)
1293{
1294 FILE *fp = NULL;
1295 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1296 int count = 0;
1297
1298 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1299 fp = popen(file,"r");
1300 if(fp == NULL)
1301 return RETURN_ERR;
1302
1303 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1304 {
1305 for(count=0;buf[count]!='\n';count++)
1306 copy_buf[count]=buf[count];
1307 copy_buf[count]='\0';
1308 }
1309 strcpy(Value,copy_buf);
1310 pclose(fp);
1311 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1312
1313 return RETURN_OK;
1314}
1315
1316void wifi_RestartHostapd_2G()
1317{
1318 int Public2GApIndex = 4;
1319
1320 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1321 wifi_setApEnable(Public2GApIndex, FALSE);
1322 wifi_setApEnable(Public2GApIndex, TRUE);
1323 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1324}
1325
1326void wifi_RestartHostapd_5G()
1327{
1328 int Public5GApIndex = 5;
1329
1330 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1331 wifi_setApEnable(Public5GApIndex, FALSE);
1332 wifi_setApEnable(Public5GApIndex, TRUE);
1333 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1334}
1335
1336void wifi_RestartPrivateWifi_2G()
1337{
1338 int PrivateApIndex = 0;
1339
1340 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1341 wifi_setApEnable(PrivateApIndex, FALSE);
1342 wifi_setApEnable(PrivateApIndex, TRUE);
1343 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1344}
1345
1346void wifi_RestartPrivateWifi_5G()
1347{
1348 int Private5GApIndex = 1;
1349
1350 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1351 wifi_setApEnable(Private5GApIndex, FALSE);
1352 wifi_setApEnable(Private5GApIndex, TRUE);
1353 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1354}
1355
1356static int writeBandWidth(int radioIndex,char *bw_value)
1357{
1358 char buf[MAX_BUF_SIZE];
1359 char cmd[MAX_CMD_SIZE];
1360
1361 snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1362 if(_syscmd(cmd, buf, sizeof(buf)))
1363 {
1364 snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1365 _syscmd(cmd, buf, sizeof(buf));
1366 return RETURN_OK;
1367 }
1368
1369 sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1370 _syscmd(cmd,buf,sizeof(buf));
1371 return RETURN_OK;
1372}
1373
1374static int readBandWidth(int radioIndex,char *bw_value)
1375{
1376 char buf[MAX_BUF_SIZE] = {0};
1377 char cmd[MAX_CMD_SIZE] = {0};
1378 sprintf(cmd,"grep 'SET_BW%d=' %s | sed 's/^.*=//'",radioIndex,BW_FNAME);
1379 _syscmd(cmd,buf,sizeof(buf));
1380 if(NULL!=strstr(buf,"20MHz"))
developer72fb0bb2023-01-11 09:46:29 +08001381 strcpy(bw_value,"20MHz");
developer72fb0bb2023-01-11 09:46:29 +08001382 else if(NULL!=strstr(buf,"40MHz"))
developer72fb0bb2023-01-11 09:46:29 +08001383 strcpy(bw_value,"40MHz");
developer72fb0bb2023-01-11 09:46:29 +08001384 else if(NULL!=strstr(buf,"80MHz"))
developer72fb0bb2023-01-11 09:46:29 +08001385 strcpy(bw_value,"80MHz");
developerd1824452023-05-18 12:30:04 +08001386 else if(NULL!=strstr(buf,"160MHz"))
1387 strcpy(bw_value,"160MHz");
1388 else if(NULL!=strstr(buf,"320MHz"))
1389 strcpy(bw_value,"320MHz");
developer72fb0bb2023-01-11 09:46:29 +08001390 else
developer72fb0bb2023-01-11 09:46:29 +08001391 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001392 return RETURN_OK;
1393}
1394
1395// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1396INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1397{
1398 struct params params={'\0'};
1399 char config_file[MAX_BUF_SIZE] = {0};
1400 char buf[MAX_BUF_SIZE] = {'\0'};
1401
1402 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1403 // Copy the numeric value
1404 if (strlen (beaconRate) >= 5) {
1405 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1406 buf[strlen(beaconRate) - 4] = '\0';
1407 } else if (strlen(beaconRate) > 0)
1408 strcpy(buf, beaconRate);
1409 else
1410 return RETURN_ERR;
1411
1412 params.name = "beacon_rate";
1413 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1414 if (strncmp(buf, "5.5", 3) == 0) {
1415 snprintf(buf, sizeof(buf), "55");
1416 params.value = buf;
1417 } else {
1418 strcat(buf, "0");
1419 params.value = buf;
1420 }
1421
1422 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1423 wifi_hostapdWrite(config_file, &params, 1);
1424 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1425 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1426
1427 return RETURN_OK;
1428}
1429
1430INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1431{
1432 char config_file[128] = {'\0'};
1433 char temp_output[128] = {'\0'};
1434 char buf[128] = {'\0'};
1435 char cmd[128] = {'\0'};
1436 int rate = 0;
1437 int phyId = 0;
1438
1439 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1440 if (NULL == beaconRate)
1441 return RETURN_ERR;
1442
1443 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1444 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1445 phyId = radio_index_to_phy(radioIndex);
1446 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1447 if(strlen(buf) > 0) {
1448 if (strncmp(buf, "55", 2) == 0)
1449 snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
1450 else {
1451 rate = strtol(buf, NULL, 10)/10;
1452 snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
1453 }
1454 } else {
1455 // config not set, so we would use lowest rate as default
1456 sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1457 _syscmd(cmd, buf, sizeof(buf));
1458 snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
1459 }
1460 strncpy(beaconRate, temp_output, sizeof(temp_output));
1461 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1462
1463 return RETURN_OK;
1464}
1465
1466INT wifi_setLED(INT radioIndex, BOOL enable)
1467{
1468 return 0;
1469}
1470INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
1471{
1472 return RETURN_OK;
1473}
1474/**********************************************************************************
1475 *
developer69b61b02023-03-07 17:17:44 +08001476 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001477 *
1478**********************************************************************************/
1479//---------------------------------------------------------------------------------------------------
1480//Wifi system api
1481//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 +08001482INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001483{
1484 if(!output_string)
1485 return RETURN_ERR;
1486 snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1487
1488 return RETURN_OK;
1489}
1490
1491
1492/* wifi_factoryReset() function */
1493/**
developer69b61b02023-03-07 17:17:44 +08001494* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001495* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1496*
1497* @param None
1498*
1499* @return The status of the operation.
1500* @retval RETURN_OK if successful.
1501* @retval RETURN_ERR if any error is detected
1502*
1503* @execution Synchronous
1504* @sideeffect None
1505*
1506* @note This function must not suspend and must not invoke any blocking system
1507* calls. It should probably just send a message to a driver event handler task.
1508*
1509*/
1510INT wifi_factoryReset()
1511{
developer47cc27a2023-05-17 23:09:58 +08001512 char cmd[MAX_CMD_SIZE] = {0};
1513 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08001514
developer47cc27a2023-05-17 23:09:58 +08001515 /*delete running hostapd conf files*/
1516 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
1517 snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1518 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001519
developer47cc27a2023-05-17 23:09:58 +08001520 wifi_PrepareDefaultHostapdConfigs();
1521 wifi_psk_file_reset();
1522
1523 memset(cmd, 0, MAX_CMD_SIZE);
1524 memset(buf, 0, MAX_BUF_SIZE);
1525
1526 snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1527 _syscmd(cmd, buf, sizeof(buf));
1528
1529 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001530}
1531
1532/* wifi_factoryResetRadios() function */
1533/**
1534* @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.
1535*
1536* @param None
1537* @return The status of the operation
1538* @retval RETURN_OK if successful
1539* @retval RETURN_ERR if any error is detected
1540*
1541* @execution Synchronous
1542*
1543* @sideeffect None
1544*
1545* @note This function must not suspend and must not invoke any blocking system
1546* calls. It should probably just send a message to a driver event handler task.
1547*
1548*/
1549INT wifi_factoryResetRadios()
1550{
1551 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1552 return RETURN_OK;
1553
1554 return RETURN_ERR;
1555}
1556
1557
1558/* wifi_factoryResetRadio() function */
1559/**
1560* @description Restore selected radio parameters without touching access point parameters
1561*
1562* @param radioIndex - Index of Wi-Fi Radio channel
1563*
1564* @return The status of the operation.
1565* @retval RETURN_OK if successful.
1566* @retval RETURN_ERR if any error is detected
1567*
1568* @execution Synchronous.
1569* @sideeffect None.
1570*
1571* @note This function must not suspend and must not invoke any blocking system
1572* calls. It should probably just send a message to a driver event handler task.
1573*
1574*/
1575INT wifi_factoryResetRadio(int radioIndex) //RDKB
1576{
developer47cc27a2023-05-17 23:09:58 +08001577 char cmd[MAX_CMD_SIZE] = {0};
1578 char buf[MAX_BUF_SIZE] = {0};
1579 char vap_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08001580
developer47cc27a2023-05-17 23:09:58 +08001581 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001582
developerb2977562023-05-24 17:54:12 +08001583 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001584
developerb2977562023-05-24 17:54:12 +08001585 /*reset gi setting*/
1586 snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001587 _syscmd(cmd, buf, sizeof(buf));
1588
developerb2977562023-05-24 17:54:12 +08001589 /*TBD: check mbss issue*/
1590 wifi_factoryResetAP(radioIndex);
1591
developer47cc27a2023-05-17 23:09:58 +08001592 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1593 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001594}
1595
1596/* wifi_initRadio() function */
1597/**
1598* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001599* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001600* different hardware implementations may have different initilization requirements.
1601* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1602*
1603* @return The status of the operation.
1604* @retval RETURN_OK if successful.
1605* @retval RETURN_ERR if any error is detected
1606*
1607* @execution Synchronous.
1608* @sideeffect None.
1609*
1610* @note This function must not suspend and must not invoke any blocking system
1611* calls. It should probably just send a message to a driver event handler task.
1612*
1613*/
1614INT wifi_initRadio(INT radioIndex)
1615{
1616 //TODO: Initializes the wifi subsystem (for specified radio)
1617 return RETURN_OK;
1618}
1619void macfilter_init()
1620{
1621 char count[4]={'\0'};
1622 char buf[253]={'\0'};
1623 char tmp[19]={'\0'};
1624 int dev_count,block,mac_entry=0;
1625 char res[4]={'\0'};
1626 char acl_file_path[64] = {'\0'};
1627 FILE *fp = NULL;
1628 int index=0;
1629 char iface[10]={'\0'};
1630 char config_file[MAX_BUF_SIZE] = {0};
1631
1632
1633 sprintf(acl_file_path,"/tmp/mac_filter.sh");
1634
1635 fp=fopen(acl_file_path,"w+");
1636 if (fp == NULL) {
1637 fprintf(stderr, "%s: failed to open file %s.\n", __func__, acl_file_path);
developer17038e62023-03-02 14:43:43 +08001638 return;
developer72fb0bb2023-01-11 09:46:29 +08001639 }
1640 sprintf(buf,"#!/bin/sh \n");
1641 fprintf(fp,"%s\n",buf);
1642
1643 system("chmod 0777 /tmp/mac_filter.sh");
1644
1645 for(index=0;index<=1;index++)
1646 {
1647 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index);
1648 wifi_hostapdRead(config_file, "interface", iface, sizeof(iface));
1649 sprintf(buf,"syscfg get %dcountfilter",index);
1650 _syscmd(buf,count,sizeof(count));
1651 mac_entry=atoi(count);
1652
1653 sprintf(buf,"syscfg get %dblockall",index);
1654 _syscmd(buf,res,sizeof(res));
1655 block = atoi(res);
1656
1657 //Allow only those macs mentioned in ACL
1658 if(block==1)
1659 {
1660 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1661 fprintf(fp,"%s\n",buf);
1662 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1663 {
1664 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1665 _syscmd(buf,tmp,sizeof(tmp));
1666 fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp);
1667 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp);
1668 fprintf(fp,"%s\n",buf);
1669 }
1670 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp);
1671 fprintf(fp,"%s\n",buf);
1672 }
1673
1674 //Block all the macs mentioned in ACL
1675 else if(block==2)
1676 {
1677 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1678 fprintf(fp,"%s\n",buf);
1679
1680 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1681 {
1682 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1683 _syscmd(buf,tmp,sizeof(tmp));
1684 fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp);
1685 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp);
1686 fprintf(fp,"%s\n",buf);
1687 }
1688 }
1689 }
1690 fclose(fp);
1691}
1692
developer17038e62023-03-02 14:43:43 +08001693
1694static void
1695wifi_ParseProfile(void)
1696{
1697 int i;
1698 int max_radio_num = 0;
1699 int card_idx;
1700 int band_idx;
1701 int phy_idx = 0;
developer745f0bd2023-03-06 14:32:53 +08001702 int wireless_mode = 0;
developer17038e62023-03-02 14:43:43 +08001703 char buf[MAX_BUF_SIZE] = {0};
1704 char chip_name[12];
1705 char card_profile[MAX_BUF_SIZE] = {0};
1706 char band_profile[MAX_BUF_SIZE] = {0};
1707 FILE* fp;
1708
1709 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1710
1711 memset(main_prefix, 0, sizeof(main_prefix));
1712 memset(ext_prefix, 0, sizeof(ext_prefix));
1713 memset(default_ssid, 0, sizeof(default_ssid));
developer745f0bd2023-03-06 14:32:53 +08001714 for (i = 0; i < MAX_NUM_RADIOS; i++)
1715 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001716
1717 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1718 /* LOG */
1719 return;
1720 }
1721
1722 for (card_idx = 0; card_idx < 3; card_idx++) {
1723 snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1724 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1725 break;
1726 }
1727 snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1728 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1729 break;
1730 }
1731 for (band_idx = 0; band_idx < 3; band_idx++) {
1732 snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1733 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1734 /* LOG */
1735 break;
1736 }
1737
1738 snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1739 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1740 /* LOG */
1741 }
1742
1743 snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1744 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1745 /* LOG */
1746 }
1747
1748 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1749 /* LOG */
1750 }
developer745f0bd2023-03-06 14:32:53 +08001751 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1752 /* LOG */
1753 }
1754
1755 wireless_mode = atoi(buf);
1756 switch (wireless_mode) {
1757 case 22:
1758 case 16:
1759 case 6:
1760 case 4:
1761 case 1:
1762 radio_band[phy_idx] = band_2_4;
1763 break;
1764 case 23:
1765 case 17:
1766 case 14:
1767 case 11:
1768 case 2:
1769 radio_band[phy_idx] = band_5;
1770 break;
1771 case 24:
1772 case 18:
1773 radio_band[phy_idx] = band_6;
1774 break;
1775 }
developer17038e62023-03-02 14:43:43 +08001776 phy_idx++;
1777 }
1778 }
1779
1780 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1781}
1782
1783static void
1784wifi_PrepareDefaultHostapdConfigs(void)
1785{
developer0132ed92023-03-21 13:48:53 +08001786 int radio_idx;
1787 int bss_idx;
1788 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001789 char buf[MAX_BUF_SIZE] = {0};
1790 char config_file[MAX_BUF_SIZE] = {0};
1791 char ssid[MAX_BUF_SIZE] = {0};
1792 char interface[32] = {0};
1793 char ret_buf[MAX_BUF_SIZE] = {0};
1794 char psk_file[64] = {0};
1795 struct params params[3];
developer47cc27a2023-05-17 23:09:58 +08001796 char *band_str[3] = {"2G", "5G", "6G"};
developer17038e62023-03-02 14:43:43 +08001797
developer0132ed92023-03-21 13:48:53 +08001798 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1799 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001800
developer0132ed92023-03-21 13:48:53 +08001801 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001802 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001803
developer47cc27a2023-05-17 23:09:58 +08001804 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
developere740c2a2023-05-23 18:34:32 +08001805 snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
developer47cc27a2023-05-17 23:09:58 +08001806 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001807
developer47cc27a2023-05-17 23:09:58 +08001808 if (radio_idx == band_2_4) {
1809 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1810 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1811 } else if (radio_idx == band_5) {
1812 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1813 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1814 } else if (radio_idx == band_6) {
1815 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1816 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1817 }
developer17038e62023-03-02 14:43:43 +08001818
developer47cc27a2023-05-17 23:09:58 +08001819 /* fix wpa_psk_file path */
1820 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
developer17038e62023-03-02 14:43:43 +08001821
developer47cc27a2023-05-17 23:09:58 +08001822 params[0].name = "ssid";
1823 params[0].value = ssid;
1824 params[1].name = "interface";
1825 params[1].value = interface;
1826 params[2].name = "wpa_psk_file";
1827 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001828
developer47cc27a2023-05-17 23:09:58 +08001829 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001830 }
1831 }
1832 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001833}
1834
1835static void
1836wifiBringUpInterfacesForRadio(int radio_idx)
1837{
developer0132ed92023-03-21 13:48:53 +08001838 int bss_idx;
1839 int ap_idx;
1840 int band_idx;
1841 char cmd[MAX_CMD_SIZE] = {0};
1842 char config_file[MAX_BUF_SIZE] = {0};
1843 char ret_buf[MAX_BUF_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08001844 char inf_name[IF_NAME_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001845
1846 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer8a3bbbf2023-03-15 17:47:23 +08001847
developered997d32023-04-18 22:45:39 +08001848 bss_idx = 0;
1849 /*TBD: we need refine setup flow and mbss flow*/
1850// for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer0132ed92023-03-21 13:48:53 +08001851 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
1852
1853 snprintf(cmd, sizeof(cmd), "touch %s%d.psk", PSK_FILE, ap_idx);
1854 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1855
1856 memset(cmd, 0, MAX_CMD_SIZE);
1857 memset(ret_buf, 0, MAX_BUF_SIZE);
developer17038e62023-03-02 14:43:43 +08001858
developer0132ed92023-03-21 13:48:53 +08001859 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1860 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radio_idx, config_file);
1861 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer8a3bbbf2023-03-15 17:47:23 +08001862
1863 wifi_GetInterfaceName(ap_idx, inf_name);
1864
1865 memset(cmd, 0, MAX_CMD_SIZE);
1866 memset(ret_buf, 0, MAX_BUF_SIZE);
1867
1868 /* fix vap-status file */
1869 snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=1/\" %s", inf_name, inf_name, VAP_STATUS_FILE);
1870 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developered997d32023-04-18 22:45:39 +08001871// }
1872
1873 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001874}
1875
1876static void
1877wifi_BringUpInterfaces(void)
1878{
1879 int radio_idx;
1880 int bss_idx;
1881 int ap_idx;
1882 int band_idx;
1883 char cmd[MAX_BUF_SIZE] = {0};
1884 char config_file[MAX_BUF_SIZE] = {0};
1885 char ret_buf[MAX_BUF_SIZE]={'\0'};
1886
1887 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1888 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1889 band_idx = radio_index_to_band(radio_idx);
1890 if (band_idx < 0) {
1891 break;
1892 }
1893 wifiBringUpInterfacesForRadio(radio_idx);
1894 }
1895 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1896}
1897
1898static void
1899wifi_BringDownInterfacesForRadio(int radio_idx)
1900{
1901 int bss_idx;
1902 int ap_idx;
1903 int band_idx;
1904 char cmd[MAX_BUF_SIZE] = {0};
1905 char config_file[MAX_BUF_SIZE] = {0};
1906 char ret_buf[MAX_BUF_SIZE]={'\0'};
1907
1908 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001909
developer8a3bbbf2023-03-15 17:47:23 +08001910 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1911 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1912
1913
developer17038e62023-03-02 14:43:43 +08001914 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1915}
1916
1917
1918static void
1919wifi_BringDownInterfaces(void)
1920{
1921 int radio_idx;
1922 int bss_idx;
1923 int ap_idx;
1924 int band_idx;
1925 char cmd[MAX_BUF_SIZE] = {0};
1926 char config_file[MAX_BUF_SIZE] = {0};
1927 char ret_buf[MAX_BUF_SIZE]={'\0'};
1928
1929 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1930 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1931 band_idx = radio_index_to_band(radio_idx);
1932 if (band_idx < 0) {
1933 break;
1934 }
1935 wifi_BringDownInterfacesForRadio(radio_idx);
1936 }
1937 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1938}
1939
developerb2977562023-05-24 17:54:12 +08001940static void wifi_dat_file_reset()
1941{
1942 char radio_idx = 0;
1943
1944 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
1945 wifi_dat_file_reset_by_radio(radio_idx);
1946}
1947
1948static void wifi_dat_file_reset_by_radio(char radio_idx)
1949{
1950 char cmd[MAX_CMD_SIZE] = {0};
1951 char ret_buf[MAX_BUF_SIZE] = {0};
1952 char rom_dat_file[MAX_CMD_SIZE]= {0};
1953 char dat_file[MAX_CMD_SIZE]= {0};
1954
1955 snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1956 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
1957 snprintf(cmd, MAX_CMD_SIZE, "cp -rf %s %s", rom_dat_file, dat_file);
1958 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1959
1960}
1961
developer47cc27a2023-05-17 23:09:58 +08001962static void wifi_psk_file_reset()
1963{
1964 char cmd[MAX_CMD_SIZE] = {0};
1965 char ret_buf[MAX_BUF_SIZE] = {0};
1966 char psk_file[MAX_CMD_SIZE]= {0};
1967 char vap_idx = 0;
1968
1969 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
1970 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1971
1972 if (access(psk_file, F_OK) != 0) {
1973 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1974 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1975 } else {
1976 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1977 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1978 }
1979 }
1980}
1981
developerb2977562023-05-24 17:54:12 +08001982static void wifi_psk_file_reset_by_radio(char radio_idx)
1983{
1984 char cmd[MAX_CMD_SIZE] = {0};
1985 char ret_buf[MAX_BUF_SIZE] = {0};
1986 char psk_file[MAX_CMD_SIZE]= {0};
1987 char vap_idx = 0;
1988
1989 for (vap_idx = radio_idx; vap_idx < MAX_APS; vap_idx += MAX_NUM_RADIOS) {
1990 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1991
1992 if (access(psk_file, F_OK) != 0) {
1993 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1994 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1995 } else {
1996 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1997 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1998 }
1999 }
2000
2001}
2002
2003
developer8a3bbbf2023-03-15 17:47:23 +08002004static void wifi_vap_status_reset()
2005{
2006 char cmd[MAX_CMD_SIZE] = {0};
2007 char ret_buf[MAX_BUF_SIZE] = {0};
2008 char radio_idx = 0;
2009 char bss_idx = 0;
developer8666b312023-03-24 14:05:31 +08002010
developer8a3bbbf2023-03-15 17:47:23 +08002011 if (access(VAP_STATUS_FILE, F_OK) != 0) {
2012 snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
2013 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2014 } else {
2015 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
2016 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2017 }
2018
2019 memset(cmd, 0, MAX_CMD_SIZE);
2020 memset(ret_buf, 0, MAX_BUF_SIZE);
2021
2022 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
2023 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
2024 snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
2025 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2026 }
2027
2028}
developer17038e62023-03-02 14:43:43 +08002029
developer72fb0bb2023-01-11 09:46:29 +08002030// Initializes the wifi subsystem (all radios)
2031INT wifi_init() //RDKB
2032{
developer96b38512023-02-22 11:17:45 +08002033 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2034 //Not intitializing macfilter for Turris-Omnia Platform for now
2035 //macfilter_init();
developer17038e62023-03-02 14:43:43 +08002036 wifi_ParseProfile();
2037 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08002038 wifi_psk_file_reset();
developer17038e62023-03-02 14:43:43 +08002039 //system("/usr/sbin/iw reg set US");
2040 system("systemctl start hostapd.service");
2041 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002042
2043 wifi_vap_status_reset();
2044
developer96b38512023-02-22 11:17:45 +08002045
2046 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002047
2048 return RETURN_OK;
2049}
2050
2051/* wifi_reset() function */
2052/**
2053* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08002054* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08002055* different hardware implementations may have different requirements.
2056* Parameters : None
2057*
2058* @return The status of the operation.
2059* @retval RETURN_OK if successful.
2060* @retval RETURN_ERR if any error is detected
2061*
2062* @execution Synchronous.
2063* @sideeffect None.
2064*
2065* @note This function must not suspend and must not invoke any blocking system
2066* calls. It should probably just send a message to a driver event handler task.
2067*
2068*/
2069INT wifi_reset()
2070{
developer17038e62023-03-02 14:43:43 +08002071
2072 wifi_BringDownInterfaces();
2073 sleep(2);
2074
developer96b38512023-02-22 11:17:45 +08002075 //TODO: resets the wifi subsystem, deletes all APs
2076 system("systemctl stop hostapd.service");
2077 sleep(2);
developer17038e62023-03-02 14:43:43 +08002078
developer96b38512023-02-22 11:17:45 +08002079 system("systemctl start hostapd.service");
2080 sleep(5);
developer17038e62023-03-02 14:43:43 +08002081
2082 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08002083 wifi_psk_file_reset();
developer17038e62023-03-02 14:43:43 +08002084 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002085
2086 wifi_vap_status_reset();
2087
developer72fb0bb2023-01-11 09:46:29 +08002088 return RETURN_OK;
2089}
2090
2091/* wifi_down() function */
2092/**
2093* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08002094* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08002095* different hardware implementations may have different requirements.
2096*
2097* @param None
2098*
2099* @return The status of the operation
2100* @retval RETURN_OK if successful
2101* @retval RETURN_ERR if any error is detected
2102*
2103* @execution Synchronous
2104* @sideeffect None
2105*
2106* @note This function must not suspend and must not invoke any blocking system
2107* calls. It should probably just send a message to a driver event handler task.
2108*
2109*/
2110INT wifi_down()
2111{
developer96b38512023-02-22 11:17:45 +08002112 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
developerb2977562023-05-24 17:54:12 +08002113 int max_num_radios = 0;
2114 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08002115
developerb2977562023-05-24 17:54:12 +08002116 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
2117 wifi_setRadioEnable(radioIndex, FALSE);
2118
developer72fb0bb2023-01-11 09:46:29 +08002119 return RETURN_OK;
2120}
2121
2122
2123/* wifi_createInitialConfigFiles() function */
2124/**
2125* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08002126* and content of these files are implementation dependent. This function call is
2127* used to trigger this task if necessary. Some implementations may not need this
2128* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08002129* do nothing and return RETURN_OK.
2130*
2131* @param None
2132*
2133* @return The status of the operation
2134* @retval RETURN_OK if successful
2135* @retval RETURN_ERR if any error is detected
2136*
2137* @execution Synchronous
2138* @sideeffect None
2139*
2140* @note This function must not suspend and must not invoke any blocking system
2141* calls. It should probably just send a message to a driver event handler task.
2142*
2143*/
2144INT wifi_createInitialConfigFiles()
2145{
2146 //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)
2147 return RETURN_OK;
2148}
2149
developer7e4a2a62023-04-06 19:56:03 +08002150/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08002151INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
2152{
developerfde01262023-05-22 15:15:24 +08002153 int ret;
developer72fb0bb2023-01-11 09:46:29 +08002154
developerfde01262023-05-22 15:15:24 +08002155 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002156
developerfde01262023-05-22 15:15:24 +08002157 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
2158 if (ret != 0) {
2159 fprintf(stderr, "%s: wifi_BandProfileRead CountryCode failed\n", __func__);
2160 return RETURN_ERR;
2161 }
developer7e4a2a62023-04-06 19:56:03 +08002162
developerfde01262023-05-22 15:15:24 +08002163 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002164
developerfde01262023-05-22 15:15:24 +08002165 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002166}
2167
2168INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
2169{
developer7e4a2a62023-04-06 19:56:03 +08002170 /*Set wifi config. Wait for wifi reset to apply*/
2171 char str[MAX_BUF_SIZE] = {0};
2172 char cmd[MAX_CMD_SIZE] = {0};
2173 struct params params;
2174 char config_file[MAX_BUF_SIZE] = {0};
2175 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08002176
developer7e4a2a62023-04-06 19:56:03 +08002177 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002178
developer7e4a2a62023-04-06 19:56:03 +08002179 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
2180 printf("%s: input para error!!!\n", __func__);
2181 return RETURN_ERR;
2182 }
developer72fb0bb2023-01-11 09:46:29 +08002183
developer7e4a2a62023-04-06 19:56:03 +08002184 if (!strlen(CountryCode))
2185 strncpy(CountryCode, "US", sizeof("US")); /*default set the code to US*/
developer72fb0bb2023-01-11 09:46:29 +08002186
developer7e4a2a62023-04-06 19:56:03 +08002187 params.name = "country_code";
2188 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08002189
developer7e4a2a62023-04-06 19:56:03 +08002190 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2191 ret = wifi_hostapdWrite(config_file, &params, 1);
2192
2193 if (ret) {
2194 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
2195 __func__, ret);
2196 }
2197
2198 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2199
2200 if (ret) {
2201 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
2202 __func__, ret);
2203 }
2204
2205 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2206
2207 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002208}
2209
2210INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
2211{
2212 char interface_name[16] = {0};
2213 char channel_util_file[64] = {0};
2214 char cmd[128] = {0};
2215 char buf[128] = {0};
2216 char line[128] = {0};
2217 char *param = NULL, *value = NULL;
2218 int read = 0;
2219 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
2220 unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
2221 size_t len = 0;
2222 FILE *f = NULL;
2223
2224 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2225
2226 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2227 return RETURN_ERR;
2228 snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
2229 _syscmd(cmd, buf, sizeof(buf));
2230 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
2231
2232 memset(cmd, 0, sizeof(cmd));
2233 memset(buf, 0, sizeof(buf));
2234 snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
2235 if ((f = popen(cmd, "r")) == NULL) {
2236 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
2237 return RETURN_ERR;
2238 }
2239
2240 read = getline(&line, &len, f);
2241 while (read != -1) {
2242 param = strtok(line, ":\t");
2243 value = strtok(NULL, " ");
2244 if(strstr(param, "frequency") != NULL) {
2245 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
2246 }
2247 if(strstr(param, "noise") != NULL) {
2248 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
2249 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
2250 }
2251 if(strstr(param, "channel active time") != NULL) {
2252 ActiveTime = strtol(value, NULL, 10);
2253 }
2254 if(strstr(param, "channel busy time") != NULL) {
2255 BusyTime = strtol(value, NULL, 10);
2256 }
2257 if(strstr(param, "channel transmit time") != NULL) {
2258 TransmitTime = strtol(value, NULL, 10);
2259 }
2260 read = getline(&line, &len, f);
2261 }
2262 pclose(f);
2263
2264 // The file should store the last active, busy and transmit time
2265 snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2266 f = fopen(channel_util_file, "r");
2267 if (f != NULL) {
2268 read = getline(&line, &len, f);
2269 preActiveTime = strtol(line, NULL, 10);
2270 read = getline(&line, &len, f);
2271 preBusyTime = strtol(line, NULL, 10);
2272 read = getline(&line, &len, f);
2273 preTransmitTime = strtol(line, NULL, 10);
2274 fclose(f);
2275 }
2276
2277 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2278 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
2279
2280 f = fopen(channel_util_file, "w");
2281 if (f != NULL) {
2282 fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime);
2283 fclose(f);
2284 }
2285 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2286 return RETURN_OK;
2287}
2288
2289/**********************************************************************************
2290 *
2291 * Wifi radio level function prototypes
2292 *
2293**********************************************************************************/
2294
2295//Get the total number of radios in this wifi subsystem
2296INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2297{
2298 if (NULL == output)
2299 return RETURN_ERR;
2300 *output = MAX_NUM_RADIOS;
2301
2302 return RETURN_OK;
2303}
2304
developer69b61b02023-03-07 17:17:44 +08002305//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002306INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2307{
2308 if (NULL == output)
2309 return RETURN_ERR;
2310 *output = MAX_APS;
2311
2312 return RETURN_OK;
2313}
2314
2315//Get the Radio enable config parameter
2316INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
2317{
developer3a85ab82023-05-25 11:59:38 +08002318 char option[64] = {};
developer72fb0bb2023-01-11 09:46:29 +08002319 char buf[128] = {0}, cmd[128] = {0};
developer3a85ab82023-05-25 11:59:38 +08002320 int ret;
2321
2322 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002323
2324 if (NULL == output_bool)
2325 return RETURN_ERR;
2326
developer3a85ab82023-05-25 11:59:38 +08002327 snprintf(option, sizeof(option), "INDEX%d_main_ifname", 0);
2328 ret = wifi_l1ProfileRead2(option, radioIndex, buf, sizeof(buf));
2329 if ((ret != 0) || (strlen(buf) <= 0)) {
2330 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08002331 return RETURN_ERR;
developer3a85ab82023-05-25 11:59:38 +08002332 }
developer72fb0bb2023-01-11 09:46:29 +08002333
developer3a85ab82023-05-25 11:59:38 +08002334 snprintf(cmd, sizeof(cmd), "iw %s info | grep channel", buf);
2335 _syscmd(cmd, buf, sizeof(buf));
2336 if (strlen(buf) == 0) {
2337 *output_bool = 0;
2338 } else {
2339 *output_bool = 1;
2340 }
developer72fb0bb2023-01-11 09:46:29 +08002341
developer3a85ab82023-05-25 11:59:38 +08002342 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002343 return RETURN_OK;
2344}
2345
developere82c0ca2023-05-10 16:25:35 +08002346typedef long time_t;
2347static time_t radio_up_time[MAX_NUM_RADIOS];
2348
developer72fb0bb2023-01-11 09:46:29 +08002349INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2350{
2351 char interface_name[16] = {0};
2352 char cmd[MAX_CMD_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08002353 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002354 int apIndex, ret;
developer69b61b02023-03-07 17:17:44 +08002355 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +08002356 int phyId = 0;
2357
2358 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2359
2360 phyId = radio_index_to_phy(radioIndex);
2361
2362 wifi_getMaxRadioNumber(&max_radio_num);
2363
developer8a3bbbf2023-03-15 17:47:23 +08002364 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002365
2366 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2367 return RETURN_ERR;
2368
2369 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002370 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002371 if(strncmp(buf, "OK", 2))
2372 fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002373 } else {
developere82c0ca2023-05-10 16:25:35 +08002374 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developer72fb0bb2023-01-11 09:46:29 +08002375 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2376 return RETURN_ERR;
2377
developer8a3bbbf2023-03-15 17:47:23 +08002378 memset(cmd, 0, MAX_CMD_SIZE);
2379 memset(buf, 0, MAX_BUF_SIZE);
2380
developer72fb0bb2023-01-11 09:46:29 +08002381 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2382 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002383
2384 if(*buf == '1') {
2385
2386 memset(cmd, 0, MAX_CMD_SIZE);
2387 memset(buf, 0, MAX_BUF_SIZE);
2388
developer72fb0bb2023-01-11 09:46:29 +08002389 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
2390 phyId, apIndex);
2391 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002392
developer72fb0bb2023-01-11 09:46:29 +08002393 }
2394 }
developere82c0ca2023-05-10 16:25:35 +08002395 time(&radio_up_time[radioIndex]);
developer72fb0bb2023-01-11 09:46:29 +08002396 }
2397
2398 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2399 return RETURN_OK;
2400}
2401
2402//Get the Radio enable status
2403INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2404{
2405 if (NULL == output_bool)
2406 return RETURN_ERR;
2407
2408 return wifi_getRadioEnable(radioIndex, output_bool);
2409}
2410
2411//Get the Radio Interface name from platform, eg "wlan0"
2412INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2413{
2414 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2415 return RETURN_ERR;
2416 return wifi_GetInterfaceName(radioIndex, output_string);
2417}
2418
2419//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2420//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.
2421INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2422{
2423 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2424 // For max bit rate, we should always choose the best MCS
2425 char mode[64] = {0};
2426 char channel_bandwidth_str[64] = {0};
2427 char *tmp = NULL;
2428 UINT mode_map = 0;
2429 UINT num_subcarrier = 0;
2430 UINT code_bits = 0;
2431 float code_rate = 0; // use max code rate
2432 int NSS = 0;
2433 UINT Symbol_duration = 0;
developer69b61b02023-03-07 17:17:44 +08002434 UINT GI_duration = 0;
developer72fb0bb2023-01-11 09:46:29 +08002435 wifi_band band = band_invalid;
2436 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2437 BOOL enable = FALSE;
2438 float bit_rate = 0;
developera1255e42023-05-13 17:45:02 +08002439 int ant_bitmap = 0;
developer72fb0bb2023-01-11 09:46:29 +08002440
2441 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2442 if (NULL == output_string)
2443 return RETURN_ERR;
2444
2445 wifi_getRadioEnable(radioIndex, &enable);
2446 if (enable == FALSE) {
2447 snprintf(output_string, 64, "0 Mb/s");
2448 return RETURN_OK;
2449 }
2450
2451 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
2452 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
2453 return RETURN_ERR;
2454 }
2455
2456 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
2457 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
2458 return RETURN_ERR;
2459 }
2460
2461 if (gi == wifi_guard_interval_3200)
2462 GI_duration = 32;
2463 else if (gi == wifi_guard_interval_1600)
2464 GI_duration = 16;
2465 else if (gi == wifi_guard_interval_800)
2466 GI_duration = 8;
2467 else // auto, 400
2468 GI_duration = 4;
2469
2470 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
2471 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
2472 return RETURN_ERR;
2473 }
2474
2475 if (strstr(channel_bandwidth_str, "80+80") != NULL)
2476 strcpy(channel_bandwidth_str, "160");
2477
2478 if (mode_map & WIFI_MODE_AX) {
2479 if (strstr(channel_bandwidth_str, "160") != NULL)
2480 num_subcarrier = 1960;
2481 else if (strstr(channel_bandwidth_str, "80") != NULL)
2482 num_subcarrier = 980;
2483 else if (strstr(channel_bandwidth_str, "40") != NULL)
2484 num_subcarrier = 468;
2485 else if (strstr(channel_bandwidth_str, "20") != NULL)
2486 num_subcarrier = 234;
2487 code_bits = 10;
2488 code_rate = (float)5/6;
2489 Symbol_duration = 128;
developera1255e42023-05-13 17:45:02 +08002490 GI_duration = 8;/*HE no GI 400ns*/
developer72fb0bb2023-01-11 09:46:29 +08002491 } else if (mode_map & WIFI_MODE_AC) {
2492 if (strstr(channel_bandwidth_str, "160") != NULL)
2493 num_subcarrier = 468;
2494 else if (strstr(channel_bandwidth_str, "80") != NULL)
2495 num_subcarrier = 234;
2496 else if (strstr(channel_bandwidth_str, "40") != NULL)
2497 num_subcarrier = 108;
2498 else if (strstr(channel_bandwidth_str, "20") != NULL)
2499 num_subcarrier = 52;
2500 code_bits = 8;
2501 code_rate = (float)5/6;
2502 Symbol_duration = 32;
2503 } else if (mode_map & WIFI_MODE_N) {
2504 if (strstr(channel_bandwidth_str, "160") != NULL)
2505 num_subcarrier = 468;
2506 else if (strstr(channel_bandwidth_str, "80") != NULL)
2507 num_subcarrier = 234;
2508 else if (strstr(channel_bandwidth_str, "40") != NULL)
2509 num_subcarrier = 108;
2510 else if (strstr(channel_bandwidth_str, "20") != NULL)
2511 num_subcarrier = 52;
2512 code_bits = 6;
2513 code_rate = (float)3/4;
2514 Symbol_duration = 32;
2515 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2516 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
2517 snprintf(output_string, 64, "65 Mb/s");
2518 return RETURN_OK;
2519 } else {
2520 snprintf(output_string, 64, "0 Mb/s");
2521 return RETURN_OK;
2522 }
2523
2524 // Spatial streams
developera1255e42023-05-13 17:45:02 +08002525 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +08002526 fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
2527 return RETURN_ERR;
2528 }
developera1255e42023-05-13 17:45:02 +08002529 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2530 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002531
2532 // multiple 10 is to align duration unit (0.1 us)
2533 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
2534 snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
developera1255e42023-05-13 17:45:02 +08002535 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2536 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
developer72fb0bb2023-01-11 09:46:29 +08002537 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2538
2539 return RETURN_OK;
2540}
2541#if 0
2542INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2543{
2544 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2545 char cmd[64];
2546 char buf[1024];
2547 int apIndex;
2548
developer69b61b02023-03-07 17:17:44 +08002549 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002550 return RETURN_ERR;
2551
2552 apIndex=(radioIndex==0)?0:1;
2553
2554 snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name);
2555 _syscmd(cmd,buf, sizeof(buf));
2556
2557 snprintf(output_string, 64, "%s", buf);
2558 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2559 return RETURN_OK;
2560}
2561#endif
2562
2563
2564//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2565//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.
2566INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2567{
2568 wifi_band band = band_invalid;
2569
2570 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2571 if (NULL == output_string)
2572 return RETURN_ERR;
2573
2574 band = wifi_index_to_band(radioIndex);
2575
2576 memset(output_string, 0, 10);
2577 if (band == band_2_4)
2578 strcpy(output_string, "2.4GHz");
2579 else if (band == band_5)
2580 strcpy(output_string, "5GHz");
2581 else if (band == band_6)
2582 strcpy(output_string, "6GHz");
2583 else
2584 return RETURN_ERR;
2585 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2586
2587 return RETURN_OK;
2588#if 0
2589 char buf[MAX_BUF_SIZE]={'\0'};
2590 char str[MAX_BUF_SIZE]={'\0'};
2591 char cmd[MAX_CMD_SIZE]={'\0'};
2592 char *ch=NULL;
2593 char *ch2=NULL;
2594
2595 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2596 if (NULL == output_string)
2597 return RETURN_ERR;
2598
2599
2600 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2601
2602 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2603 {
2604 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2605 return RETURN_ERR;
2606 }
2607 ch=strchr(buf,'\n');
2608 *ch='\0';
2609 ch=strchr(buf,'=');
2610 if(ch==NULL)
2611 return RETURN_ERR;
2612
2613
2614 ch++;
2615
2616 /* prepend 0 for channel with single digit. for ex, 6 would be 06 */
2617 strcpy(buf,"0");
2618 if(strlen(ch) == 1)
2619 ch=strcat(buf,ch);
2620
2621
2622 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2623
2624 if(_syscmd(cmd,str,64) == RETURN_ERR)
2625 {
2626 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2627 return RETURN_ERR;
2628 }
2629
2630
2631 ch2=strchr(str,'\n');
2632 //replace \n with \0
2633 *ch2='\0';
2634 ch2=strchr(str,'=');
2635 if(ch2==NULL)
2636 {
2637 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2638 return RETURN_ERR;
2639 }
2640 else
2641 wifi_dbg_printf("%s",ch2+1);
2642
2643
2644 ch2++;
2645
2646
2647 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch);
2648
2649 memset(buf,'\0',sizeof(buf));
2650 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2651 {
2652 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2653 return RETURN_ERR;
2654 }
2655 if (strstr(buf,"2.4") != NULL )
2656 strcpy(output_string,"2.4GHz");
2657 else if(strstr(buf,"5.") != NULL )
2658 strcpy(output_string,"5GHz");
2659 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2660
2661 return RETURN_OK;
2662#endif
2663}
2664
2665//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2666//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.
2667INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2668{
2669 wifi_band band = band_invalid;
2670 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2671 if (NULL == output_string)
2672 return RETURN_ERR;
2673 band = wifi_index_to_band(radioIndex);
2674
developer69b61b02023-03-07 17:17:44 +08002675 if (band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08002676 snprintf(output_string, 64, "2.4GHz");
2677 else if (band == band_5)
developer69b61b02023-03-07 17:17:44 +08002678 snprintf(output_string, 64, "5GHz");
developer72fb0bb2023-01-11 09:46:29 +08002679 else if (band == band_6)
2680 snprintf(output_string, 64, "6GHz");
2681
2682 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2683
2684 return RETURN_OK;
2685#if 0
2686 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2687 char buf[MAX_BUF_SIZE]={'\0'};
2688 char str[MAX_BUF_SIZE]={'\0'};
2689 char cmd[MAX_CMD_SIZE]={'\0'};
2690 char *ch=NULL;
2691 char *ch2=NULL;
2692 char ch1[5]="0";
2693
2694 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2695
2696 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2697 {
2698 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2699 return RETURN_ERR;
2700 }
2701
2702 ch=strchr(buf,'\n');
2703 *ch='\0';
2704 ch=strchr(buf,'=');
2705 if(ch==NULL)
2706 return RETURN_ERR;
2707 ch++;
2708
2709 if(strlen(ch)==1)
2710 {
2711 strcat(ch1,ch);
2712
2713 }
2714 else
2715 {
2716 strcpy(ch1,ch);
2717 }
2718
2719
2720
2721 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2722 if(_syscmd(cmd,str,64) == RETURN_ERR)
2723 {
2724 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2725 return RETURN_ERR;
2726 }
2727
2728
2729 ch2=strchr(str,'\n');
2730 //replace \n with \0
2731 *ch2='\0';
2732 ch2=strchr(str,'=');
2733 if(ch2==NULL)
2734 {
2735 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2736 return RETURN_ERR;
2737 }
2738 else
2739 wifi_dbg_printf("%s",ch2+1);
2740 ch2++;
2741
2742
2743 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1);
2744 memset(buf,'\0',sizeof(buf));
2745 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2746 {
2747 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2748 return RETURN_ERR;
2749 }
2750
2751
2752 if(strstr(buf,"2.4")!=NULL)
2753 {
2754 strcpy(output_string,"2.4GHz");
2755 }
2756 if(strstr(buf,"5.")!=NULL)
2757 {
2758 strcpy(output_string,"5GHz");
2759 }
2760 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2761 return RETURN_OK;
2762#endif
2763}
2764
2765//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2766//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.
2767INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2768{
2769 char cmd[128]={0};
2770 char buf[128]={0};
2771 char temp_output[128] = {0};
2772 wifi_band band;
2773 int phyId = 0;
2774
2775 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08002776 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002777 return RETURN_ERR;
2778
2779 band = wifi_index_to_band(radioIndex);
2780 if (band == band_2_4) {
2781 strcat(temp_output, "b,g,");
2782 } else if (band == band_5) {
2783 strcat(temp_output, "a,");
2784 }
2785 phyId = radio_index_to_phy(radioIndex);
2786 // ht capabilities
2787 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);
2788 _syscmd(cmd, buf, sizeof(buf));
2789 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
2790 strcat(temp_output, "n,");
2791 }
2792
2793 // vht capabilities
2794 if (band == band_5) {
2795 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2796 _syscmd(cmd, buf, sizeof(buf));
2797 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
2798 strcat(temp_output, "ac,");
2799 }
2800 }
2801
2802 // he capabilities
2803 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);
2804 _syscmd(cmd, buf, sizeof(buf));
2805 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2806 strcat(temp_output, "ax,");
2807 }
2808
developere82c0ca2023-05-10 16:25:35 +08002809 // eht capabilities
2810 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);
2811 _syscmd(cmd, buf, sizeof(buf));
2812 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2813 strcat(temp_output, "be,");
2814 }
2815
developer72fb0bb2023-01-11 09:46:29 +08002816 // Remove the last comma
2817 if (strlen(temp_output) != 0)
2818 temp_output[strlen(temp_output)-1] = '\0';
2819 strncpy(output_string, temp_output, strlen(temp_output));
2820 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2821 return RETURN_OK;
2822}
2823
2824//Get the radio operating mode, and pure mode flag. eg: "ac"
2825//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.
2826INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
2827{
2828 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2829 if (NULL == output_string)
2830 return RETURN_ERR;
2831
2832 if (radioIndex == 0) {
2833 snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
2834 *gOnly = FALSE;
2835 *nOnly = TRUE;
2836 *acOnly = FALSE;
2837 } else {
2838 snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
2839 *gOnly = FALSE;
2840 *nOnly = FALSE;
2841 *acOnly = FALSE;
2842 }
2843 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2844
2845 return RETURN_OK;
2846#if 0
2847 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2848 char buf[64] = {0};
2849 char config_file[MAX_BUF_SIZE] = {0};
2850
developer69b61b02023-03-07 17:17:44 +08002851 if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly))
developer72fb0bb2023-01-11 09:46:29 +08002852 return RETURN_ERR;
2853
2854 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2855 wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf));
2856
2857 wifi_dbg_printf("\nhw_mode=%s\n",buf);
developer69b61b02023-03-07 17:17:44 +08002858 if (strlen(buf) == 0)
developer72fb0bb2023-01-11 09:46:29 +08002859 {
2860 wifi_dbg_printf("\nwifi_hostapdRead returned none\n");
2861 return RETURN_ERR;
2862 }
2863 if(strcmp(buf,"g")==0)
2864 {
2865 wifi_dbg_printf("\nG\n");
2866 *gOnly=TRUE;
2867 *nOnly=FALSE;
2868 *acOnly=FALSE;
2869 }
2870 else if(strcmp(buf,"n")==0)
2871 {
2872 wifi_dbg_printf("\nN\n");
2873 *gOnly=FALSE;
2874 *nOnly=TRUE;
2875 *acOnly=FALSE;
2876 }
2877 else if(strcmp(buf,"ac")==0)
2878 {
2879 wifi_dbg_printf("\nac\n");
2880 *gOnly=FALSE;
2881 *nOnly=FALSE;
2882 *acOnly=TRUE;
2883 }
2884 /* hostapd-5G.conf has "a" as hw_mode */
2885 else if(strcmp(buf,"a")==0)
2886 {
2887 wifi_dbg_printf("\na\n");
2888 *gOnly=FALSE;
2889 *nOnly=FALSE;
2890 *acOnly=FALSE;
2891 }
2892 else
2893 wifi_dbg_printf("\nInvalid Mode %s\n", buf);
2894
2895 //for a,n mode
2896 if(radioIndex == 1)
2897 {
2898 wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf));
2899 if(strcmp(buf,"1")==0)
2900 {
2901 strncpy(output_string, "n", 1);
2902 *nOnly=FALSE;
2903 }
2904 }
2905
2906 wifi_dbg_printf("\nReturning from getRadioStandard\n");
2907 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2908 return RETURN_OK;
2909#endif
2910}
2911
developer0f10c772023-05-16 21:43:39 +08002912enum WIFI_MODE {
2913 WMODE_INVALID = 0,
2914 WMODE_A = 1 << 0,
2915 WMODE_B = 1 << 1,
2916 WMODE_G = 1 << 2,
2917 WMODE_GN = 1 << 3,
2918 WMODE_AN = 1 << 4,
2919 WMODE_AC = 1 << 5,
2920 WMODE_AX_24G = 1 << 6,
2921 WMODE_AX_5G = 1 << 7,
2922 WMODE_AX_6G = 1 << 8,
2923 WMODE_BE_24G = 1 << 9,
2924 WMODE_BE_5G = 1 << 10,
2925 WMODE_BE_6G = 1 << 11,
2926 /*
2927 * total types of supported wireless mode,
2928 * add this value once yow add new type
2929 */
2930 WMODE_COMP = 12,
2931};
2932
2933#define RADIO_MODE_LEN 32
developer72fb0bb2023-01-11 09:46:29 +08002934INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
2935{
developer0f10c772023-05-16 21:43:39 +08002936 char cmd[MAX_CMD_SIZE] = {0};
2937 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002938 wifi_band band;
developer0f10c772023-05-16 21:43:39 +08002939 unsigned int phymode;
2940 unsigned char radio_mode_tem_len;
2941 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002942
2943 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2944 if(NULL == output_string || NULL == pureMode)
2945 return RETURN_ERR;
2946
developer0f10c772023-05-16 21:43:39 +08002947 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2948 return RETURN_ERR;
2949
2950 snprintf(cmd, sizeof(cmd), "mwctl %s dump radio_info | grep 'phymode' | cut -d ' ' -f2", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08002951 _syscmd(cmd, buf, sizeof(buf));
2952
developer0f10c772023-05-16 21:43:39 +08002953 phymode = strtoul(buf, NULL, 10);
2954 band = wifi_index_to_band(radioIndex);
2955
2956 // puremode is a bit map
developer72fb0bb2023-01-11 09:46:29 +08002957 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08002958 memset(output_string, 0, RADIO_MODE_LEN);
2959
2960 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2961
2962 switch (band) {
2963 case band_2_4:
2964 if (phymode & WMODE_B) {
2965 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
2966 *pureMode |= WIFI_MODE_B;
2967 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2968 }
2969 if (phymode & WMODE_G) {
2970 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
2971 *pureMode |= WIFI_MODE_G;
2972 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2973 }
2974 if (phymode & WMODE_GN) {
2975 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2976 *pureMode |= WIFI_MODE_N;
2977 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2978 }
2979 if (phymode & WMODE_AX_24G) {
2980 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2981 *pureMode |= WIFI_MODE_AX;
2982 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2983 }
2984 if (phymode & WMODE_BE_24G) {
2985 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2986 *pureMode |= WIFI_MODE_BE;
2987 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2988 }
2989 break;
2990 case band_5:
2991 if (phymode & WMODE_A) {
2992 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
2993 *pureMode |= WIFI_MODE_A;
2994 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2995 }
2996 if (phymode & WMODE_AN) {
2997 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2998 *pureMode |= WIFI_MODE_N;
2999 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3000 }
3001 if (phymode & WMODE_AC) {
3002 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
3003 *pureMode |= WIFI_MODE_AC;
3004 }
3005 if (phymode & WMODE_AX_5G) {
3006 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3007 *pureMode |= WIFI_MODE_AX;
3008 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3009 }
3010 if (phymode & WMODE_BE_5G) {
3011 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3012 *pureMode |= WIFI_MODE_BE;
3013 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3014 }
3015 break;
3016 case band_6:
3017 if (phymode & WMODE_AX_6G) {
3018 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3019 *pureMode |= WIFI_MODE_AX;
3020 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3021 }
3022 if (phymode & WMODE_BE_6G) {
3023 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3024 *pureMode |= WIFI_MODE_BE;
3025 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3026 }
3027 break;
3028 default:
3029 fprintf(stderr, "%s band_idx invalid\n", __func__);
3030 break;
3031 }
3032
3033 /* Remove the last comma */
3034 if (strlen(output_string) != 0)
3035 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08003036
3037 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3038 return RETURN_OK;
3039}
3040
3041// Set the radio operating mode, and pure mode flag.
3042INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
3043{
developer69b61b02023-03-07 17:17:44 +08003044 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003045 if (strcmp (channelMode,"11A") == 0)
3046 {
3047 writeBandWidth(radioIndex,"20MHz");
3048 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3049 printf("\nChannel Mode is 802.11a (5GHz)\n");
3050 }
3051 else if (strcmp (channelMode,"11NAHT20") == 0)
3052 {
3053 writeBandWidth(radioIndex,"20MHz");
3054 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3055 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
3056 }
3057 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
3058 {
3059 writeBandWidth(radioIndex,"40MHz");
3060 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3061 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3062 }
3063 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
3064 {
3065 writeBandWidth(radioIndex,"40MHz");
3066 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3067 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3068 }
3069 else if (strcmp (channelMode,"11ACVHT20") == 0)
3070 {
3071 writeBandWidth(radioIndex,"20MHz");
3072 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3073 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
3074 }
3075 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
3076 {
3077 writeBandWidth(radioIndex,"40MHz");
3078 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3079 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3080 }
3081 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
3082 {
3083 writeBandWidth(radioIndex,"40MHz");
3084 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3085 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3086 }
3087 else if (strcmp (channelMode,"11ACVHT80") == 0)
3088 {
3089 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
3090 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
3091 }
3092 else if (strcmp (channelMode,"11ACVHT160") == 0)
3093 {
3094 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
3095 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
developer69b61b02023-03-07 17:17:44 +08003096 }
developer72fb0bb2023-01-11 09:46:29 +08003097 else if (strcmp (channelMode,"11B") == 0)
3098 {
3099 writeBandWidth(radioIndex,"20MHz");
3100 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3101 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
3102 }
3103 else if (strcmp (channelMode,"11G") == 0)
3104 {
3105 writeBandWidth(radioIndex,"20MHz");
3106 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3107 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
3108 }
3109 else if (strcmp (channelMode,"11NGHT20") == 0)
3110 {
3111 writeBandWidth(radioIndex,"20MHz");
3112 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3113 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3114 }
3115 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3116 {
3117 writeBandWidth(radioIndex,"40MHz");
3118 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3119 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3120 }
3121 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3122 {
3123 writeBandWidth(radioIndex,"40MHz");
3124 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3125 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3126 }
developer69b61b02023-03-07 17:17:44 +08003127 else
developer72fb0bb2023-01-11 09:46:29 +08003128 {
3129 return RETURN_ERR;
3130 }
3131 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3132
3133 return RETURN_OK;
3134}
3135
developer0f10c772023-05-16 21:43:39 +08003136typedef enum _RT_802_11_PHY_MODE {
3137 PHY_11BG_MIXED = 0,
3138 PHY_11B = 1,
3139 PHY_11A = 2,
3140 PHY_11ABG_MIXED = 3,
3141 PHY_11G = 4,
3142 PHY_11ABGN_MIXED = 5, /* both band 5 */
3143 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3144 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3145 PHY_11AN_MIXED = 8, /* 5G band 8 */
3146 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3147 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3148 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
3149 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3150 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3151 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3152 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3153 PHY_11AX_24G = 16,
3154 PHY_11AX_5G = 17,
3155 PHY_11AX_6G = 18,
3156 PHY_11AX_24G_6G = 19,
3157 PHY_11AX_5G_6G = 20,
3158 PHY_11AX_24G_5G_6G = 21,
3159 PHY_11BE_24G = 22,
3160 PHY_11BE_5G = 23,
3161 PHY_11BE_6G = 24,
3162 PHY_11BE_24G_6G = 25,
3163 PHY_11BE_5G_6G = 26,
3164 PHY_11BE_24G_5G_6G = 27,
3165 PHY_MODE_MAX,
3166} RT_802_11_PHY_MODE;
3167
3168unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3169{
3170 int band_idx = 0;
3171 unsigned int wireless_mode = PHY_MODE_MAX;
3172
3173 band_idx = radio_index_to_band(radioIndex);
3174
3175 switch (band_idx) {
3176 case band_2_4:
3177 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3178 wireless_mode = PHY_11GN_MIXED;
3179 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3180 wireless_mode = PHY_11BGN_MIXED;
3181 if (pureMode & WIFI_MODE_AX)
3182 wireless_mode = PHY_11AX_24G;
3183 if (pureMode & WIFI_MODE_BE)
3184 wireless_mode = PHY_11BE_24G;
3185 break;
3186 case band_5:
3187 if (pureMode == WIFI_MODE_N)
3188 wireless_mode = PHY_11N_5G;
3189 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3190 wireless_mode = PHY_11VHT_N_MIXED;
3191 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3192 wireless_mode = PHY_11VHT_N_A_MIXED;
3193 if (pureMode & WIFI_MODE_AX)
3194 wireless_mode = PHY_11AX_5G;
3195 if (pureMode & WIFI_MODE_BE)
3196 wireless_mode = PHY_11BE_5G;
3197 break;
3198 case band_6:
3199 if (pureMode & WIFI_MODE_AX)
3200 wireless_mode = PHY_11AX_6G;
3201 if (pureMode & WIFI_MODE_BE)
3202 wireless_mode = PHY_11BE_6G;
3203 break;
3204 default:
3205 fprintf(stderr, "%s band_idx invalid\n", __func__);
3206 break;
3207 }
3208
3209 return wireless_mode;
3210}
3211
developer72fb0bb2023-01-11 09:46:29 +08003212// Set the radio operating mode, and pure mode flag.
3213INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3214{
developer0f10c772023-05-16 21:43:39 +08003215 unsigned int wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003216
developer0f10c772023-05-16 21:43:39 +08003217 char interface_name[IF_NAME_SIZE] = {0};
3218 char cmd[MAX_CMD_SIZE] = {0};
3219 char buf[MAX_BUF_SIZE] = {0};
3220 int i;
developer72fb0bb2023-01-11 09:46:29 +08003221
developer0f10c772023-05-16 21:43:39 +08003222 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003223
developer0f10c772023-05-16 21:43:39 +08003224 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003225
developer0f10c772023-05-16 21:43:39 +08003226 if (wireless_mode == PHY_MODE_MAX) {
3227 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3228 return RETURN_ERR;
3229 }
developer72fb0bb2023-01-11 09:46:29 +08003230
developer0f10c772023-05-16 21:43:39 +08003231 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3232 return RETURN_ERR;
3233 snprintf(cmd, sizeof(cmd), "mwctl %s set phymode %d", interface_name, wireless_mode);
3234 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003235
developer0f10c772023-05-16 21:43:39 +08003236 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3237
3238 return RETURN_OK;
3239}
3240
3241INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3242{
3243 unsigned int wireless_mode = PHY_MODE_MAX;
3244 char interface_name[IF_NAME_SIZE] = {0};
3245 char cmd[MAX_CMD_SIZE] = {0};
3246 char buf[MAX_BUF_SIZE] = {0};
3247 int i;
3248 char dat_file[MAX_BUF_SIZE] = {0};
3249 struct params params={0};
3250
3251 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3252
3253 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3254
3255 if (wireless_mode == PHY_MODE_MAX) {
3256 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3257 return RETURN_ERR;
3258 }
3259
3260 params.name = "WirelessMode";
3261 snprintf(buf, sizeof(buf), "%d", wireless_mode);
3262 params.value = buf;
3263
3264 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3265 wifi_datfileWrite(dat_file, &params, 1);
3266
developer72fb0bb2023-01-11 09:46:29 +08003267 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3268
3269 return RETURN_OK;
3270}
3271
3272INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3273
3274 char config_file[64] = {0};
3275 char buf[64] = {0};
3276 struct params params = {0};
3277 wifi_band band = band_invalid;
3278
3279 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3280
3281 band = wifi_index_to_band(radioIndex);
3282
3283 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3284 return RETURN_ERR;
3285 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3286 return RETURN_ERR;
3287 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3288 return RETURN_ERR;
3289
3290 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3291 params.name = "hw_mode";
3292 params.value = hw_mode;
3293 wifi_hostapdWrite(config_file, &params, 1);
3294 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3295
3296 if (band == band_2_4) {
3297 if (strncmp(hw_mode, "b", 1) == 0) {
3298 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
3299 snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3300 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3301 snprintf(buf, sizeof(buf), "%s", "1,2");
3302 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3303 } else {
3304 // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
3305
3306 snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3307 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3308 snprintf(buf, sizeof(buf), "%s", "6,12,24");
3309 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3310 }
3311 }
3312
3313 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3314 return RETURN_OK;
3315}
3316
3317INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3318{
3319 char config_file[64] = {0};
3320 struct params params = {0};
3321 wifi_band band = band_invalid;
3322
3323 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3324
3325 band = wifi_index_to_band(radioIndex);
3326 if (band != band_2_4)
3327 return RETURN_OK;
3328
3329 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3330 params.name = "noscan";
3331 params.value = noscan;
3332 wifi_hostapdWrite(config_file, &params, 1);
3333 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3334
3335 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3336 return RETURN_OK;
3337}
3338
3339//Get the list of supported channel. eg: "1-11"
3340//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.
3341INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3342{
3343 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08003344 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08003345 return RETURN_ERR;
3346 char cmd[256] = {0};
3347 char buf[128] = {0};
3348 BOOL dfs_enable = false;
3349 int phyId = 0;
3350
3351 // Parse possible channel number and separate them with commas.
3352 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3353 phyId = radio_index_to_phy(radioIndex);
3354 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3355 if (dfs_enable)
3356 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 +08003357 else
developer72fb0bb2023-01-11 09:46:29 +08003358 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);
3359
3360 _syscmd(cmd,buf,sizeof(buf));
3361 strncpy(output_string, buf, sizeof(buf));
3362
3363 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3364 return RETURN_OK;
3365}
developerd1824452023-05-18 12:30:04 +08003366//Getting current radio extension channel
3367INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3368{
3369 CHAR buf[150] = {0};
3370 CHAR cmd[150] = {0};
3371
3372 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer262f4cb2023-05-24 12:22:04 +08003373 if (strncmp(buf, "Below", 5) == 0) //below
developerd1824452023-05-18 12:30:04 +08003374 strcpy(Value,"BelowControlChannel");
developer262f4cb2023-05-24 12:22:04 +08003375 if(strncmp(buf, "Above", 5) == 0) //above
developerd1824452023-05-18 12:30:04 +08003376 strcpy(Value,"AboveControlChannel");
3377 return RETURN_OK;
3378}
developerf6a87542023-05-16 15:47:28 +08003379
developer72fb0bb2023-01-11 09:46:29 +08003380//Get the list for used channel. eg: "1,6,9,11"
3381//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.
3382INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3383{
3384 char interface_name[16] = {0};
3385 char cmd[128] = {0};
3386 char buf[128] = {0};
3387 char config_file[64] = {0};
3388 int channel = 0;
3389 int freq = 0;
3390 int bandwidth = 0;
3391 int center_freq = 0;
3392 int center_channel = 0;
3393 int channel_delta = 0;
3394 wifi_band band = band_invalid;
3395
3396 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3397
3398 if (NULL == output_string)
3399 return RETURN_ERR;
3400
3401 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3402 return RETURN_ERR;
3403 sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3404 _syscmd(cmd, buf, sizeof(buf));
3405 if (strlen(buf) == 0) {
3406 fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__);
3407 return RETURN_ERR;
3408 }
3409 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
3410
3411 if (bandwidth == 20) {
3412 snprintf(output_string, 256, "%d", channel);
3413 return RETURN_OK;
3414 }
3415
3416 center_channel = ieee80211_frequency_to_channel(center_freq);
3417
3418 band = wifi_index_to_band(radioIndex);
3419 if (band == band_2_4 && bandwidth == 40) {
developerd1824452023-05-18 12:30:04 +08003420 sprintf(config_file, "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08003421 memset(buf, 0, sizeof(buf));
3422 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
3423
3424 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
3425 snprintf(output_string, 256, "%d,%d", channel, channel+4);
3426 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
3427 snprintf(output_string, 256, "%d,%d", channel-4, channel);
3428 } else {
3429 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
3430 return RETURN_ERR;
3431 }
3432 } else if (band == band_5 || band == band_6){
3433 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
developerd1824452023-05-18 12:30:04 +08003434 // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6.
developer72fb0bb2023-01-11 09:46:29 +08003435 channel_delta = (bandwidth-20)/10;
developerd1824452023-05-18 12:30:04 +08003436 memset(output_string, 0, 256);
3437 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3438 // If i is not the last channel, we add a comma.
3439 snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
3440 strncat(output_string, buf, strlen(buf));
3441 }
developer72fb0bb2023-01-11 09:46:29 +08003442 } else
3443 return RETURN_ERR;
3444
3445 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3446 return RETURN_OK;
3447}
3448
developer69b61b02023-03-07 17:17:44 +08003449//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003450INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003451{
3452 char channel_str[16] = {0};
3453 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +08003454 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003455
3456 if (output_ulong == NULL)
3457 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003458 band = wifi_index_to_band(radioIndex);
3459 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3460 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
developer72fb0bb2023-01-11 09:46:29 +08003461
3462 *output_ulong = strtoul(channel_str, NULL, 10);
3463
3464 return RETURN_OK;
3465}
3466
3467
3468INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
3469{
3470 char cmd[1024] = {0}, buf[5] = {0};
3471 char interface_name[16] = {0};
3472
3473 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3474 if (NULL == output_ulong)
3475 return RETURN_ERR;
3476
3477 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name);
3478 if (wifi_getApName(apIndex,interface_name) != RETURN_OK)
3479 return RETURN_ERR;
3480 _syscmd(cmd,buf,sizeof(buf));
3481 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
3482 if (*output_ulong == 0) {
3483 return RETURN_ERR;
3484 }
3485
3486 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3487 return RETURN_OK;
3488}
3489
3490//Storing the previous channel value
3491INT wifi_storeprevchanval(INT radioIndex)
3492{
3493 char buf[256] = {0};
3494 char output[4]={'\0'};
3495 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08003496 wifi_band band = band_invalid;
3497
3498 band = wifi_index_to_band(radioIndex);
3499 if (band == band_invalid) {
3500 return RETURN_ERR;
3501 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
3502 }
3503 snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
3504 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
3505
3506 if(band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08003507 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003508 else if(band == band_5)
developer72fb0bb2023-01-11 09:46:29 +08003509 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003510 else
3511 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
developer72fb0bb2023-01-11 09:46:29 +08003512 system(buf);
3513 Radio_flag = FALSE;
3514 return RETURN_OK;
3515}
3516
3517//Set the running channel number
3518INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
3519{
3520 // We only write hostapd config here
3521 char str_channel[8]={0};
3522 char *list_channel;
3523 char config_file[128] = {0};
3524 char possible_channels[256] = {0};
developerd1824452023-05-18 12:30:04 +08003525 char config_file_dat[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003526 int max_radio_num = 0;
3527 struct params list = {0};
developerd1824452023-05-18 12:30:04 +08003528 struct params dat = {0};
3529 struct params acs = {0};
3530 wifi_band band = band_invalid;
3531 bool acs_channel = false;
developer72fb0bb2023-01-11 09:46:29 +08003532
3533 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3534
developerd1824452023-05-18 12:30:04 +08003535 if (channel == 0)
3536 acs_channel = true;
developer72fb0bb2023-01-11 09:46:29 +08003537 // Check valid
3538 sprintf(str_channel, "%lu", channel);
3539
developerd1824452023-05-18 12:30:04 +08003540
developer72fb0bb2023-01-11 09:46:29 +08003541 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
3542 list_channel = strtok(possible_channels, ",");
3543 while(true)
3544 {
3545 if(list_channel == NULL) { // input not in the list
3546 fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel);
3547 return RETURN_ERR;
3548 }
3549 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
3550 break;
3551 list_channel = strtok(NULL, ",");
3552 }
developerd1824452023-05-18 12:30:04 +08003553 /*
developer72fb0bb2023-01-11 09:46:29 +08003554 list.name = "channel";
3555 list.value = str_channel;
3556 wifi_getMaxRadioNumber(&max_radio_num);
3557 for(int i=0; i<=MAX_APS/max_radio_num;i++)
3558 {
3559 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3560 wifi_hostapdWrite(config_file, &list, 1);
3561 }
developerd1824452023-05-18 12:30:04 +08003562 */
3563 dat.name = "Channel";
3564 dat.value = str_channel;
3565 band = wifi_index_to_band(radioIndex);
3566 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3567 wifi_datfileWrite(config_file_dat, &dat, 1);
3568 if (acs_channel == true) {
3569 acs.name = "AutoChannelSelect";
3570 acs.value = "3";
3571 } else {
3572 acs.name = "AutoChannelSelect";
3573 acs.value = "0";
3574 }
3575 wifi_datfileWrite(config_file_dat, &acs, 1);
developerc0772e62023-05-18 15:10:48 +08003576 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003577 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3578 return RETURN_OK;
3579}
3580
3581INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
3582{
3583 struct params list[2];
3584 char str_idx[16];
3585 char config_file[64];
3586 int max_num_radios = 0;
3587 wifi_band band = band_invalid;
3588
3589 band = wifi_index_to_band(radioIndex);
3590 if (band == band_2_4)
3591 return RETURN_OK;
3592
3593 snprintf(str_idx, sizeof(str_idx), "%lu", channel);
3594 list[0].name = "vht_oper_centr_freq_seg0_idx";
3595 list[0].value = str_idx;
3596 list[1].name = "he_oper_centr_freq_seg0_idx";
3597 list[1].value = str_idx;
3598
3599 wifi_getMaxRadioNumber(&max_num_radios);
3600 for(int i=0; i<=MAX_APS/max_num_radios; i++)
3601 {
3602 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
3603 if (band == band_6)
3604 wifi_hostapdWrite(config_file, &list[1], 1);
3605 else
3606 wifi_hostapdWrite(config_file, list, 2);
3607 }
3608
3609 return RETURN_OK;
3610}
3611
3612//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
3613//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
3614INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
3615{
3616 //Set to wifi config only. Wait for wifi reset to apply.
3617 char buf[256] = {0};
3618 char str_channel[256] = {0};
3619 int count = 0;
3620 ULONG Value = 0;
3621 FILE *fp = NULL;
3622 if(enable == TRUE)
3623 {
3624 wifi_setRadioChannel(radioIndex,Value);
3625 }
3626 return RETURN_OK;
3627}
3628
3629INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
3630{
3631 if (output_bool == NULL)
3632 return RETURN_ERR;
3633
3634 *output_bool = TRUE;
3635
3636 return RETURN_OK;
3637}
3638
3639INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
3640{
developer69b61b02023-03-07 17:17:44 +08003641 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003642 return RETURN_ERR;
3643 *output_bool=FALSE;
3644 return RETURN_OK;
3645}
3646
3647INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
3648{
developer69b61b02023-03-07 17:17:44 +08003649 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003650 return RETURN_ERR;
3651 *output_bool=FALSE;
3652 return RETURN_OK;
3653}
3654
3655INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
3656{
3657 //Set to wifi config only. Wait for wifi reset to apply.
3658 return RETURN_OK;
3659}
3660
3661INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
3662{
3663 return RETURN_OK;
3664}
3665
3666INT wifi_factoryResetAP(int apIndex)
3667{
developer47cc27a2023-05-17 23:09:58 +08003668 char ap_config_file[MAX_CMD_SIZE] = {0};
3669 char cmd[MAX_CMD_SIZE] = {0};
3670 char ret_buf[MAX_BUF_SIZE] = {0};
3671 int radio_idx = 0;
3672 int bss_idx = 0;
3673 char ssid[32] = {0};
3674 char interface[IF_NAME_SIZE] = {0};
3675 char psk_file[MAX_CMD_SIZE] = {0};
3676 struct params params[3] = {0};
3677 char *band_str[3] = {"2G", "5G", "6G"};
developer72fb0bb2023-01-11 09:46:29 +08003678
3679 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3680
developer47cc27a2023-05-17 23:09:58 +08003681 /*del old config file*/
3682 snprintf(ap_config_file, MAX_CMD_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
3683 snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
3684 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003685
developer47cc27a2023-05-17 23:09:58 +08003686 memset(cmd, 0, sizeof(cmd));
3687 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003688
developer47cc27a2023-05-17 23:09:58 +08003689 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
3690
3691 /*prepare new config file*/
developere740c2a2023-05-23 18:34:32 +08003692 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
developer47cc27a2023-05-17 23:09:58 +08003693 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3694
3695 if (radio_idx == band_2_4) {
3696 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
3697 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
3698 } else if (radio_idx == band_5) {
3699 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
3700 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
3701 } else if (radio_idx == band_6) {
3702 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
3703 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
3704 }
3705
3706 /* fix wpa_psk_file path */
3707 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
3708
3709 params[0].name = "ssid";
3710 params[0].value = ssid;
3711 params[1].name = "interface";
3712 params[1].value = interface;
3713 params[2].name = "wpa_psk_file";
3714 params[2].value = psk_file;
3715
3716 wifi_hostapdWrite(ap_config_file, params, 3);
3717
3718 /*clear psk file*/
3719 memset(cmd, 0, sizeof(cmd));
3720 memset(ret_buf, 0, sizeof(ret_buf));
3721
3722 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
3723
3724 if (access(psk_file, F_OK) != 0) {
3725 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
3726 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3727 } else {
3728 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
3729 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3730 }
3731
3732 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3733
3734 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003735}
3736
3737//To set Band Steering AP group
3738//To-do
3739INT wifi_setBandSteeringApGroup(char *ApGroup)
3740{
3741 return RETURN_OK;
3742}
3743
3744INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
3745{
3746 char config_file[128] = {'\0'};
3747 char buf[128] = {'\0'};
3748
3749 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3750 if (dtimInterval == NULL)
3751 return RETURN_ERR;
3752
3753 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer885b56c2023-05-22 15:02:46 +08003754 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003755
3756 if (strlen(buf) == 0) {
3757 *dtimInterval = 2;
3758 } else {
3759 *dtimInterval = strtoul(buf, NULL, 10);
3760 }
3761
3762 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3763 return RETURN_OK;
3764}
3765
3766INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
3767{
3768 struct params params={0};
3769 char config_file[MAX_BUF_SIZE] = {'\0'};
3770 char buf[MAX_BUF_SIZE] = {'\0'};
3771
3772 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3773 if (dtimInterval < 1 || dtimInterval > 255) {
3774 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
3775 return RETURN_ERR;
3776 }
developer69b61b02023-03-07 17:17:44 +08003777
developer72fb0bb2023-01-11 09:46:29 +08003778 params.name = "dtim_period";
3779 snprintf(buf, sizeof(buf), "%d", dtimInterval);
3780 params.value = buf;
3781
3782 sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex);
3783 wifi_hostapdWrite(config_file, &params, 1);
3784 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3785
3786 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3787 return RETURN_OK;
3788}
3789
3790//Check if the driver support the Dfs
3791INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
3792{
3793 wifi_band band = band_invalid;
developer69b61b02023-03-07 17:17:44 +08003794 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003795 return RETURN_ERR;
3796 *output_bool=FALSE;
3797
3798 band = wifi_index_to_band(radioIndex);
3799 if (band == band_5)
3800 *output_bool = TRUE;
3801 return RETURN_OK;
3802}
3803
3804//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.
3805//The value of this parameter is a comma seperated list of channel number
3806INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
3807{
developer69b61b02023-03-07 17:17:44 +08003808 if (NULL == output_pool)
developer72fb0bb2023-01-11 09:46:29 +08003809 return RETURN_ERR;
3810 if (radioIndex==1)
developer69b61b02023-03-07 17:17:44 +08003811 return RETURN_OK;//TODO need to handle for 5GHz band, i think
developer72fb0bb2023-01-11 09:46:29 +08003812 snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
3813
3814 return RETURN_OK;
3815}
3816
3817INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
3818{
3819 //Set to wifi config. And apply instantly.
3820 return RETURN_OK;
3821}
3822
3823INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
3824{
developer69b61b02023-03-07 17:17:44 +08003825 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
developer72fb0bb2023-01-11 09:46:29 +08003826 return RETURN_ERR;
3827 *output_interval_seconds=1800;
3828 *output_dwell_milliseconds=40;
3829
3830 return RETURN_OK;
3831}
3832
3833INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
3834{
3835 //Set to wifi config. And apply instantly.
3836 return RETURN_OK;
3837}
3838
3839INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
3840{
3841 if (output_bool == NULL)
3842 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08003843 *output_bool = true;
3844 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003845}
3846
3847INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
3848{
3849 return RETURN_OK;
3850}
3851
3852//Get the Dfs enable status
3853INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
3854{
3855 char buf[16] = {0};
3856 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08003857 char config_file_dat[128] = {0};
developerd1824452023-05-18 12:30:04 +08003858 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003859
3860 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3861
3862 if (output_bool == NULL)
3863 return RETURN_ERR;
developerf6a87542023-05-16 15:47:28 +08003864 *output_bool = TRUE; // default
developerd1824452023-05-18 12:30:04 +08003865 band = wifi_index_to_band(radioIndex);
3866 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3867
developer262f4cb2023-05-24 12:22:04 +08003868 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08003869
3870 if (strncmp(buf, "0", 1) == 0)
3871 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08003872 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3873 return RETURN_OK;
3874}
3875
3876//Set the Dfs enable status
3877INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
3878{
3879 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +08003880 char config_dat_file[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003881 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08003882 struct params dat = {0};
3883 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003884
3885 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3886
3887 f = fopen(DFS_ENABLE_FILE, "w");
3888 if (f == NULL)
3889 return RETURN_ERR;
3890 fprintf(f, "%d", enable);
3891 fclose(f);
3892
developer72fb0bb2023-01-11 09:46:29 +08003893 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
3894
developerd1824452023-05-18 12:30:04 +08003895 dat.name = "DfsEnable";
developer262f4cb2023-05-24 12:22:04 +08003896 dat.value = enable?"1":"0";
developerd1824452023-05-18 12:30:04 +08003897 band = wifi_index_to_band(radioIndex);
3898 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3899 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08003900 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3901 return RETURN_OK;
3902}
3903
3904//Check if the driver support the AutoChannelRefreshPeriod
3905INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
3906{
developer69b61b02023-03-07 17:17:44 +08003907 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003908 return RETURN_ERR;
3909 *output_bool=FALSE; //not support
3910
3911 return RETURN_OK;
3912}
3913
3914//Get the ACS refresh period in seconds
3915INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
3916{
developer69b61b02023-03-07 17:17:44 +08003917 if (NULL == output_ulong)
developer72fb0bb2023-01-11 09:46:29 +08003918 return RETURN_ERR;
3919 *output_ulong=300;
3920
3921 return RETURN_OK;
3922}
3923
3924//Set the ACS refresh period in seconds
3925INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
3926{
3927 return RETURN_ERR;
3928}
3929
3930//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
3931//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.
3932INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
3933{
developer8666b312023-03-24 14:05:31 +08003934 char cmd[MAX_CMD_SIZE] = {0}, buf[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003935 char extchannel[128] = {0};
developer8666b312023-03-24 14:05:31 +08003936 char interface_name[64] = {0};
3937 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08003938 BOOL radio_enable = FALSE;
3939 wifi_band band;
3940
3941 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3942
developerd1824452023-05-18 12:30:04 +08003943 if (NULL == output_string) {
3944 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003945 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003946 }
3947 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
3948 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003949 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003950 }
3951 if (radio_enable != TRUE) {
3952 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003953 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08003954 }
developer8666b312023-03-24 14:05:31 +08003955 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3956 return RETURN_ERR;
3957 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08003958
developer8666b312023-03-24 14:05:31 +08003959 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
3960 ret = _syscmd(cmd, buf, sizeof(buf));
3961 len = strlen(buf);
3962 if((ret != 0) || (len == 0))
3963 {
3964 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
3965 return RETURN_ERR;
3966 }
3967
developer72fb0bb2023-01-11 09:46:29 +08003968 band = wifi_index_to_band(radioIndex);
developer8666b312023-03-24 14:05:31 +08003969 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
developer72fb0bb2023-01-11 09:46:29 +08003970 wifi_getRadioExtChannel(radioIndex, extchannel);
developer8666b312023-03-24 14:05:31 +08003971 if (strncmp(extchannel, "Auto", 4) != 0) // not auto means we have set HT40+/-
3972 snprintf(buf, sizeof(buf), "40");
developer72fb0bb2023-01-11 09:46:29 +08003973 }
developer8666b312023-03-24 14:05:31 +08003974 snprintf(output_string, 64, "%sMHz", buf);
developer72fb0bb2023-01-11 09:46:29 +08003975 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3976
3977 return RETURN_OK;
3978}
developer72fb0bb2023-01-11 09:46:29 +08003979//Set the Operating Channel Bandwidth.
3980INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
3981{
3982 char config_file[128];
developerd1824452023-05-18 12:30:04 +08003983 char ht_value[16];
3984 char vht_value[16];
3985 char eht_value[16];
3986 struct params dat[3];
3987 wifi_band band = band_invalid;
developer262f4cb2023-05-24 12:22:04 +08003988 char cmd[MAX_CMD_SIZE] = {0};
3989 char buf[MAX_BUF_SIZE] = {0};
3990 int bw = 20;
developer72fb0bb2023-01-11 09:46:29 +08003991
3992 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3993
3994 if(NULL == bandwidth)
3995 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003996 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003997
developerd1824452023-05-18 12:30:04 +08003998 if(strstr(bandwidth,"320") != NULL) {
3999 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4000 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4001 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developer262f4cb2023-05-24 12:22:04 +08004002 bw = 320;
developerd1824452023-05-18 12:30:04 +08004003 } else if(strstr(bandwidth,"160") != NULL) {
4004 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4005 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4006 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developer262f4cb2023-05-24 12:22:04 +08004007 bw = 160;
developerd1824452023-05-18 12:30:04 +08004008 } else if(strstr(bandwidth,"80") != NULL) {
4009 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4010 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
4011 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developer262f4cb2023-05-24 12:22:04 +08004012 bw = 80;
developerd1824452023-05-18 12:30:04 +08004013 } else if(strstr(bandwidth,"40") != NULL) {
4014 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4015 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4016 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developer262f4cb2023-05-24 12:22:04 +08004017 bw = 40;
developerd1824452023-05-18 12:30:04 +08004018 } else if(strstr(bandwidth,"20") != NULL) {
4019 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
4020 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4021 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developer262f4cb2023-05-24 12:22:04 +08004022 bw = 20;
developerd1824452023-05-18 12:30:04 +08004023 } else {
developer72fb0bb2023-01-11 09:46:29 +08004024 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
4025 return RETURN_ERR;
4026 }
4027
developerd1824452023-05-18 12:30:04 +08004028 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4029 dat[0].name = "HT_BW";
4030 dat[0].value = ht_value;
4031 dat[1].name = "VHT_BW";
4032 dat[1].value = vht_value;
4033 dat[2].name = "EHT_ApBw";
4034 dat[2].value = eht_value;
4035 wifi_datfileWrite(config_file, dat, 3);
developer262f4cb2023-05-24 12:22:04 +08004036 snprintf(cmd, sizeof(cmd), "mwctl phy phy%d set channel bw=%d\n", band, bw);
4037 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004038
4039 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4040 return RETURN_OK;
4041}
4042
developer72fb0bb2023-01-11 09:46:29 +08004043//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
4044//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.
4045INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
4046{
4047 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004048 char config_dat_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004049 char mode_str[16] = {0};
4050 char buf[64] = {0};
developerd1824452023-05-18 12:30:04 +08004051 char cmd[MAX_CMD_SIZE] = {0};
4052 char interface_name[64] = {0};
4053 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08004054 wifi_band band;
developerd1824452023-05-18 12:30:04 +08004055 ULONG channel = 0;
4056 int centr_channel = 0;
developer72fb0bb2023-01-11 09:46:29 +08004057 UINT mode_map = 0;
developerd1824452023-05-18 12:30:04 +08004058 int freq=0;
developer72fb0bb2023-01-11 09:46:29 +08004059
4060 if (output_string == NULL)
4061 return RETURN_ERR;
4062
4063 wifi_getRadioMode(radioIndex, mode_str, &mode_map);
4064
4065 band = wifi_index_to_band(radioIndex);
4066 if (band == band_invalid)
4067 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004068 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4069 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004070
4071 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4072
4073 snprintf(output_string, 64, "Auto");
developer23e71282023-01-18 10:25:19 +08004074 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
developerd1824452023-05-18 12:30:04 +08004075 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
4076 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4077 wifi_halgetRadioExtChannel(config_dat_file, output_string);
developer23e71282023-01-18 10:25:19 +08004078 if (!(mode_map&WIFI_MODE_N))
developer72fb0bb2023-01-11 09:46:29 +08004079 snprintf(output_string, 64, "Auto");
4080 } else {
4081 // 5G and 6G band with ac or ax mode.
4082 wifi_getRadioChannel(radioIndex, &channel);
developerd1824452023-05-18 12:30:04 +08004083 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
4084
4085 ret = _syscmd(cmd, buf, sizeof(buf));
4086 len = strlen(buf);
4087 if((ret != 0) || (len == 0))
4088 {
4089 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4090 return RETURN_ERR;
4091 }
4092 sscanf(buf, "%d", &freq);
4093 centr_channel = ieee80211_frequency_to_channel(freq);
4094 if (centr_channel > (int)channel)
developer72fb0bb2023-01-11 09:46:29 +08004095 snprintf(output_string, 64, "AboveControlChannel");
4096 else
4097 snprintf(output_string, 64, "BelowControlChannel");
4098 }
4099
4100 return RETURN_OK;
4101}
4102
4103//Set the extension channel.
4104INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08004105{
developer72fb0bb2023-01-11 09:46:29 +08004106 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4107 struct params params={0};
4108 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004109 char config_dat_file[64] = {0};
4110 char ext_channel[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004111 char buf[128] = {0};
4112 char cmd[128] = {0};
4113 int max_radio_num =0, ret = 0, bandwidth = 0;
4114 unsigned long channel = 0, centr_channel = 0;
4115 bool stbcEnable = FALSE;
4116 params.name = "ht_capab";
4117 wifi_band band;
4118
4119 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4120 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
4121 _syscmd(cmd, buf, sizeof(buf));
4122 if (strlen(buf) != 0)
4123 stbcEnable = TRUE;
4124 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
4125 return RETURN_ERR;
4126 bandwidth = strtol(buf, NULL, 10);
4127 // TDK expected to get error with 20MHz
developer262f4cb2023-05-24 12:22:04 +08004128 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
developer72fb0bb2023-01-11 09:46:29 +08004129 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
4130 return RETURN_ERR;
4131
4132 band = wifi_index_to_band(radioIndex);
4133 if (band == band_invalid)
4134 return RETURN_ERR;
4135
4136 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
4137 return RETURN_ERR;
4138
developer262f4cb2023-05-24 12:22:04 +08004139 snprintf(buf, sizeof(buf), "HT%d", bandwidth);
4140 ret = util_get_sec_chan_offset(channel, buf);
4141 if (ret == -EINVAL)
4142 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004143
4144 if(NULL!= strstr(string,"Above")) {
developer262f4cb2023-05-24 12:22:04 +08004145 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
4146 return RETURN_OK;
4147 strcpy(ext_channel, "Above");
developer72fb0bb2023-01-11 09:46:29 +08004148 } else if(NULL!= strstr(string,"Below")) {
developer262f4cb2023-05-24 12:22:04 +08004149 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
4150 return RETURN_OK;
4151 strcpy(ext_channel, "Below");
4152 } else {
developerd1824452023-05-18 12:30:04 +08004153 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08004154 return RETURN_ERR;
4155 }
developerd1824452023-05-18 12:30:04 +08004156 params.name = "HT_EXTCHA";
developer72fb0bb2023-01-11 09:46:29 +08004157 params.value = ext_channel;
4158
developerd1824452023-05-18 12:30:04 +08004159 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4160 wifi_datfileWrite(config_dat_file, &params, 1);
4161
developer72fb0bb2023-01-11 09:46:29 +08004162 wifi_getMaxRadioNumber(&max_radio_num);
4163 for(int i=0; i<=MAX_APS/max_radio_num; i++)
4164 {
4165 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
developer72fb0bb2023-01-11 09:46:29 +08004166 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
4167 }
4168
4169 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
4170 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4171 return RETURN_OK;
4172}
4173
4174//Get the guard interval value. eg "400nsec" or "800nsec"
4175//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.
4176INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
4177{
4178 wifi_guard_interval_t GI;
4179
4180 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4181
4182 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
4183 return RETURN_ERR;
4184
4185 if (GI == wifi_guard_interval_400)
4186 strcpy(output_string, "400nsec");
4187 else if (GI == wifi_guard_interval_800)
4188 strcpy(output_string, "800nsec");
4189 else if (GI == wifi_guard_interval_1600)
4190 strcpy(output_string, "1600nsec");
4191 else if (GI == wifi_guard_interval_3200)
4192 strcpy(output_string, "3200nsec");
4193 else
4194 strcpy(output_string, "Auto");
4195
4196 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4197 return RETURN_OK;
4198}
4199
4200//Set the guard interval value.
4201INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
4202{
4203 wifi_guard_interval_t GI;
4204 int ret = 0;
4205
4206 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4207
4208 if (strcmp(string, "400nsec") == 0)
4209 GI = wifi_guard_interval_400;
4210 else if (strcmp(string , "800nsec") == 0)
4211 GI = wifi_guard_interval_800;
4212 else if (strcmp(string , "1600nsec") == 0)
4213 GI = wifi_guard_interval_1600;
4214 else if (strcmp(string , "3200nsec") == 0)
4215 GI = wifi_guard_interval_3200;
4216 else
4217 GI = wifi_guard_interval_auto;
4218
4219 ret = wifi_setGuardInterval(radioIndex, GI);
4220
4221 if (ret == RETURN_ERR) {
4222 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
4223 return RETURN_ERR;
4224 }
4225
4226 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4227 return RETURN_OK;
4228}
4229
4230//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
4231INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
4232{
4233 char buf[32]={0};
4234 char mcs_file[64] = {0};
4235 char cmd[64] = {0};
4236 int mode_bitmap = 0;
4237
4238 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4239 if(output_int == NULL)
4240 return RETURN_ERR;
4241 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4242
4243 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
4244 _syscmd(cmd, buf, sizeof(buf));
4245 if (strlen(buf) > 0)
4246 *output_int = strtol(buf, NULL, 10);
4247 else {
4248 // output the max MCS for the current radio mode
4249 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
4250 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
4251 return RETURN_ERR;
4252 }
4253 if (mode_bitmap & WIFI_MODE_AX) {
4254 *output_int = 11;
4255 } else if (mode_bitmap & WIFI_MODE_AC) {
4256 *output_int = 9;
4257 } else if (mode_bitmap & WIFI_MODE_N) {
4258 *output_int = 7;
4259 }
4260 }
4261 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4262
4263 return RETURN_OK;
4264}
4265
4266//Set the Modulation Coding Scheme index
4267INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
4268{
developera1255e42023-05-13 17:45:02 +08004269 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
4270 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 +08004271 char config_file[64] = {0};
4272 char set_value[16] = {0};
4273 char mcs_file[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004274 struct params set_config = {0};
4275 FILE *f = NULL;
developera1255e42023-05-13 17:45:02 +08004276 INT nss = 0;
4277 int ant_bitmap = 0;
4278 unsigned short cal_value = 0;
4279 UCHAR tval = 0, i = 0;
developer72fb0bb2023-01-11 09:46:29 +08004280
4281 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4282
4283 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4284
4285 // -1 means auto
4286 if (MCS > 15 || MCS < -1) {
4287 fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS);
4288 return RETURN_ERR;
4289 }
developera1255e42023-05-13 17:45:02 +08004290 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
4291 for(; ant_bitmap > 0; ant_bitmap >>= 1)
4292 nss += 1;
4293 //printf("%s:nss = %d\n", __func__, nss);
4294 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
4295 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
developer72fb0bb2023-01-11 09:46:29 +08004296 if (MCS > 9 || MCS == -1)
developera1255e42023-05-13 17:45:02 +08004297 tval = 2;/*one stream value*/
developer72fb0bb2023-01-11 09:46:29 +08004298 else if (MCS > 7)
developera1255e42023-05-13 17:45:02 +08004299 tval = 1;
developer72fb0bb2023-01-11 09:46:29 +08004300 else
developera1255e42023-05-13 17:45:02 +08004301 tval = 0;
4302 for (i = 0; i < nss; i++)
4303 cal_value |= (tval << (2*i));
4304 snprintf(set_value, sizeof(set_value), "%x", cal_value);
4305 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
4306 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
developer72fb0bb2023-01-11 09:46:29 +08004307 set_config.value = set_value;
4308
4309 wifi_hostapdWrite(config_file, &set_config, 1);
4310 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
4311
4312 // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
4313 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4314 f = fopen(mcs_file, "w");
4315 if (f == NULL) {
4316 fprintf(stderr, "%s: fopen failed\n", __func__);
4317 return RETURN_ERR;
4318 }
4319 fprintf(f, "%d", MCS);
4320 fclose(f);
4321
4322 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4323 return RETURN_OK;
4324}
4325
4326//Get supported Transmit Power list, eg : "0,25,50,75,100"
4327//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.
4328INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
4329{
4330 if (NULL == output_list)
4331 return RETURN_ERR;
4332 snprintf(output_list, 64,"0,25,50,75,100");
4333 return RETURN_OK;
4334}
4335
4336//Get current Transmit Power in dBm units.
4337//The transmite power level is in units of full power for this radio.
4338INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
4339{
4340 char interface_name[16] = {0};
4341 char cmd[128]={0};
4342 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08004343 char pwr_file[128]={0};
4344
developer72fb0bb2023-01-11 09:46:29 +08004345 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4346
4347 if(output_ulong == NULL)
4348 return RETURN_ERR;
4349
4350 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4351 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004352/*
developer72fb0bb2023-01-11 09:46:29 +08004353 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
4354 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004355 *output_ulong = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +08004356*/
4357 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4358 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
4359 _syscmd(cmd, buf, sizeof(buf));
4360 if (strlen(buf) > 0)
4361 *output_ulong = strtol(buf, NULL, 10);
4362 else
4363 *output_ulong = 100;
developer72fb0bb2023-01-11 09:46:29 +08004364 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4365 return RETURN_OK;
4366}
4367
4368//Set Transmit Power
4369//The transmite power level is in units of full power for this radio.
4370INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
4371{
4372 char interface_name[16] = {0};
4373 char *support;
4374 char cmd[128]={0};
4375 char buf[128]={0};
4376 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08004377 char pwr_file[128]={0};
4378 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08004379
4380 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4381
4382 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4383 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004384 // Get the Tx power supported list and check that is the input in the list
4385 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4386 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4387 support = strtok(buf, ",");
4388 while(true)
4389 {
4390 if(support == NULL) { // input not in the list
4391 wifi_dbg_printf("Input value is invalid.\n");
4392 return RETURN_ERR;
4393 }
4394 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4395 break;
4396 }
4397 support = strtok(NULL, ",");
4398 }
4399 snprintf(cmd, sizeof(cmd), "mwctl dev %s set pwr PercentageCtrl=1\n", interface_name);
4400 _syscmd(cmd, buf, sizeof(buf));
4401 snprintf(cmd, sizeof(cmd), "mwctl dev %s set pwr PowerDropCtrl=%lu\n", interface_name, TransmitPower);
4402 _syscmd(cmd, buf, sizeof(buf));
4403 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4404 f = fopen(pwr_file, "w");
4405 if (f == NULL) {
4406 fprintf(stderr, "%s: fopen failed\n", __func__);
4407 return RETURN_ERR;
4408 }
4409 fprintf(f, "%d", TransmitPower);
4410 fclose(f);
4411/* 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 +08004412 _syscmd(cmd, buf, sizeof(buf));
4413 maximum_tx = strtol(buf, NULL, 10);
4414
4415 // Get the Tx power supported list and check that is the input in the list
4416 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4417 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4418 support = strtok(buf, ",");
4419 while(true)
4420 {
4421 if(support == NULL) { // input not in the list
4422 wifi_dbg_printf("Input value is invalid.\n");
4423 return RETURN_ERR;
4424 }
4425 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4426 break;
4427 }
4428 support = strtok(NULL, ",");
4429 }
4430 txpower = TransmitPower*maximum_tx/100;
4431 phyId = radio_index_to_phy(radioIndex);
4432 snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower);
4433 _syscmd(cmd, buf, sizeof(buf));
4434 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +08004435*/
4436 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004437}
4438
4439//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
4440INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
4441{
developer69b61b02023-03-07 17:17:44 +08004442 if (NULL == Supported)
developer72fb0bb2023-01-11 09:46:29 +08004443 return RETURN_ERR;
4444 *Supported = TRUE;
4445
4446 return RETURN_OK;
4447}
4448
4449//Get 80211h feature enable
4450INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
4451{
4452 char buf[64]={'\0'};
4453 char config_file[64] = {'\0'};
4454
4455 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4456 if(enable == NULL)
4457 return RETURN_ERR;
4458
4459 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
developerd1824452023-05-18 12:30:04 +08004460 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
4461 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004462
4463 if (strncmp(buf, "1", 1) == 0)
4464 *enable = TRUE;
4465 else
4466 *enable = FALSE;
4467
4468 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4469 return RETURN_OK;
4470}
4471
4472//Set 80211h feature enable
4473INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
4474{
4475 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4476 struct params params={'\0'};
developerd1824452023-05-18 12:30:04 +08004477 struct params dat={0};
developer72fb0bb2023-01-11 09:46:29 +08004478 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08004479 char config_dat_file[MAX_BUF_SIZE] = {0};
4480 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004481
4482 params.name = "ieee80211h";
4483
4484 if (enable) {
4485 params.value = "1";
4486 } else {
4487 params.value = "0";
4488 }
4489
developerd1824452023-05-18 12:30:04 +08004490 dat.name = "IEEE80211H";
4491 dat.value = params.value;
4492
4493 band = wifi_index_to_band(radioIndex);
4494 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4495 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer69b61b02023-03-07 17:17:44 +08004496
developerd1824452023-05-18 12:30:04 +08004497 wifi_hostapdWrite(config_file, &params, 1);
4498 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08004499 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4500 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4501 return RETURN_OK;
4502}
4503
4504//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.
4505INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
4506{
4507 if (NULL == output)
4508 return RETURN_ERR;
4509 *output=100;
4510
4511 return RETURN_OK;
4512}
4513
4514//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.
4515INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
4516{
4517 if (NULL == output)
4518 return RETURN_ERR;
4519 *output = -99;
4520
4521 return RETURN_OK;
4522}
4523
4524INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
4525{
4526 return RETURN_ERR;
4527}
4528
4529
4530//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
4531INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
4532{
4533 char interface_name[16] = {0};
4534 char cmd[MAX_BUF_SIZE]={'\0'};
4535 char buf[MAX_CMD_SIZE]={'\0'};
4536
4537 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4538 if(output == NULL)
4539 return RETURN_ERR;
4540
4541 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4542 return RETURN_ERR;
4543 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
4544 _syscmd(cmd, buf, sizeof(buf));
4545 *output = atoi(buf);
4546
4547 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4548 return RETURN_OK;
4549}
developer69b61b02023-03-07 17:17:44 +08004550
developer72fb0bb2023-01-11 09:46:29 +08004551INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
4552{
4553 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4554 struct params params={'\0'};
4555 char buf[MAX_BUF_SIZE] = {'\0'};
4556 char config_file[MAX_BUF_SIZE] = {'\0'};
4557
4558 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
4559 return RETURN_ERR;
4560
4561 params.name = "beacon_int";
4562 snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
4563 params.value = buf;
4564
4565 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4566 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08004567
developer72fb0bb2023-01-11 09:46:29 +08004568 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4569 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4570 return RETURN_OK;
4571}
4572
4573//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.
4574INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
4575{
4576 //TODO: need to revisit below implementation
4577 char *temp;
4578 char temp_output[128] = {0};
4579 char temp_TransmitRates[64] = {0};
4580 char config_file[64] = {0};
4581
4582 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4583 if (NULL == output)
4584 return RETURN_ERR;
4585 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4586 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08004587
developer72fb0bb2023-01-11 09:46:29 +08004588 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
4589 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
4590 } else {
4591 temp = strtok(temp_TransmitRates," ");
4592 while(temp!=NULL)
4593 {
4594 // Convert 100 kbps to Mbps
4595 temp[strlen(temp)-1]=0;
4596 if((temp[0]=='5') && (temp[1]=='\0'))
4597 {
4598 temp="5.5";
4599 }
4600 strcat(temp_output,temp);
4601 temp = strtok(NULL," ");
4602 if(temp!=NULL)
4603 {
4604 strcat(temp_output,",");
4605 }
4606 }
4607 strcpy(output,temp_output);
4608 }
4609 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4610 return RETURN_OK;
4611}
4612
4613INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
4614{
4615 char *temp;
4616 char temp1[128];
4617 char temp_output[128];
4618 char temp_TransmitRates[128];
4619 char set[128];
4620 char sub_set[128];
4621 int set_count=0,subset_count=0;
4622 int set_index=0,subset_index=0;
4623 char *token;
4624 int flag=0, i=0;
4625 struct params params={'\0'};
4626 char config_file[MAX_BUF_SIZE] = {0};
4627 wifi_band band = wifi_index_to_band(radioIndex);
4628
4629 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4630 if(NULL == TransmitRates)
4631 return RETURN_ERR;
4632 strcpy(sub_set,TransmitRates);
4633
4634 //Allow only supported Data transmit rate to be set
4635 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
4636 token = strtok(sub_set,",");
4637 while( token != NULL ) /* split the basic rate to be set, by comma */
4638 {
4639 sub_set[subset_count]=atoi(token);
4640 subset_count++;
4641 token=strtok(NULL,",");
4642 }
4643 token=strtok(set,",");
4644 while(token!=NULL) /* split the supported rate by comma */
4645 {
4646 set[set_count]=atoi(token);
4647 set_count++;
4648 token=strtok(NULL,",");
4649 }
4650 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
4651 {
4652 for(set_index=0;set_index < set_count;set_index++)
4653 {
4654 flag=0;
4655 if(sub_set[subset_index]==set[set_index])
4656 break;
4657 else
4658 flag=1; /* No match found */
4659 }
4660 if(flag==1)
4661 return RETURN_ERR; //If value not found return Error
4662 }
4663 strcpy(temp_TransmitRates,TransmitRates);
4664
4665 for(i=0;i<strlen(temp_TransmitRates);i++)
4666 {
4667 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
4668 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
4669 {
4670 continue;
4671 }
4672 else
4673 {
4674 return RETURN_ERR;
4675 }
4676 }
4677 strcpy(temp_output,"");
4678 temp = strtok(temp_TransmitRates,",");
4679 while(temp!=NULL)
4680 {
4681 strcpy(temp1,temp);
4682 if(band == band_5)
4683 {
4684 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
4685 {
4686 return RETURN_ERR;
4687 }
4688 }
4689
4690 if(strcmp(temp,"5.5")==0)
4691 {
4692 strcpy(temp1,"55");
4693 }
4694 else
4695 {
4696 strcat(temp1,"0");
4697 }
4698 strcat(temp_output,temp1);
4699 temp = strtok(NULL,",");
4700 if(temp!=NULL)
4701 {
4702 strcat(temp_output," ");
4703 }
4704 }
4705 strcpy(TransmitRates,temp_output);
4706
4707 params.name= "basic_rates";
4708 params.value =TransmitRates;
4709
4710 wifi_dbg_printf("\n%s:",__func__);
4711 wifi_dbg_printf("\nparams.value=%s\n",params.value);
4712 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
4713 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4714 wifi_hostapdWrite(config_file,&params,1);
4715 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4716 return RETURN_OK;
4717}
4718
4719//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
4720INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
4721{
4722 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4723 FILE *fp = NULL;
4724 char path[256] = {0}, output_string[256] = {0};
4725 int count = 0;
4726 char *interface = NULL;
4727
4728 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
4729 if (fp == NULL)
4730 {
4731 printf("Failed to run command in Function %s\n", __FUNCTION__);
4732 return RETURN_ERR;
4733 }
4734 if (fgets(path, sizeof(path) - 1, fp) != NULL)
4735 {
4736 interface = strchr(path, '=');
4737
4738 if (interface != NULL)
4739 {
4740 strcpy(output_string, interface + 1);
4741 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
4742 interface_name[count] = output_string[count];
4743
4744 interface_name[count] = '\0';
4745 }
4746 }
4747 pclose(fp);
4748 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4749 return RETURN_OK;
4750}
4751
4752INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
4753{
4754 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4755 output_struct->radio_BytesSent = 0;
4756 output_struct->radio_BytesReceived = 0;
4757 output_struct->radio_PacketsSent = 0;
4758 output_struct->radio_PacketsReceived = 0;
4759 output_struct->radio_ErrorsSent = 0;
4760 output_struct->radio_ErrorsReceived = 0;
4761 output_struct->radio_DiscardPacketsSent = 0;
4762 output_struct->radio_DiscardPacketsReceived = 0;
4763 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4764 return RETURN_OK;
4765}
4766
4767
4768INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
4769{
4770 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4771 CHAR buf[MAX_CMD_SIZE] = {0};
4772 CHAR Value[MAX_BUF_SIZE] = {0};
4773 FILE *fp = NULL;
4774
4775 if (ifname == NULL || strlen(ifname) <= 1)
4776 return RETURN_OK;
4777
4778 snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
4779 system(buf);
4780
4781 fp = fopen("/tmp/Radio_Stats.txt", "r");
4782 if(fp == NULL)
4783 {
4784 printf("/tmp/Radio_Stats.txt not exists \n");
4785 return RETURN_ERR;
4786 }
4787 fclose(fp);
4788
4789 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4790 File_Reading(buf, Value);
4791 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
4792
4793 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4794 File_Reading(buf, Value);
4795 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
4796
4797 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4798 File_Reading(buf, Value);
4799 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
4800
4801 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4802 File_Reading(buf, Value);
4803 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
4804
4805 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4806 File_Reading(buf, Value);
4807 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
4808
4809 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4810 File_Reading(buf, Value);
4811 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
4812
4813 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4814 File_Reading(buf, Value);
4815 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
4816
4817 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4818 File_Reading(buf, Value);
4819 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
4820
4821 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4822 return RETURN_OK;
4823}
4824
4825INT GetIfacestatus(CHAR *interface_name, CHAR *status)
4826{
developer7e4a2a62023-04-06 19:56:03 +08004827 CHAR buf[MAX_CMD_SIZE] = {0};
4828 INT count = 0;
developer72fb0bb2023-01-11 09:46:29 +08004829
developer7e4a2a62023-04-06 19:56:03 +08004830 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4831
4832 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
4833 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
4834 File_Reading(buf, status);
4835 }
4836
4837 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4838 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004839}
4840
4841//Get detail radio traffic static info
4842INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
4843{
4844
developer69b61b02023-03-07 17:17:44 +08004845#if 0
4846 //ifconfig radio_x
developer72fb0bb2023-01-11 09:46:29 +08004847 output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters.
4848 output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters.
4849 output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface.
4850 output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface.
4851
4852 output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors.
4853 output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
4854 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.
4855 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.
4856
developer69b61b02023-03-07 17:17:44 +08004857 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 +08004858 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].
4859 output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error.
4860 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.
4861 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
4862 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
4863 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
4864 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
4865 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
4866
4867 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
4868 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
4869 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
4870 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.
4871
4872 return RETURN_OK;
4873#endif
4874
4875 CHAR interface_name[64] = {0};
4876 BOOL iface_status = FALSE;
4877 wifi_radioTrafficStats2_t radioTrafficStats = {0};
4878
4879 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4880 if (NULL == output_struct)
4881 return RETURN_ERR;
4882
4883 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4884 return RETURN_ERR;
4885
4886 wifi_getApEnable(radioIndex, &iface_status);
4887
4888 if (iface_status == TRUE)
4889 wifi_halGetIfStats(interface_name, &radioTrafficStats);
4890 else
4891 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
4892
4893 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
4894 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
4895 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
4896 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
4897 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
4898 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
4899 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
4900 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
4901
4902 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
4903 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].
4904 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
4905 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.
4906 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
4907 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
4908 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
4909 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
4910 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
4911
4912 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
4913 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
4914 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
4915 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.
4916
4917 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4918
4919 return RETURN_OK;
4920}
4921
4922//Set radio traffic static Measureing rules
4923INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
4924{
4925 //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
4926 // Else, save the MeasuringRate and MeasuringInterval for future usage
4927
4928 return RETURN_OK;
4929}
4930
4931//To start or stop RadioTrafficStats
4932INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
4933{
4934 //zqiu: If the RadioTrafficStats process running
4935 // if(enable)
4936 // return RETURN_OK.
4937 // else
4938 // Stop RadioTrafficStats process
developer69b61b02023-03-07 17:17:44 +08004939 // Else
developer72fb0bb2023-01-11 09:46:29 +08004940 // if(enable)
4941 // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds
4942 // else
4943 // return RETURN_OK.
4944
4945 return RETURN_OK;
4946}
4947
4948//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
4949INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
4950{
4951 //zqiu: Please ignor signalIndex.
developer69b61b02023-03-07 17:17:44 +08004952 if (NULL == SignalLevel)
developer72fb0bb2023-01-11 09:46:29 +08004953 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08004954
developer72fb0bb2023-01-11 09:46:29 +08004955 *SignalLevel=(radioIndex==0)?-19:-19;
4956
4957 return RETURN_OK;
4958}
4959
4960//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
4961INT wifi_applyRadioSettings(INT radioIndex)
4962{
4963 return RETURN_OK;
4964}
4965
4966//Get the radio index assocated with this SSID entry
4967INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
4968{
4969 if(NULL == radioIndex)
4970 return RETURN_ERR;
4971 int max_radio_num = 0;
4972 wifi_getMaxRadioNumber(&max_radio_num);
4973 *radioIndex = ssidIndex%max_radio_num;
4974 return RETURN_OK;
4975}
4976
4977//Device.WiFi.SSID.{i}.Enable
4978//Get SSID enable configuration parameters (not the SSID enable status)
4979INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
4980{
developer69b61b02023-03-07 17:17:44 +08004981 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08004982 return RETURN_ERR;
4983
4984 return wifi_getApEnable(ssidIndex, output_bool);
4985}
4986
4987//Device.WiFi.SSID.{i}.Enable
4988//Set SSID enable configuration parameters
4989INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
4990{
4991 return wifi_setApEnable(ssidIndex, enable);
4992}
4993
4994//Device.WiFi.SSID.{i}.Status
4995//Get the SSID enable status
4996INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
4997{
4998 char cmd[MAX_CMD_SIZE]={0};
4999 char buf[MAX_BUF_SIZE]={0};
5000 BOOL output_bool;
5001
5002 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5003 if (NULL == output_string)
5004 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08005005
developer72fb0bb2023-01-11 09:46:29 +08005006 wifi_getApEnable(ssidIndex,&output_bool);
5007 snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
5008
5009 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5010 return RETURN_OK;
5011}
5012
5013// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
5014INT wifi_getSSIDName(INT apIndex, CHAR *output)
5015{
5016 char config_file[MAX_BUF_SIZE] = {0};
5017
developer69b61b02023-03-07 17:17:44 +08005018 if (NULL == output)
developer72fb0bb2023-01-11 09:46:29 +08005019 return RETURN_ERR;
5020
5021 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5022 wifi_hostapdRead(config_file,"ssid",output,32);
5023
5024 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
5025 return RETURN_OK;
5026}
5027
developer69b61b02023-03-07 17:17:44 +08005028// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08005029INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
5030{
5031 char str[MAX_BUF_SIZE]={'\0'};
5032 char cmd[MAX_CMD_SIZE]={'\0'};
5033 struct params params;
5034 char config_file[MAX_BUF_SIZE] = {0};
5035
5036 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5037 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
5038 return RETURN_ERR;
5039
5040 params.name = "ssid";
5041 params.value = ssid_string;
5042 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5043 wifi_hostapdWrite(config_file, &params, 1);
5044 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5045 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5046
5047 return RETURN_OK;
5048}
5049
5050//Get the BSSID
5051INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
5052{
developer7e4a2a62023-04-06 19:56:03 +08005053 char cmd[MAX_CMD_SIZE] = {0};
5054 char inf_name[IF_NAME_SIZE] = {0};
5055 char conf_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005056
developer7e4a2a62023-04-06 19:56:03 +08005057 if (!output_string)
developer72fb0bb2023-01-11 09:46:29 +08005058 return RETURN_ERR;
5059
developer47cc27a2023-05-17 23:09:58 +08005060 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
5061 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08005062
developer5b2f10c2023-05-25 17:02:21 +08005063 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
5064 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
5065 strncpy(output_string, "\0", 1);
5066 return RETURN_ERR;
5067 }
5068 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
5069 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08005070
developer5b2f10c2023-05-25 17:02:21 +08005071 /* if hostapd does not control interface even if this interface has been brought up,
5072 * try to get its mac address by iw command.
5073 */
5074 if(strlen(output_string) == 0) {
5075 memset(cmd, 0, sizeof(cmd));
5076 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
5077 _syscmd(cmd, output_string, 64);
5078 }
developer72fb0bb2023-01-11 09:46:29 +08005079
developer5b2f10c2023-05-25 17:02:21 +08005080 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005081}
5082
5083//Get the MAC address associated with this Wifi SSID
5084INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
5085{
5086 wifi_getBaseBSSID(ssidIndex,output_string);
5087 return RETURN_OK;
5088}
5089
5090//Get the basic SSID traffic static info
5091//Apply SSID and AP (in the case of Acess Point devices) to the hardware
5092//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5093INT wifi_applySSIDSettings(INT ssidIndex)
5094{
5095 char interface_name[16] = {0};
5096 BOOL status = false;
5097 char cmd[MAX_CMD_SIZE] = {0};
5098 char buf[MAX_CMD_SIZE] = {0};
5099 int apIndex, ret;
5100 int max_radio_num = 0;
5101 int radioIndex = 0;
5102
5103 wifi_getMaxRadioNumber(&max_radio_num);
5104
5105 radioIndex = ssidIndex % max_radio_num;
5106
5107 wifi_getApEnable(ssidIndex,&status);
5108 // Do not apply when ssid index is disabled
5109 if (status == false)
5110 return RETURN_OK;
5111
5112 /* Doing full remove and add for ssid Index
5113 * Not all hostapd options are supported with reload
5114 * for example macaddr_acl
5115 */
5116 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
5117 return RETURN_ERR;
5118
5119 ret = wifi_setApEnable(ssidIndex,true);
5120
5121 /* Workaround for hostapd issue with multiple bss definitions
5122 * when first created interface will be removed
5123 * then all vaps other vaps on same phy are removed
5124 * after calling setApEnable to false readd all enabled vaps */
5125 for(int i=0; i < MAX_APS/max_radio_num; i++) {
5126 apIndex = max_radio_num*i+radioIndex;
5127 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5128 return RETURN_ERR;
5129 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
5130 _syscmd(cmd, buf, sizeof(buf));
5131 if(*buf == '1')
5132 wifi_setApEnable(apIndex, true);
5133 }
5134
5135 return ret;
5136}
5137
5138struct channels_noise {
5139 int channel;
5140 int noise;
5141};
5142
5143// Return noise array for each channel
5144int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
5145{
5146 char interface_name[16] = {0};
5147 FILE *f = NULL;
5148 char cmd[128] = {0};
5149 char line[256] = {0};
5150 size_t len = 0;
5151 ssize_t read = 0;
5152 int tmp = 0, arr_index = -1;
5153
5154 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5155 return RETURN_ERR;
5156 sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
5157
5158 if ((f = popen(cmd, "r")) == NULL) {
5159 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5160 return RETURN_ERR;
5161 }
developer69b61b02023-03-07 17:17:44 +08005162
developer72fb0bb2023-01-11 09:46:29 +08005163 while(fgets(line, sizeof(line), f) != NULL) {
5164 if(arr_index < channels_num){
5165 sscanf(line, "%d", &tmp);
5166 if (tmp > 0) { // channel frequency, the first line must be frequency
5167 arr_index++;
5168 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
5169 } else { // noise
5170 channels_noise_arr[arr_index].noise = tmp;
5171 }
5172 }else{
5173 break;
5174 }
5175 }
5176 pclose(f);
5177 return RETURN_OK;
5178}
5179
5180//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
5181//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08005182INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08005183{
5184 int index = -1;
5185 wifi_neighbor_ap2_t *scan_array = NULL;
5186 char cmd[256]={0};
5187 char buf[128]={0};
5188 char file_name[32] = {0};
5189 char filter_SSID[32] = {0};
5190 char line[256] = {0};
5191 char interface_name[16] = {0};
5192 char *ret = NULL;
5193 int freq=0;
5194 FILE *f = NULL;
5195 size_t len=0;
5196 int channels_num = 0;
5197 int vht_channel_width = 0;
5198 int get_noise_ret = RETURN_ERR;
5199 bool filter_enable = false;
5200 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
5201 int phyId = 0;
5202
5203 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
5204
5205 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5206 return RETURN_ERR;
5207
5208 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
5209 f = fopen(file_name, "r");
5210 if (f != NULL) {
5211 fgets(filter_SSID, sizeof(file_name), f);
5212 if (strlen(filter_SSID) != 0)
5213 filter_enable = true;
5214 fclose(f);
5215 }
5216
5217 phyId = radio_index_to_phy(radioIndex);
5218 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
5219 _syscmd(cmd, buf, sizeof(buf));
5220 channels_num = strtol(buf, NULL, 10);
5221
5222
5223
5224 sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
5225 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
5226 fprintf(stderr, "cmd: %s\n", cmd);
5227 if ((f = popen(cmd, "r")) == NULL) {
5228 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5229 return RETURN_ERR;
5230 }
developer69b61b02023-03-07 17:17:44 +08005231
developer72fb0bb2023-01-11 09:46:29 +08005232 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
5233 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08005234
developer72fb0bb2023-01-11 09:46:29 +08005235 ret = fgets(line, sizeof(line), f);
5236 while (ret != NULL) {
5237 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +08005238 // 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 +08005239 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
5240 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
5241
5242 if (!filter_BSS) {
5243 index++;
5244 wifi_neighbor_ap2_t *tmp;
5245 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
5246 if (tmp == NULL) { // no more memory to use
5247 index--;
5248 wifi_dbg_printf("%s: realloc failed\n", __func__);
5249 break;
5250 }
5251 scan_array = tmp;
5252 }
5253 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5254
5255 filter_BSS = false;
5256 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
5257 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
5258 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
5259 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
5260 } else if (strstr(line, "freq") != NULL) {
5261 sscanf(line," freq: %d", &freq);
5262 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
5263
5264 if (freq >= 2412 && freq <= 2484) {
5265 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
5266 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
5267 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
5268 }
5269 else if (freq >= 5160 && freq <= 5805) {
5270 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
5271 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
5272 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
5273 }
5274
5275 scan_array[index].ap_Noise = 0;
5276 if (get_noise_ret == RETURN_OK) {
5277 for (int i = 0; i < channels_num; i++) {
5278 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
5279 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
5280 break;
5281 }
5282 }
5283 }
5284 } else if (strstr(line, "beacon interval") != NULL) {
5285 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
5286 } else if (strstr(line, "signal") != NULL) {
5287 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
5288 } else if (strstr(line,"SSID") != NULL) {
5289 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
5290 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
5291 filter_BSS = true;
5292 }
5293 } else if (strstr(line, "Supported rates") != NULL) {
5294 char SRate[80] = {0}, *tmp = NULL;
5295 memset(buf, 0, sizeof(buf));
5296 strcpy(SRate, line);
5297 tmp = strtok(SRate, ":");
5298 tmp = strtok(NULL, ":");
5299 strcpy(buf, tmp);
5300 memset(SRate, 0, sizeof(SRate));
5301
5302 tmp = strtok(buf, " \n");
5303 while (tmp != NULL) {
5304 strcat(SRate, tmp);
5305 if (SRate[strlen(SRate) - 1] == '*') {
5306 SRate[strlen(SRate) - 1] = '\0';
5307 }
5308 strcat(SRate, ",");
5309
5310 tmp = strtok(NULL, " \n");
5311 }
5312 SRate[strlen(SRate) - 1] = '\0';
5313 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
5314 } else if (strstr(line, "DTIM") != NULL) {
5315 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
5316 } else if (strstr(line, "VHT capabilities") != NULL) {
5317 strcat(scan_array[index].ap_SupportedStandards, ",ac");
5318 strcpy(scan_array[index].ap_OperatingStandards, "ac");
5319 } else if (strstr(line, "HT capabilities") != NULL) {
5320 strcat(scan_array[index].ap_SupportedStandards, ",n");
5321 strcpy(scan_array[index].ap_OperatingStandards, "n");
5322 } else if (strstr(line, "VHT operation") != NULL) {
5323 ret = fgets(line, sizeof(line), f);
5324 sscanf(line," * channel width: %d", &vht_channel_width);
5325 if(vht_channel_width == 1) {
5326 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
5327 } else {
5328 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
5329 }
5330 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5331 continue;
5332 } else if (strstr(line, "HT operation") != NULL) {
5333 ret = fgets(line, sizeof(line), f);
5334 sscanf(line," * secondary channel offset: %s", &buf);
5335 if (!strcmp(buf, "above")) {
5336 //40Mhz +
5337 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
5338 }
5339 else if (!strcmp(buf, "below")) {
5340 //40Mhz -
5341 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
5342 } else {
5343 //20Mhz
5344 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
5345 }
5346 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5347 continue;
5348 } else if (strstr(line, "HE capabilities") != NULL) {
5349 strcat(scan_array[index].ap_SupportedStandards, ",ax");
5350 strcpy(scan_array[index].ap_OperatingStandards, "ax");
5351 ret = fgets(line, sizeof(line), f);
5352 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
5353 if (strstr(line, "HE40/2.4GHz") != NULL)
5354 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
5355 else
5356 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
5357 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
5358 if (strstr(line, "HE80/5GHz") != NULL) {
5359 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
5360 ret = fgets(line, sizeof(line), f);
5361 } else
5362 continue;
5363 if (strstr(line, "HE160/5GHz") != NULL)
5364 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
5365 }
5366 continue;
5367 } else if (strstr(line, "WPA") != NULL) {
5368 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
5369 } else if (strstr(line, "RSN") != NULL) {
5370 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
5371 } else if (strstr(line, "Group cipher") != NULL) {
5372 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
5373 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
5374 strcpy(scan_array[index].ap_EncryptionMode, "AES");
5375 }
5376 }
5377 ret = fgets(line, sizeof(line), f);
5378 }
5379
5380 if (!filter_BSS) {
5381 *output_array_size = index + 1;
5382 } else {
5383 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5384 *output_array_size = index;
5385 }
5386 *neighbor_ap_array = scan_array;
5387 pclose(f);
5388 free(channels_noise_arr);
5389 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5390 return RETURN_OK;
5391}
5392
5393//>> Deprecated: used for old RDKB code.
5394INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
5395{
5396 INT status = RETURN_ERR;
5397
5398 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5399 output_struct->wifi_PLCPErrorCount = 0;
5400 output_struct->wifi_FCSErrorCount = 0;
5401 output_struct->wifi_InvalidMACCount = 0;
5402 output_struct->wifi_PacketsOtherReceived = 0;
5403 output_struct->wifi_Noise = 0;
5404 status = RETURN_OK;
5405 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5406 return status;
5407}
5408
5409INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
5410{
5411 char interface_name[16] = {0};
5412 char cmd[128] = {0};
5413 char buf[1280] = {0};
5414 char *pos = NULL;
5415
5416 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5417 if (NULL == output_struct)
5418 return RETURN_ERR;
5419
5420 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5421 return RETURN_ERR;
5422
5423 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5424
5425 snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
5426 _syscmd(cmd, buf, sizeof(buf));
5427
5428 pos = buf;
5429 if ((pos = strstr(pos, "RX packets:")) == NULL)
5430 return RETURN_ERR;
5431 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
5432
5433 if ((pos = strstr(pos, "TX packets:")) == NULL)
5434 return RETURN_ERR;
5435 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
5436
5437 if ((pos = strstr(pos, "RX bytes:")) == NULL)
5438 return RETURN_ERR;
5439 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
5440
5441 if ((pos = strstr(pos, "TX bytes:")) == NULL)
5442 return RETURN_ERR;
5443 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
5444
5445 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
5446 _syscmd(cmd, buf, sizeof(buf));
5447 sscanf(buf, "%lu", &output_struct->wifi_Associations);
5448
5449#if 0
5450 //TODO: need to revisit below implementation
5451 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5452 char interface_name[MAX_BUF_SIZE] = {0};
5453 char interface_status[MAX_BUF_SIZE] = {0};
5454 char Value[MAX_BUF_SIZE] = {0};
5455 char buf[MAX_CMD_SIZE] = {0};
5456 char cmd[MAX_CMD_SIZE] = {0};
5457 FILE *fp = NULL;
5458
5459 if (NULL == output_struct) {
5460 return RETURN_ERR;
5461 }
5462
5463 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5464
5465 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
5466 {
5467 if(apIndex == 0) //private_wifi for 2.4G
5468 {
5469 wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
5470 }
5471 else if(apIndex == 1) //private_wifi for 5G
5472 {
5473 wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
5474 }
5475 else if(apIndex == 4) //public_wifi for 2.4G
5476 {
5477 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
5478 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
5479 {
5480 return RETURN_ERR;
5481 }
5482 if(buf[0] == '#')//tp-link
5483 wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
5484 else//tenda
5485 wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name);
5486 }
5487 else if(apIndex == 5) //public_wifi for 5G
5488 {
5489 wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
5490 }
5491
5492 GetIfacestatus(interface_name, interface_status);
5493
5494 if(0 != strcmp(interface_status, "1"))
5495 return RETURN_ERR;
5496
5497 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5498 system(cmd);
5499
5500 fp = fopen("/tmp/SSID_Stats.txt", "r");
5501 if(fp == NULL)
5502 {
5503 printf("/tmp/SSID_Stats.txt not exists \n");
5504 return RETURN_ERR;
5505 }
5506 fclose(fp);
5507
5508 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5509 File_Reading(buf, Value);
5510 output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10);
5511
5512 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5513 File_Reading(buf, Value);
5514 output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10);
5515
5516 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5517 File_Reading(buf, Value);
5518 output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10);
5519
5520 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5521 File_Reading(buf, Value);
5522 output_struct->wifi_BytesSent = strtoul(Value, NULL, 10);
5523
5524 /* There is no specific parameter from caller to associate the value wifi_Associations */
5525 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);
5526 //_syscmd(cmd, buf, sizeof(buf));
5527 //sscanf(buf,"%lu", &output_struct->wifi_Associations);
5528 }
5529#endif
5530 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5531 return RETURN_OK;
5532}
5533
5534INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
5535{
5536 char interface_name[MAX_BUF_SIZE] = {0};
5537 char interface_status[MAX_BUF_SIZE] = {0};
5538 char Value[MAX_BUF_SIZE] = {0};
5539 char buf[MAX_CMD_SIZE] = {0};
5540 char cmd[MAX_CMD_SIZE] = {0};
5541 FILE *fp = NULL;
5542
5543 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5544 if (NULL == output_struct)
5545 return RETURN_ERR;
5546
5547 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
5548
5549 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
5550 return RETURN_ERR;
5551 GetIfacestatus(interface_name, interface_status);
5552
5553 if(0 != strcmp(interface_status, "1"))
5554 return RETURN_ERR;
5555
5556 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5557 system(cmd);
5558
5559 fp = fopen("/tmp/SSID_Stats.txt", "r");
5560 if(fp == NULL)
5561 {
5562 printf("/tmp/SSID_Stats.txt not exists \n");
5563 return RETURN_ERR;
5564 }
5565 fclose(fp);
5566
5567 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5568 File_Reading(buf, Value);
5569 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
5570
5571 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5572 File_Reading(buf, Value);
5573 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
5574
5575 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5576 File_Reading(buf, Value);
5577 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
5578
5579 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5580 File_Reading(buf, Value);
5581 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
5582
5583 output_struct->wifi_UnicastPacketsSent = 0;
5584 output_struct->wifi_UnicastPacketsReceived = 0;
5585 output_struct->wifi_MulticastPacketsSent = 0;
5586 output_struct->wifi_MulticastPacketsReceived = 0;
5587 output_struct->wifi_BroadcastPacketsSent = 0;
5588 output_struct->wifi_BroadcastPacketsRecevied = 0;
5589 output_struct->wifi_UnknownPacketsReceived = 0;
5590
5591 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5592 return RETURN_OK;
5593}
5594
5595INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
5596{
5597 INT status = RETURN_ERR;
5598
5599 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5600 //Below values should get updated from hal
5601 output_struct->wifi_RetransCount=0;
5602 output_struct->wifi_FailedRetransCount=0;
5603 output_struct->wifi_RetryCount=0;
5604 output_struct->wifi_MultipleRetryCount=0;
5605 output_struct->wifi_ACKFailureCount=0;
5606 output_struct->wifi_AggregatedPacketCount=0;
5607
5608 status = RETURN_OK;
5609 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5610
5611 return status;
5612}
5613
5614INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
5615{
5616 INT status = RETURN_ERR;
5617 UINT index;
5618 wifi_neighbor_ap_t *pt=NULL;
5619
5620 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5621 *output_array_size=2;
5622 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
5623 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
5624 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
5625 strcpy(pt->ap_Radio,"");
5626 strcpy(pt->ap_SSID,"");
5627 strcpy(pt->ap_BSSID,"");
5628 strcpy(pt->ap_Mode,"");
5629 pt->ap_Channel=1;
5630 pt->ap_SignalStrength=0;
5631 strcpy(pt->ap_SecurityModeEnabled,"");
5632 strcpy(pt->ap_EncryptionMode,"");
5633 strcpy(pt->ap_OperatingFrequencyBand,"");
5634 strcpy(pt->ap_SupportedStandards,"");
5635 strcpy(pt->ap_OperatingStandards,"");
5636 strcpy(pt->ap_OperatingChannelBandwidth,"");
5637 pt->ap_BeaconPeriod=1;
5638 pt->ap_Noise=0;
5639 strcpy(pt->ap_BasicDataTransferRates,"");
5640 strcpy(pt->ap_SupportedDataTransferRates,"");
5641 pt->ap_DTIMPeriod=1;
5642 pt->ap_ChannelUtilization = 1;
5643 }
5644
5645 status = RETURN_OK;
5646 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5647
5648 return status;
5649}
5650
5651//----------------- AP HAL -------------------------------
5652
5653//>> Deprecated: used for old RDKB code.
5654INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
5655{
5656 if (NULL == output_ulong || NULL == output_struct)
5657 return RETURN_ERR;
5658 *output_ulong = 0;
5659 *output_struct = NULL;
5660 return RETURN_OK;
5661}
5662
5663#ifdef HAL_NETLINK_IMPL
5664static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
5665 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5666 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5667 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
5668 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
5669 char mac_addr[20];
5670 static int count=0;
5671 int rate=0;
5672
5673 wifi_device_info_t *out = (wifi_device_info_t*)arg;
5674
5675 nla_parse(tb,
5676 NL80211_ATTR_MAX,
5677 genlmsg_attrdata(gnlh, 0),
5678 genlmsg_attrlen(gnlh, 0),
5679 NULL);
5680
5681 if(!tb[NL80211_ATTR_STA_INFO]) {
5682 fprintf(stderr, "sta stats missing!\n");
5683 return NL_SKIP;
5684 }
5685
5686
5687 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
5688 fprintf(stderr, "failed to parse nested attributes!\n");
5689 return NL_SKIP;
5690 }
5691
5692 //devIndex starts from 1
5693 if( ++count == out->wifi_devIndex )
5694 {
5695 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
5696 //Getting the mac addrress
5697 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
5698
5699 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
5700 fprintf(stderr, "failed to parse nested rate attributes!");
5701 return NL_SKIP;
5702 }
5703
5704 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
5705 if(rinfo[NL80211_RATE_INFO_BITRATE])
5706 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5707 out->wifi_devTxRate = rate/10;
5708 }
5709
5710 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
5711 fprintf(stderr, "failed to parse nested rate attributes!");
5712 return NL_SKIP;
5713 }
5714
5715 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
5716 if(rinfo[NL80211_RATE_INFO_BITRATE])
5717 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5718 out->wifi_devRxRate = rate/10;
5719 }
5720 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
5721 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
5722
5723 out->wifi_devAssociatedDeviceAuthentiationState = 1;
5724 count = 0; //starts the count for next cycle
5725 return NL_STOP;
5726 }
5727
5728 return NL_SKIP;
5729
5730}
5731#endif
5732
5733INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
5734{
5735#ifdef HAL_NETLINK_IMPL
5736 Netlink nl = {0};
5737 char if_name[10] = {0};
5738 char interface_name[16] = {0};
5739
5740 wifi_device_info_t info = {0};
5741 info.wifi_devIndex = devIndex;
5742
5743 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5744 return RETURN_ERR;
5745
5746 snprintf(if_name,sizeof(if_name),"%s", interface_name);
5747
5748 nl.id = initSock80211(&nl);
5749
5750 if (nl.id < 0) {
5751 fprintf(stderr, "Error initializing netlink \n");
5752 return -1;
5753 }
5754
5755 struct nl_msg* msg = nlmsg_alloc();
5756
5757 if (!msg) {
5758 fprintf(stderr, "Failed to allocate netlink message.\n");
5759 nlfree(&nl);
5760 return -2;
5761 }
5762
5763 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +08005764 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +08005765 NL_AUTO_SEQ,
5766 nl.id,
5767 0,
5768 NLM_F_DUMP,
5769 NL80211_CMD_GET_STATION,
5770 0);
5771
5772 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +08005773 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +08005774 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
5775 nl_recvmsgs(nl.socket, nl.cb);
5776 nlmsg_free(msg);
5777 nlfree(&nl);
5778
5779 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
5780 output_struct->wifi_devRxRate = info.wifi_devRxRate;
5781 output_struct->wifi_devTxRate = info.wifi_devTxRate;
5782 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
5783 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
5784 return RETURN_OK;
5785#else
5786 //iw utility to retrieve station information
5787#define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt"
5788#define SIGNALFILE "/tmp/wifi_signalstrength.txt"
5789#define MACFILE "/tmp/wifi_AssoMac.txt"
5790#define TXRATEFILE "/tmp/wifi_txrate.txt"
5791#define RXRATEFILE "/tmp/wifi_rxrate.txt"
5792 FILE *file = NULL;
5793 char if_name[10] = {'\0'};
5794 char pipeCmd[256] = {'\0'};
5795 char line[256] = {0};
5796 char interface_name[16] = {0};
5797 int count = 0, device = 0;
5798
5799 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5800 return RETURN_ERR;
5801
5802 snprintf(if_name,sizeof(if_name),"%s", interface_name);
5803
5804 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name);
5805 file = popen(pipeCmd, "r");
5806
5807 if(file == NULL)
5808 return RETURN_ERR; //popen failed
5809
5810 fgets(line, sizeof line, file);
5811 device = atoi(line);
5812 pclose(file);
5813
5814 if(device == 0)
5815 return RETURN_ERR; //No devices are connected
5816
5817 sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name);
5818 system(pipeCmd);
5819
5820 system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE);
5821
5822 system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE);
5823
5824 system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE);
5825
5826 system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE);
5827
5828 //devIndex starts from 1, ++count
5829 if((file = fopen(SIGNALFILE, "r")) != NULL )
5830 {
5831 for(count =0;fgets(line, sizeof line, file) != NULL;)
5832 {
5833 if (++count == devIndex)
5834 {
5835 output_struct->wifi_devSignalStrength = atoi(line);
5836 break;
5837 }
5838 }
5839 fclose(file);
5840 }
5841 else
5842 fprintf(stderr,"fopen wifi_signalstrength.txt failed");
5843
5844 if((file = fopen(MACFILE, "r")) != NULL )
5845 {
5846 for(count =0;fgets(line, sizeof line, file) != NULL;)
5847 {
5848 if (++count == devIndex)
5849 {
5850 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]);
5851 break;
5852 }
5853 }
5854 fclose(file);
5855 }
5856 else
5857 fprintf(stderr,"fopen wifi_AssoMac.txt failed");
5858
5859 if((file = fopen(TXRATEFILE, "r")) != NULL )
5860 {
5861 for(count =0;fgets(line, sizeof line, file) != NULL;)
5862 {
5863 if (++count == devIndex)
5864 {
5865 output_struct->wifi_devTxRate = atoi(line);
5866 break;
5867 }
5868 }
5869 fclose(file);
5870 }
5871 else
5872 fprintf(stderr,"fopen wifi_txrate.txt failed");
5873
5874 if((file = fopen(RXRATEFILE, "r")) != NULL)
5875 {
5876 for(count =0;fgets(line, sizeof line, file) != NULL;)
5877 {
5878 if (++count == devIndex)
5879 {
5880 output_struct->wifi_devRxRate = atoi(line);
5881 break;
5882 }
5883 }
5884 fclose(file);
5885 }
5886 else
5887 fprintf(stderr,"fopen wifi_rxrate.txt failed");
5888
5889 output_struct->wifi_devAssociatedDeviceAuthentiationState = 1;
5890
5891 return RETURN_OK;
5892#endif
5893}
5894
5895INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
5896{
5897 if (NULL == device)
5898 return RETURN_ERR;
5899 return RETURN_OK;
5900}
5901//<<
5902
5903
5904//--------------wifi_ap_hal-----------------------------
5905//enables CTS protection for the radio used by this AP
5906INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
5907{
5908 //save config and Apply instantly
5909 return RETURN_ERR;
5910}
5911
5912// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
5913INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
5914{
5915 char config_file[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08005916 char config_dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08005917 char buf[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08005918 struct params list = {0};
5919 struct params dat = {0};
5920 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08005921
5922 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5923 list.name = "ht_coex";
5924 snprintf(buf, sizeof(buf), "%d", enable);
5925 list.value = buf;
5926
developerd1824452023-05-18 12:30:04 +08005927 dat.name = "HT_BSSCoexistence";
5928 dat.value = buf;
5929
5930 band = wifi_index_to_band(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08005931 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd1824452023-05-18 12:30:04 +08005932 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08005933 wifi_hostapdWrite(config_file, &list, 1);
developer262f4cb2023-05-24 12:22:04 +08005934 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08005935 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5936
5937 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5938
5939 return RETURN_OK;
5940}
5941
5942//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
5943INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
5944{
5945 char config_file[MAX_BUF_SIZE] = {'\0'};
5946 char buf[MAX_BUF_SIZE] = {'\0'};
5947 struct params list;
5948
5949 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5950 if (threshold < 256 || threshold > 2346 )
5951 return RETURN_ERR;
5952 list.name = "fragm_threshold";
5953 snprintf(buf, sizeof(buf), "%d", threshold);
5954 list.value = buf;
5955
5956 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5957 wifi_hostapdWrite(config_file, &list, 1);
5958 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5959
5960 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5961
5962 return RETURN_OK;
5963}
5964
5965// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
5966INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
5967{
5968 char config_file[64] = {'\0'};
5969 char cmd[512] = {'\0'};
5970 char buf[512] = {'\0'};
5971 char stbc_config[16] = {'\0'};
5972 wifi_band band;
5973 int iterator = 0;
5974 BOOL current_stbc = FALSE;
5975 int ant_count = 0;
5976 int ant_bitmap = 0;
5977 struct params list;
developera1255e42023-05-13 17:45:02 +08005978 char dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08005979
5980 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5981
5982 band = wifi_index_to_band(radioIndex);
5983 if (band == band_invalid)
5984 return RETURN_ERR;
5985
5986 if (band == band_2_4)
5987 iterator = 1;
developera1255e42023-05-13 17:45:02 +08005988 else if ((band == band_5) || (band == band_6))
developer72fb0bb2023-01-11 09:46:29 +08005989 iterator = 2;
5990 else
5991 return RETURN_OK;
5992
5993 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
5994 for (; ant_bitmap > 0; ant_bitmap >>= 1)
5995 ant_count += ant_bitmap & 1;
5996
5997 if (ant_count == 1 && STBC_Enable == TRUE) {
5998 fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__);
5999 return RETURN_OK;
6000 }
6001
6002 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6003
6004 // set ht and vht config
6005 for (int i = 0; i < iterator; i++) {
6006 memset(stbc_config, 0, sizeof(stbc_config));
6007 memset(cmd, 0, sizeof(cmd));
6008 memset(buf, 0, sizeof(buf));
6009 list.name = (i == 0)?"ht_capab":"vht_capab";
6010 snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
6011 snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
6012 _syscmd(cmd, buf, sizeof(buf));
6013 if (strlen(buf) != 0)
6014 current_stbc = TRUE;
6015 if (current_stbc == STBC_Enable)
6016 continue;
6017
6018 if (STBC_Enable == TRUE) {
6019 // Append the STBC flags in capab config
6020 memset(cmd, 0, sizeof(cmd));
6021 if (i == 0)
6022 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
6023 else
6024 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
6025 _syscmd(cmd, buf, sizeof(buf));
6026 } else if (STBC_Enable == FALSE) {
6027 // Remove the STBC flags and remain other flags in capab
6028 memset(cmd, 0, sizeof(cmd));
6029 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6030 _syscmd(cmd, buf, sizeof(buf));
6031 memset(cmd, 0, sizeof(cmd));
6032 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
6033 _syscmd(cmd, buf, sizeof(buf));
6034 }
6035 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
6036 list.value = buf;
6037 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
6038 }
developera1255e42023-05-13 17:45:02 +08006039 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6040 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
6041 _syscmd(cmd, buf, sizeof(buf));
6042 if ((band == band_5) || (band == band_6)) {
6043 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
6044 _syscmd(cmd, buf, sizeof(buf));
6045 }
6046 /*wifi_reloadAp(radioIndex);
6047 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08006048
6049 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6050 return RETURN_OK;
6051}
6052
6053// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
6054INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
6055{
developer2c22d832023-05-18 17:46:26 +08006056 char dat_file[128] = {0};
6057 BOOL enable;
6058 wifi_band band;
6059 char amdus_buff[8] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006060
developer2c22d832023-05-18 17:46:26 +08006061 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006062
developer2c22d832023-05-18 17:46:26 +08006063 band = wifi_index_to_band(radioIndex);
6064 if (band == band_invalid) {
6065 printf("%s:Band Error\n", __func__);
6066 return RETURN_ERR;
6067 }
6068 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6069 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6070 if (strncmp(amdus_buff, "1", 1) == 0)
developer72fb0bb2023-01-11 09:46:29 +08006071 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08006072 else
6073 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006074
developer2c22d832023-05-18 17:46:26 +08006075 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6076
6077 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006078}
6079
6080// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
6081INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
6082{
developer2c22d832023-05-18 17:46:26 +08006083 char dat_file[128] = {0};
6084 BOOL enable;
6085 wifi_band band;
6086 char amdus_buff[8] = {'\0'};
6087 struct params params = {0};
developer72fb0bb2023-01-11 09:46:29 +08006088
developer2c22d832023-05-18 17:46:26 +08006089 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006090
developer2c22d832023-05-18 17:46:26 +08006091 band = wifi_index_to_band(radioIndex);
6092 if (band == band_invalid) {
6093 printf("%s:Band Error\n", __func__);
6094 return RETURN_ERR;
6095 }
6096 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6097 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6098 if (strncmp(amdus_buff, "1", 1) == 0)
6099 enable = TRUE;
6100 else
6101 enable = FALSE;
6102 if (amsduEnable == enable)
6103 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006104
developer2c22d832023-05-18 17:46:26 +08006105 params.name = "HT_AMSDU";
6106 if (amsduEnable)
6107 params.value = "1";
6108 else
6109 params.value = "0";
6110 wifi_datfileWrite(dat_file, &params, 1);
6111 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006112
developer2c22d832023-05-18 17:46:26 +08006113 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006114
developer72fb0bb2023-01-11 09:46:29 +08006115 return RETURN_OK;
6116}
6117
6118//P2 // outputs the number of Tx streams
6119INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
6120{
6121 char buf[8] = {0};
6122 char cmd[128] = {0};
6123 int phyId = 0;
6124
6125 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6126
6127 phyId = radio_index_to_phy(radioIndex);
6128 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
6129 _syscmd(cmd, buf, sizeof(buf));
6130
6131 *output_int = (INT)strtol(buf, NULL, 16);
6132
6133 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6134
6135 return RETURN_OK;
6136}
6137
6138INT fitChainMask(INT radioIndex, int antcount)
6139{
6140 char buf[128] = {0};
6141 char cmd[128] = {0};
6142 char config_file[64] = {0};
6143 wifi_band band;
6144 struct params list[2] = {0};
6145
6146 band = wifi_index_to_band(radioIndex);
6147 if (band == band_invalid)
6148 return RETURN_ERR;
6149
6150 list[0].name = "he_mu_beamformer";
6151 list[1].name = "he_su_beamformer";
6152
6153 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6154 if (antcount == 1) {
6155 // remove config about multiple antennas
6156 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6157 _syscmd(cmd, buf, sizeof(buf));
6158
6159 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
6160 _syscmd(cmd, buf, sizeof(buf));
6161
6162 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
6163 _syscmd(cmd, buf, sizeof(buf));
6164
6165 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
6166 _syscmd(cmd, buf, sizeof(buf));
6167
6168 list[0].value = "0";
6169 list[1].value = "0";
6170 } else {
6171 // 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.
6172 if (band == band_2_4 || band == band_5) {
6173 snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6174 _syscmd(cmd, buf, sizeof(buf));
6175 if (strlen(buf) > 0) {
6176 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
6177 _syscmd(cmd, buf, sizeof(buf));
6178 }
6179 }
6180 if (band == band_5) {
6181 snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6182 _syscmd(cmd, buf, sizeof(buf));
6183 if (strlen(buf) > 0) {
6184 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
6185 _syscmd(cmd, buf, sizeof(buf));
6186 }
6187 }
6188
6189 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
6190 _syscmd(cmd, buf, sizeof(buf));
6191 if (strlen(buf) == 0) {
6192 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
6193 _syscmd(cmd, buf, sizeof(buf));
6194 }
6195
6196 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
6197 _syscmd(cmd, buf, sizeof(buf));
6198 if (strlen(buf) == 0) {
6199 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
6200 _syscmd(cmd, buf, sizeof(buf));
6201 }
6202
6203 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
6204 _syscmd(cmd, buf, sizeof(buf));
6205 if (strlen(buf) == 0) {
6206 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
6207 } else {
6208 snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
6209 }
6210 _syscmd(cmd, buf, sizeof(buf));
6211
6212 list[0].value = "1";
6213 list[1].value = "1";
6214 }
6215 wifi_hostapdWrite(config_file, list, 2);
6216}
6217
6218//P2 // sets the number of Tx streams to an enviornment variable
6219INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
6220{
6221 char cmd[128] = {0};
6222 char buf[128] = {0};
6223 int phyId = 0;
6224 int cur_mask = 0;
developera1255e42023-05-13 17:45:02 +08006225 int antcountmsk = 0;
6226 INT cur_nss = 0;
6227 UCHAR dat_file[64] = {0};
6228 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08006229
6230 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6231
6232 if (numStreams <= 0) {
6233 fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams);
6234 return RETURN_ERR;
6235 }
6236
developera1255e42023-05-13 17:45:02 +08006237 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
6238 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
6239 cur_nss += 1;
6240 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
6241 if (cur_nss == numStreams)
developer72fb0bb2023-01-11 09:46:29 +08006242 return RETURN_OK;
6243
6244 wifi_setRadioEnable(radioIndex, FALSE);
6245
6246 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08006247 //iw need mask value.
6248 for (;numStreams > 0; numStreams--)
6249 antcountmsk |= 0x1 << (numStreams - 1);
6250 snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
developer72fb0bb2023-01-11 09:46:29 +08006251 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006252 if (strlen(buf) > 0) {
6253 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6254 return RETURN_ERR;
6255 }
developera1255e42023-05-13 17:45:02 +08006256 band = wifi_index_to_band(radioIndex);
6257 if (band == band_invalid) {
6258 printf("%s:Band Error\n", __func__);
6259 return RETURN_ERR;
6260 }
6261 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6262 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
6263 _syscmd(cmd, buf, sizeof(buf));
6264 if (strlen(buf) > 0) {
6265 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6266 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006267 }
developera1255e42023-05-13 17:45:02 +08006268 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
6269 _syscmd(cmd, buf, sizeof(buf));
6270 if (strlen(buf) > 0) {
6271 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6272 return RETURN_ERR;
6273 }
6274 fitChainMask(radioIndex, numStreams);
developer72fb0bb2023-01-11 09:46:29 +08006275 wifi_setRadioEnable(radioIndex, TRUE);
6276
6277 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6278 return RETURN_OK;
6279}
6280
6281//P2 // outputs the number of Rx streams
6282INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
6283{
6284 char buf[8] = {0};
6285 char cmd[128] = {0};
6286 int phyId = 0;
6287
6288 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6289
6290 phyId = radio_index_to_phy(radioIndex);
6291 sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
6292 _syscmd(cmd, buf, sizeof(buf));
6293
6294 *output_int = (INT)strtol(buf, NULL, 16);
6295
6296 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6297
6298 return RETURN_OK;
6299}
6300
6301//P2 // sets the number of Rx streams to an enviornment variable
6302INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
6303{
6304 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6305 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
6306 fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__);
6307 return RETURN_ERR;
6308 }
6309 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6310 return RETURN_ERR;
6311}
6312
6313//Get radio RDG enable setting
6314INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
6315{
developer47cc27a2023-05-17 23:09:58 +08006316 if (NULL == output_bool)
6317 return RETURN_ERR;
6318
6319 *output_bool = TRUE;
6320 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006321}
6322
6323//Get radio RDG enable setting
6324INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
6325{
developer47cc27a2023-05-17 23:09:58 +08006326 char cmd[MAX_CMD_SIZE] = {0};
6327 char buf[MAX_BUF_SIZE] = {0};
6328 char rdg_status[2] = {0};
6329 char dat_file[MAX_CMD_SIZE] = {0};
6330 struct params params = {0};
6331
6332 if (NULL == output_bool)
6333 return RETURN_ERR;
6334
6335 /*prepare dat file path*/
6336 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6337
6338 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
6339 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
6340 *output_bool = TRUE;
6341 else
6342 *output_bool = FALSE;
6343
6344 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006345}
6346
6347//Set radio RDG enable setting
6348INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
6349{
developer47cc27a2023-05-17 23:09:58 +08006350 char cmd[MAX_CMD_SIZE] = {0};
6351 char buf[MAX_BUF_SIZE] = {0};
6352 char dat_file[MAX_CMD_SIZE] = {0};
6353 struct params params = {0};
6354
6355 /*prepare dat file path*/
6356 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6357
6358 params.name = "HT_RDG";
6359
6360 if (enable) {
6361 params.value = "1";
6362 } else {
6363 params.value = "0";
6364 }
6365
6366 wifi_datfileWrite(dat_file, &params, 1);
6367
6368 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006369}
6370
6371//Get radio ADDBA enable setting
6372INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
6373{
developer8e6583c2023-05-23 13:36:06 +08006374 char interface_name[16] = {0};
6375 char cmd[128]={0};
6376 char buf[10]={0};
6377 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6378
6379 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08006380 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08006381
6382 snprintf(cmd, sizeof(cmd), "mwctl %s set ba_decline s", interface_name);
6383 _syscmd(cmd, buf, sizeof(buf));
6384
6385 if (strncmp(buf, "enabled", 7) == 0)
6386 *output_bool = TRUE;
6387 else
6388 *output_bool = FALSE;
6389
6390 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6391
developer72fb0bb2023-01-11 09:46:29 +08006392 return RETURN_OK;
6393}
6394
6395//Set radio ADDBA enable setting
6396INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
6397{
6398 return RETURN_ERR;
6399}
6400
6401//Get radio auto block ack enable setting
6402INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
6403{
developer8e6583c2023-05-23 13:36:06 +08006404 char interface_name[16] = {0};
6405 char cmd[128]={0};
6406 char buf[10]={0};
6407 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6408
6409 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08006410 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08006411
6412 snprintf(cmd, sizeof(cmd), "mwctl %s set ba_auto s", interface_name);
6413 _syscmd(cmd, buf, sizeof(buf));
6414 if (strncmp(buf, "enabled", 7) == 0)
6415 *output_bool = TRUE;
6416 else
6417 *output_bool = FALSE;
6418
6419 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6420
developer72fb0bb2023-01-11 09:46:29 +08006421 return RETURN_OK;
6422}
6423
6424//Set radio auto block ack enable setting
6425INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
6426{
6427 return RETURN_ERR;
6428}
6429
6430//Get radio 11n pure mode enable support
6431INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
6432{
6433 if (NULL == output_bool)
6434 return RETURN_ERR;
6435 *output_bool = TRUE;
6436 return RETURN_OK;
6437}
6438
6439//Get radio 11n pure mode enable setting
6440INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
6441{
6442 if (NULL == output_bool)
6443 return RETURN_ERR;
6444 *output_bool = TRUE;
6445 return RETURN_OK;
6446}
6447
6448//Set radio 11n pure mode enable setting
6449INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
6450{
6451 return RETURN_ERR;
6452}
6453
6454//Get radio IGMP snooping enable setting
6455INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
6456{
6457 char interface_name[16] = {0};
6458 char cmd[128]={0};
developer8e6583c2023-05-23 13:36:06 +08006459 char buf[10]={0};
developer72fb0bb2023-01-11 09:46:29 +08006460 bool bridge = FALSE, mac80211 = FALSE;
6461 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6462
developer72fb0bb2023-01-11 09:46:29 +08006463 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6464 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006465
developer8e6583c2023-05-23 13:36:06 +08006466 snprintf(cmd, sizeof(cmd), "mwctl %s set multicast_snooping enable=s", interface_name);
6467 _syscmd(cmd, buf, sizeof(buf));
6468 if (strncmp(buf, "enabled", 7) == 0)
developer72fb0bb2023-01-11 09:46:29 +08006469 *output_bool = TRUE;
developer8e6583c2023-05-23 13:36:06 +08006470 else
6471 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006472
6473 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6474 return RETURN_OK;
6475}
6476
6477//Set radio IGMP snooping enable setting
6478INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
6479{
6480 char interface_name[16] = {0};
6481 char cmd[128]={0};
6482 char buf[4]={0};
developer72fb0bb2023-01-11 09:46:29 +08006483
developer8e6583c2023-05-23 13:36:06 +08006484 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6485 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6486 return RETURN_ERR;
6487 snprintf(cmd, sizeof(cmd), "mwctl %s set multicast_snooping enable=1", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08006488 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006489 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6490 return RETURN_OK;
6491}
6492
6493//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08006494INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08006495{
developer69b61b02023-03-07 17:17:44 +08006496 if (NULL == output_int)
developer72fb0bb2023-01-11 09:46:29 +08006497 return RETURN_ERR;
6498 *output_int = (radioIndex==0)? 1: 3;
6499
6500 return RETURN_OK;
6501}
6502
6503
6504//---------------------------------------------------------------------------------------------------
6505//
6506// Additional Wifi AP level APIs used for Access Point devices
6507//
6508//---------------------------------------------------------------------------------------------------
6509
6510// creates a new ap and pushes these parameters to the hardware
6511INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
6512{
6513 // Deprecated when use hal version 3, use wifi_createVap() instead.
6514 return RETURN_OK;
6515}
6516
6517// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
6518INT wifi_deleteAp(INT apIndex)
6519{
developer7e4a2a62023-04-06 19:56:03 +08006520 char interface_name[16] = {0};
6521 char buf[MAX_BUF_SIZE];
6522 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08006523
developer7e4a2a62023-04-06 19:56:03 +08006524 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6525 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08006526
developer7e4a2a62023-04-06 19:56:03 +08006527 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
6528 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006529
developer7e4a2a62023-04-06 19:56:03 +08006530 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006531
developer7e4a2a62023-04-06 19:56:03 +08006532 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006533}
6534
6535// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
6536INT wifi_getApName(INT apIndex, CHAR *output_string)
6537{
developer7e4a2a62023-04-06 19:56:03 +08006538 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08006539 int radio_idx = 0;
6540 int bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08006541
developer7e4a2a62023-04-06 19:56:03 +08006542 if(!output_string)
6543 return RETURN_ERR;
6544
6545 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
6546 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
6547
6548 snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model.
6549 } else
6550 snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
6551
6552 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006553}
6554
6555// Outputs the index number in that corresponds to the SSID string
6556INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
6557{
developer7e4a2a62023-04-06 19:56:03 +08006558 char cmd [128] = {0};
6559 char buf[32] = {0};
6560 char ap_idx = 0;
6561 char *apIndex_str = NULL;
6562 char radio_idx = 0;
6563 char bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08006564
developer7e4a2a62023-04-06 19:56:03 +08006565 snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
6566 inputSsidString);
6567 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006568
developer7e4a2a62023-04-06 19:56:03 +08006569 if (strlen(buf)) {
6570 apIndex_str = strtok(buf, "\n");
6571 *output_int = strtoul(apIndex_str, NULL, 10);
6572 return RETURN_OK;
6573 }
developer72fb0bb2023-01-11 09:46:29 +08006574
developer7e4a2a62023-04-06 19:56:03 +08006575 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
6576 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
6577 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
6578 radio_idx = 2;
6579 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
6580 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
6581 radio_idx = 1;
6582 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
6583 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
6584 radio_idx = 0;
6585 } else {
6586 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
6587 __func__, inputSsidString, ap_idx);
6588 *output_int = -1;
6589 return RETURN_ERR;
6590 }
6591
6592 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
6593
6594 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
6595 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
6596 __func__, inputSsidString, ap_idx);
6597 *output_int = ap_idx;
6598 return RETURN_OK;
6599 }
6600
6601 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006602}
6603
6604INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
6605{
6606 return wifi_getIndexFromName(inputSsidString, output_int);
6607}
6608
6609// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
6610INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
6611{
6612 char buf[MAX_BUF_SIZE] = {0};
6613 char cmd[MAX_CMD_SIZE] = {0};
6614 char config_file[MAX_BUF_SIZE] = {0};
6615
6616 if(NULL == output_string)
6617 return RETURN_ERR;
6618
6619 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6620 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
6621 if((strcmp(buf,"3")==0))
6622 snprintf(output_string, 32, "WPAand11i");
6623 else if((strcmp(buf,"2")==0))
6624 snprintf(output_string, 32, "11i");
6625 else if((strcmp(buf,"1")==0))
6626 snprintf(output_string, 32, "WPA");
6627 else
6628 snprintf(output_string, 32, "None");
6629
6630 return RETURN_OK;
6631}
6632
6633// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
6634INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
6635{
6636 char config_file[MAX_BUF_SIZE] = {0};
6637 struct params list;
6638
6639 if (NULL == beaconTypeString)
6640 return RETURN_ERR;
6641 list.name = "wpa";
6642 list.value = "0";
6643
6644 if((strcmp(beaconTypeString,"WPAand11i")==0))
6645 list.value="3";
6646 else if((strcmp(beaconTypeString,"11i")==0))
6647 list.value="2";
6648 else if((strcmp(beaconTypeString,"WPA")==0))
6649 list.value="1";
6650
6651 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6652 wifi_hostapdWrite(config_file, &list, 1);
6653 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6654 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
6655 return RETURN_OK;
6656}
6657
6658// sets the beacon interval on the hardware for this AP
6659INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
6660{
6661 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6662 struct params params={'\0'};
6663 char buf[MAX_BUF_SIZE] = {'\0'};
6664 char config_file[MAX_BUF_SIZE] = {'\0'};
6665
6666 params.name = "beacon_int";
6667 snprintf(buf, sizeof(buf), "%u", beaconInterval);
6668 params.value = buf;
6669
6670 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6671 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08006672
developer72fb0bb2023-01-11 09:46:29 +08006673 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6675 return RETURN_OK;
6676}
6677
6678INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
6679{
6680 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
6681 return RETURN_ERR;
6682 return RETURN_OK;
6683}
6684
6685// Get the packet size threshold supported.
6686INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
6687{
6688 //save config and apply instantly
6689 if (NULL == output_bool)
6690 return RETURN_ERR;
6691 *output_bool = TRUE;
6692 return RETURN_OK;
6693}
6694
6695// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
6696INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
6697{
developer72fb0bb2023-01-11 09:46:29 +08006698 char buf[16] = {0};
6699 char config_file[128] = {0};
6700 struct params param = {0};
6701
6702 if (threshold > 65535) {
6703 fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold);
6704 return RETURN_ERR;
6705 }
6706
developer23e71282023-01-18 10:25:19 +08006707 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006708 snprintf(buf, sizeof(buf), "%u", threshold);
6709 param.name = "rts_threshold";
6710 param.value = buf;
6711 wifi_hostapdWrite(config_file, &param, 1);
6712 wifi_hostapdProcessUpdate(apIndex, &param, 1);
6713 wifi_reloadAp(apIndex);
6714
6715 return RETURN_OK;
6716}
6717
6718// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
6719INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
6720{
6721 if (NULL == output_string)
6722 return RETURN_ERR;
6723 snprintf(output_string, 32, "TKIPandAESEncryption");
6724 return RETURN_OK;
6725
6726}
6727
6728// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
6729INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
6730{
6731 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6732 char *param_name = NULL;
6733 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
6734
6735 if(NULL == output_string)
6736 return RETURN_ERR;
6737
6738 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6739 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
6740
6741 if(strcmp(buf,"0")==0)
6742 {
6743 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
6744 snprintf(output_string, 32, "None");
6745 return RETURN_OK;
6746 }
6747 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
6748 param_name = "rsn_pairwise";
6749 else if((strcmp(buf,"1")==0))
6750 param_name = "wpa_pairwise";
6751 else
6752 return RETURN_ERR;
6753 memset(output_string,'\0',32);
6754 wifi_hostapdRead(config_file,param_name,output_string,32);
6755 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
6756 param_name = "wpa_pairwise";
6757 memset(output_string, '\0', 32);
6758 wifi_hostapdRead(config_file, param_name, output_string, 32);
6759 }
6760 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
6761
developere5750452023-05-15 16:46:42 +08006762 if(strcmp(output_string,"TKIP CCMP") == 0)
6763 strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption"));
6764 else if(strcmp(output_string,"TKIP") == 0)
developer72fb0bb2023-01-11 09:46:29 +08006765 strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption"));
6766 else if(strcmp(output_string,"CCMP") == 0)
6767 strncpy(output_string,"AESEncryption", strlen("AESEncryption"));
developer72fb0bb2023-01-11 09:46:29 +08006768
6769 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6770 return RETURN_OK;
6771}
6772
6773// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
6774INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
6775{
6776 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6777 struct params params={'\0'};
6778 char output_string[32];
6779 char config_file[MAX_BUF_SIZE] = {0};
6780
6781 memset(output_string,'\0',32);
developere5750452023-05-15 16:46:42 +08006782 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08006783
6784 if(strcmp(encMode, "TKIPEncryption") == 0)
6785 params.value = "TKIP";
6786 else if(strcmp(encMode,"AESEncryption") == 0)
6787 params.value = "CCMP";
6788 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
6789 params.value = "TKIP CCMP";
6790
6791 if((strcmp(output_string,"WPAand11i")==0))
6792 {
6793 params.name = "wpa_pairwise";
6794 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6795 wifi_hostapdWrite(config_file, &params, 1);
6796 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6797
6798 params.name = "rsn_pairwise";
6799 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6800 wifi_hostapdWrite(config_file, &params, 1);
6801 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6802
6803 return RETURN_OK;
6804 }
6805 else if((strcmp(output_string,"11i")==0))
6806 {
6807 params.name = "rsn_pairwise";
6808 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6809 wifi_hostapdWrite(config_file, &params, 1);
6810 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6811 return RETURN_OK;
6812 }
6813 else if((strcmp(output_string,"WPA")==0))
6814 {
6815 params.name = "wpa_pairwise";
6816 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6817 wifi_hostapdWrite(config_file, &params, 1);
6818 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6819 return RETURN_OK;
6820 }
6821
6822 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6823 return RETURN_OK;
6824}
6825
6826// deletes internal security varable settings for this ap
6827INT wifi_removeApSecVaribles(INT apIndex)
6828{
6829 //TODO: remove the entry in hostapd config file
6830 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name);
6831 //_syscmd(cmd, buf, sizeof(buf));
6832
6833 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name);
6834 //_syscmd(cmd, buf, sizeof(buf));
6835 return RETURN_ERR;
6836}
6837
6838// changes the hardware settings to disable encryption on this ap
6839INT wifi_disableApEncryption(INT apIndex)
6840{
6841 //Apply instantly
6842 return RETURN_ERR;
6843}
6844
6845// set the authorization mode on this ap
6846// mode mapping as: 1: open, 2: shared, 4:auto
6847INT wifi_setApAuthMode(INT apIndex, INT mode)
6848{
6849 struct params params={0};
6850 char config_file[64] = {0};
6851 int ret;
6852
6853 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6854
6855 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
6856 params.name = "auth_algs";
6857
developere5750452023-05-15 16:46:42 +08006858 if ((mode & 1 && mode & 2) || mode & 4)
developer72fb0bb2023-01-11 09:46:29 +08006859 params.value = "3";
6860 else if (mode & 2)
6861 params.value = "2";
6862 else if (mode & 1)
6863 params.value = "1";
6864 else
6865 params.value = "0";
6866
6867 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6868 wifi_hostapdWrite(config_file, &params, 1);
6869 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08006870 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006871 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6872
6873 return RETURN_OK;
6874}
6875
6876// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
6877INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
6878{
6879 //save to wifi config, and wait for wifi restart to apply
6880 struct params params={'\0'};
6881 char config_file[MAX_BUF_SIZE] = {0};
6882 int ret;
6883
6884 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6885 if(authMode == NULL)
6886 return RETURN_ERR;
6887
6888 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
6889 params.name = "wpa_key_mgmt";
6890
6891 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
6892 params.value = "WPA-PSK";
6893 else if(strcmp(authMode,"EAPAuthentication") == 0)
6894 params.value = "WPA-EAP";
6895 else if (strcmp(authMode, "SAEAuthentication") == 0)
6896 params.value = "SAE";
6897 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
6898 params.value = "WPA-EAP-SUITE-B-192";
6899 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
6900 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
developer3086e2f2023-01-17 09:40:01 +08006901 else if (strcmp(authMode, "Enhanced_Open") == 0)
6902 params.value = "OWE";
developer72fb0bb2023-01-11 09:46:29 +08006903 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
6904 return RETURN_OK; //This is taken careof in beaconType
6905
6906 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6907 ret=wifi_hostapdWrite(config_file,&params,1);
6908 if(!ret)
6909 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
6910 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6911
6912 return ret;
6913}
6914
6915// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
6916INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
6917{
6918 //save to wifi config, and wait for wifi restart to apply
6919 char BeaconType[50] = {0};
6920 char config_file[MAX_BUF_SIZE] = {0};
6921
6922 *authMode = 0;
6923 wifi_getApBeaconType(apIndex,BeaconType);
6924 printf("%s____%s \n",__FUNCTION__,BeaconType);
6925
6926 if(strcmp(BeaconType,"None") == 0)
6927 strcpy(authMode,"None");
6928 else
6929 {
6930 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6931 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
6932 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
6933 if(strcmp(authMode,"WPA-PSK") == 0)
6934 strcpy(authMode,"SharedAuthentication");
6935 else if(strcmp(authMode,"WPA-EAP") == 0)
6936 strcpy(authMode,"EAPAuthentication");
6937 }
6938
6939 return RETURN_OK;
6940}
6941
6942// Outputs the number of stations associated per AP
6943INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
6944{
6945 char interface_name[16] = {0};
6946 char cmd[128]={0};
6947 char buf[128]={0};
6948 BOOL status = false;
6949
6950 if(apIndex > MAX_APS)
6951 return RETURN_ERR;
6952
6953 wifi_getApEnable(apIndex,&status);
6954 if (!status)
6955 return RETURN_OK;
6956
6957 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
6958 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6959 return RETURN_ERR;
6960 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name);
6961 _syscmd(cmd, buf, sizeof(buf));
6962 sscanf(buf,"%lu", output_ulong);
6963
6964 return RETURN_OK;
6965}
6966
6967// manually removes any active wi-fi association with the device specified on this ap
6968INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
6969{
developer7e4a2a62023-04-06 19:56:03 +08006970 char inf_name[16] = {0};
6971 char cmd[MAX_CMD_SIZE] = {0};
6972 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006973
developer7e4a2a62023-04-06 19:56:03 +08006974 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08006975 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08006976
6977 snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
6978 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006979
6980 return RETURN_OK;
6981}
6982
6983// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
6984INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
6985{
developer7e4a2a62023-04-06 19:56:03 +08006986 int max_radio_num = 0;
6987
6988 if(NULL == output_int)
6989 return RETURN_ERR;
6990
6991 wifi_getMaxRadioNumber(&max_radio_num);
6992 *output_int = apIndex % max_radio_num;
6993
6994 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006995}
6996
6997// sets the radio index for the specific ap
6998INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
6999{
7000 //set to config only and wait for wifi reset to apply settings
7001 return RETURN_ERR;
7002}
7003
developer121a8e72023-05-22 09:19:39 +08007004
7005#define MAX_ACL_DUMP_LEN 4096
7006int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
7007{
7008 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7009 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
7010 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7011 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08007012 int err = 0;
developer121a8e72023-05-22 09:19:39 +08007013 unsigned short acl_result_len = 0;
7014 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08007015 if (!msg || !cb_data) {
developer2edaf012023-05-24 14:24:53 +08007016 wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08007017 return NL_SKIP;
7018 }
developer121a8e72023-05-22 09:19:39 +08007019 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7020 genlmsg_attrlen(gnlh, 0), NULL);
7021 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08007022 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08007023 return NL_SKIP;
7024 }
developer121a8e72023-05-22 09:19:39 +08007025 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7026 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
7027 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7028 if (err < 0)
7029 return NL_SKIP;
7030 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
7031 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7032 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7033 if (acl_result_len > MAX_ACL_DUMP_LEN) {
7034 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
7035 return NL_SKIP;
7036 } else if (*(show_str + acl_result_len - 1) != '\0') {
7037 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
7038 *(show_str + acl_result_len - 1) = '\0';
7039 }
7040 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08007041
7042 if (cb_data->out_len >= acl_result_len) {
7043 memset(cb_data->out_buf, 0, cb_data->out_len);
7044 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
7045 memmove(cb_data->out_buf, show_str, acl_result_len);
7046 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
7047 } else {
7048 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08007049 }
developer121a8e72023-05-22 09:19:39 +08007050 } else
7051 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
7052 } else
7053 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
7054 return NL_OK;
7055}
developer72fb0bb2023-01-11 09:46:29 +08007056// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08007057INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08007058{
developer7e4a2a62023-04-06 19:56:03 +08007059 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08007060 struct mtk_nl80211_param params;
7061 unsigned int if_idx = 0;
7062 int ret = -1;
7063 struct unl unl_ins;
7064 struct nl_msg *msg = NULL;
7065 struct nlattr * msg_data = NULL;
7066 struct mtk_nl80211_param param;
7067 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08007068 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7069 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08007070 if_idx = if_nametoindex(inf_name);
7071 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08007072 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08007073 return RETURN_ERR;
7074 }
7075 /*init mtk nl80211 vendor cmd*/
7076 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7077 param.if_type = NL80211_ATTR_IFINDEX;
7078 param.if_idx = if_idx;
7079
7080 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7081 if (ret) {
7082 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7083 return RETURN_ERR;
7084 }
developer121a8e72023-05-22 09:19:39 +08007085 /*add mtk vendor cmd data*/
7086 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08007087 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08007088 nlmsg_free(msg);
7089 goto err;
7090 }
developer72fb0bb2023-01-11 09:46:29 +08007091
developer121a8e72023-05-22 09:19:39 +08007092 /*send mtk nl80211 vendor msg*/
7093 cb_data.out_buf = macArray;
7094 cb_data.out_len = buf_size;
7095
7096 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
7097 if (ret) {
7098 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7099 goto err;
7100 }
7101 /*deinit mtk nl80211 vendor msg*/
7102 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007103 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developer72fb0bb2023-01-11 09:46:29 +08007104 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08007105err:
7106 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007107 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08007108 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007109}
7110
developer2edaf012023-05-24 14:24:53 +08007111INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7112{
7113 char *mac_arry_buf = NULL;
7114
7115 mac_arry_buf = malloc(buf_size);
7116 if (!mac_arry_buf) {
7117 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
7118 return RETURN_ERR;
7119 }
7120 memset(mac_arry_buf, 0, buf_size);
7121 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
7122 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
7123 free(mac_arry_buf);
7124 mac_arry_buf = NULL;
7125 return RETURN_ERR;
7126 }
7127 /*
7128 mtk format to wifi hal format:
7129 "policy=1
7130 00:11:22:33:44:55
7131 00:11:22:33:44:66
7132 "
7133 -->
7134 "00:11:22:33:44:55
7135 00:11:22:33:44:66
7136 "
7137 */
7138 memset(macArray, 0, buf_size);
7139 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
7140 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
7141 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
7142 }
7143 free(mac_arry_buf);
7144 mac_arry_buf = NULL;
7145 return RETURN_OK;
7146}
7147
developer72fb0bb2023-01-11 09:46:29 +08007148INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7149{
developer72fb0bb2023-01-11 09:46:29 +08007150
developer7e4a2a62023-04-06 19:56:03 +08007151 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08007152
7153 return RETURN_OK;
7154}
7155
7156
7157// Get the list of stations associated per AP
7158INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
7159{
developer7e4a2a62023-04-06 19:56:03 +08007160 char interface_name[IF_NAME_SIZE] = {0};
7161 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08007162
developer7e4a2a62023-04-06 19:56:03 +08007163 if(apIndex > 3) //Currently supporting apIndex upto 3
7164 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007165
developer7e4a2a62023-04-06 19:56:03 +08007166 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7167 return RETURN_ERR;
7168
7169 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
7170 _syscmd(cmd, macArray, buf_size);
7171 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007172}
7173
developer8dd72532023-05-17 19:58:35 +08007174int hex2num(char c)
7175{
7176 if (c >= '0' && c <= '9')
7177 return c - '0';
7178 if (c >= 'a' && c <= 'f')
7179 return c - 'a' + 10;
7180 if (c >= 'A' && c <= 'F')
7181 return c - 'A' + 10;
7182 return -1;
7183}
7184
7185/**
7186 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
7187 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
7188 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
7189 * Returns: Characters used (> 0) on success, -1 on failure
7190 */
7191int hwaddr_aton2(const char *txt, unsigned char *addr)
7192{
7193 int i;
7194 const char *pos = txt;
7195
7196 for (i = 0; i < 6; i++) {
7197 int a, b;
7198
7199 while (*pos == ':' || *pos == '.' || *pos == '-')
7200 pos++;
7201
7202 a = hex2num(*pos++);
7203 if (a < 0)
7204 return -1;
7205 b = hex2num(*pos++);
7206 if (b < 0)
7207 return -1;
7208 *addr++ = (a << 4) | b;
7209 }
7210
7211 return pos - txt;
7212}
7213
developer72fb0bb2023-01-11 09:46:29 +08007214// adds the mac address to the filter list
7215//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7216INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7217{
developer7e4a2a62023-04-06 19:56:03 +08007218 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08007219 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08007220 struct nl_msg *msg = NULL;
7221 struct nlattr * msg_data = NULL;
7222 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08007223 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
7224 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08007225 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7226 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007227 if (!DeviceMacAddress)
7228 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08007229 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08007230 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08007231 return RETURN_ERR;
7232 }
developer8dd72532023-05-17 19:58:35 +08007233 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08007234 if (!if_idx) {
7235 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7236 return RETURN_ERR;
7237 }
developer49b17232023-05-19 16:35:19 +08007238 /*init mtk nl80211 vendor cmd*/
7239 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7240 param.if_type = NL80211_ATTR_IFINDEX;
7241 param.if_idx = if_idx;
7242 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7243 if (ret) {
7244 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007245 return RETURN_ERR;
7246 }
developer49b17232023-05-19 16:35:19 +08007247 /*add mtk vendor cmd data*/
7248 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08007249 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08007250 nlmsg_free(msg);
7251 goto err;
7252 }
developer49b17232023-05-19 16:35:19 +08007253 /*send mtk nl80211 vendor msg*/
7254 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7255 if (ret) {
7256 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007257 goto err;
7258 }
developer49b17232023-05-19 16:35:19 +08007259 /*deinit mtk nl80211 vendor msg*/
7260 mtk_nl80211_deint(&unl_ins);
7261 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08007262 return RETURN_OK;
7263err:
developer49b17232023-05-19 16:35:19 +08007264 mtk_nl80211_deint(&unl_ins);
7265 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08007266 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007267}
7268
7269// deletes the mac address from the filter list
7270//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7271INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7272{
developer2edaf012023-05-24 14:24:53 +08007273 struct unl unl_ins;
7274 int if_idx = 0, ret = 0;
7275 struct nl_msg *msg = NULL;
7276 struct nlattr * msg_data = NULL;
7277 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08007278 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007279 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007280
developer7e4a2a62023-04-06 19:56:03 +08007281 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7282 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007283
developer7e4a2a62023-04-06 19:56:03 +08007284 if (!DeviceMacAddress)
7285 return RETURN_ERR;
7286
developer2edaf012023-05-24 14:24:53 +08007287 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
7288 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
7289 return RETURN_ERR;
7290 }
developer72fb0bb2023-01-11 09:46:29 +08007291
developer2edaf012023-05-24 14:24:53 +08007292 if_idx = if_nametoindex(inf_name);
7293 if (!if_idx) {
7294 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7295 return RETURN_ERR;
7296 }
7297 /*init mtk nl80211 vendor cmd*/
7298 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7299 param.if_type = NL80211_ATTR_IFINDEX;
7300 param.if_idx = if_idx;
7301 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7302 if (ret) {
7303 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7304 return RETURN_ERR;
7305 }
7306 /*add mtk vendor cmd data*/
7307 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
7308 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7309 nlmsg_free(msg);
7310 goto err;
7311 }
7312 /*send mtk nl80211 vendor msg*/
7313 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7314 if (ret) {
7315 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7316 goto err;
7317 }
7318 /*deinit mtk nl80211 vendor msg*/
7319 mtk_nl80211_deint(&unl_ins);
7320 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
7321 return RETURN_OK;
7322err:
7323 mtk_nl80211_deint(&unl_ins);
7324 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7325 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007326}
7327
7328// outputs the number of devices in the filter list
7329INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
7330{
developer7e4a2a62023-04-06 19:56:03 +08007331 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007332 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
7333 UINT buf_size = 1024;
7334 UINT sta_num = 0;
7335 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007336 if(output_uint == NULL)
7337 return RETURN_ERR;
7338
developer2edaf012023-05-24 14:24:53 +08007339 mac_arry = (char *)malloc(buf_size);
7340 if (mac_arry == NULL) {
7341 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08007342 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007343 }
7344 memset(mac_arry, buf_size, 0);
7345 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
7346 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
7347 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
7348 return RETURN_ERR;
7349 }
7350 /*count the acl str nums:*/
7351 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08007352
developer2edaf012023-05-24 14:24:53 +08007353 /*mac addr string format:
7354 exp1: 00:11:22:33:44:55\0
7355 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
7356 */
7357 ptr = mac_arry;
7358 while (sscanf(ptr, "%17s", mac_str) == 1) {
7359 if (hwaddr_aton2(mac_str, mac) >= 0)
7360 sta_num++;
7361 ptr = strstr(ptr, mac_str) + strlen(mac_str);
7362 }
7363 *output_uint = sta_num;
7364 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
7365 free(mac_arry);
7366 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08007367 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007368err:
7369 free(mac_arry);
7370 mac_arry = NULL;
7371 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007372}
7373
7374INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
7375{
7376 char cmd[128]={'\0'};
7377 char buf[128]={'\0'};
7378
7379 if(strcmp(action,"DENY")==0)
7380 {
7381 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
7382 system(buf);
7383 return RETURN_OK;
7384 }
7385
7386 if(strcmp(action,"ALLOW")==0)
7387 {
7388 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
7389 system(buf);
7390 return RETURN_OK;
7391 }
7392
7393 return RETURN_ERR;
7394
7395}
7396
7397// enable kick for devices on acl black list
7398INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
7399{
developer47cc27a2023-05-17 23:09:58 +08007400 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
7401 char assocArray[MAX_BUF_SIZE] = {0}, *asso = NULL;
developer72fb0bb2023-01-11 09:46:29 +08007402
7403 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
7404 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
7405
developer7e4a2a62023-04-06 19:56:03 +08007406 /* if there are no devices connected there is nothing to do */
developer72fb0bb2023-01-11 09:46:29 +08007407 if (strlen(assocArray) < 17)
7408 return RETURN_OK;
7409
developer7e4a2a62023-04-06 19:56:03 +08007410 if (enable == TRUE) {
7411 /* kick off the MAC which is in ACL array (deny list) */
7412 acl = strtok(aclArray, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007413 while (acl != NULL) {
7414 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
7415 wifi_kickApAssociatedDevice(apIndex, acl);
7416
developer7e4a2a62023-04-06 19:56:03 +08007417 acl = strtok(NULL, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007418 }
7419 wifi_setApMacAddressControlMode(apIndex, 2);
developer7e4a2a62023-04-06 19:56:03 +08007420 } else
developer72fb0bb2023-01-11 09:46:29 +08007421 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08007422
developer72fb0bb2023-01-11 09:46:29 +08007423 return RETURN_OK;
7424}
7425
7426INT wifi_setPreferPrivateConnection(BOOL enable)
7427{
7428 return RETURN_OK;
7429}
7430
7431// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
7432INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
7433{
developer2edaf012023-05-24 14:24:53 +08007434 int if_idx = 0, ret = 0;
7435 struct unl unl_ins;
7436 struct nl_msg *msg = NULL;
7437 struct nlattr * msg_data = NULL;
7438 struct mtk_nl80211_param param;
7439 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08007440 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007441
developer7e4a2a62023-04-06 19:56:03 +08007442 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7443 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007444 if_idx = if_nametoindex(inf_name);
7445 if (!if_idx) {
7446 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7447 return RETURN_ERR;
7448 }
7449 /*init mtk nl80211 vendor cmd*/
7450 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7451 param.if_type = NL80211_ATTR_IFINDEX;
7452 param.if_idx = if_idx;
7453 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7454 if (ret) {
7455 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7456 return RETURN_ERR;
7457 }
7458 /*add mtk vendor cmd data*/
7459 if (filterMode == 0) {
7460 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
7461 } else if (filterMode == 1) {
7462 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
7463 } else if (filterMode == 2) {
7464 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
7465 } else {
7466 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
7467 nlmsg_free(msg);
7468 goto err;
7469 }
7470 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
7471 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7472 nlmsg_free(msg);
7473 goto err;
7474 }
7475 /*send mtk nl80211 vendor msg*/
7476 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7477 if (ret) {
7478 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7479 goto err;
7480 }
7481 /*deinit mtk nl80211 vendor msg*/
7482 mtk_nl80211_deint(&unl_ins);
7483 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08007484 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007485err:
7486 mtk_nl80211_deint(&unl_ins);
7487 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7488 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007489}
7490
7491// 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.
7492INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
7493{
7494 return RETURN_ERR;
7495}
7496
7497// gets the vlan ID for this ap from an internal enviornment variable
7498INT wifi_getApVlanID(INT apIndex, INT *output_int)
7499{
7500 if(apIndex==0)
7501 {
7502 *output_int=100;
7503 return RETURN_OK;
7504 }
7505
7506 return RETURN_ERR;
7507}
7508
7509// sets the vlan ID for this ap to an internal enviornment variable
7510INT wifi_setApVlanID(INT apIndex, INT vlanId)
7511{
7512 //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)
7513 return RETURN_ERR;
7514}
7515
7516// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
7517INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
7518{
7519 snprintf(bridgeName, 32, "brlan0");
7520 snprintf(IP, 32, "10.0.0.1");
7521 snprintf(subnet, 32, "255.255.255.0");
7522
7523 return RETURN_OK;
7524}
7525
7526//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
7527INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
7528{
7529 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
7530 return RETURN_ERR;
7531}
7532
7533// reset the vlan configuration for this ap
7534INT wifi_resetApVlanCfg(INT apIndex)
7535{
developera1255e42023-05-13 17:45:02 +08007536 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08007537 int if_idx, ret = 0;
7538 struct nl_msg *msg = NULL;
7539 struct nlattr * msg_data = NULL;
7540 struct mtk_nl80211_param param;
7541 struct unl unl_ins;
7542 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08007543
developer2202b332023-05-24 16:23:22 +08007544 if (apIndex > MAX_APS) {
7545 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
7546 return RETURN_ERR;
7547 }
developer72fb0bb2023-01-11 09:46:29 +08007548
developer2202b332023-05-24 16:23:22 +08007549 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7550 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7551 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007552
developer2202b332023-05-24 16:23:22 +08007553 /*step 1. mwctl dev %s set vlan_tag 0*/
7554 if_idx = if_nametoindex(interface_name);
7555 /*init mtk nl80211 vendor cmd*/
7556 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
7557 param.if_type = NL80211_ATTR_IFINDEX;
7558 param.if_idx = if_idx;
7559 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08007560
developer2202b332023-05-24 16:23:22 +08007561 if (ret) {
7562 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7563 return RETURN_ERR;
7564 }
developer72fb0bb2023-01-11 09:46:29 +08007565
developer2202b332023-05-24 16:23:22 +08007566 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
7567 printf("Nla put attribute error\n");
7568 nlmsg_free(msg);
7569 goto err;
7570 }
developer72fb0bb2023-01-11 09:46:29 +08007571
developer2202b332023-05-24 16:23:22 +08007572 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7573 if (ret) {
7574 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7575 goto err;
7576 }
7577 mtk_nl80211_deint(&unl_ins);
7578 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08007579
developer2202b332023-05-24 16:23:22 +08007580 /*step 2. mwctl dev %s set vlan_priority 0*/
7581 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7582 if (ret) {
7583 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7584 return RETURN_ERR;
7585 }
developer72fb0bb2023-01-11 09:46:29 +08007586
developer2202b332023-05-24 16:23:22 +08007587 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
7588 printf("Nla put attribute error\n");
7589 nlmsg_free(msg);
7590 goto err;
7591 }
developer72fb0bb2023-01-11 09:46:29 +08007592
developer2202b332023-05-24 16:23:22 +08007593 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7594 if (ret) {
7595 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7596 goto err;
7597 }
7598 mtk_nl80211_deint(&unl_ins);
7599 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
7600
7601 /*step 3. mwctl dev %s set vlan_id 0*/
7602 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7603 if (ret) {
7604 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08007605 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08007606 }
developer72fb0bb2023-01-11 09:46:29 +08007607
developer2202b332023-05-24 16:23:22 +08007608 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
7609 printf("Nla put attribute error\n");
7610 nlmsg_free(msg);
7611 goto err;
7612 }
7613
7614 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7615 if (ret) {
7616 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7617 goto err;
7618 }
7619 mtk_nl80211_deint(&unl_ins);
7620 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
7621
7622 /*step 4. mwctl dev %s set vlan_en 0*/
7623 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7624 if (ret) {
7625 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7626 return RETURN_ERR;
7627 }
7628
7629 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
7630 printf("Nla put attribute error\n");
7631 nlmsg_free(msg);
7632 goto err;
7633 }
7634
7635 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7636 if (ret) {
7637 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7638 goto err;
7639 }
7640 mtk_nl80211_deint(&unl_ins);
7641 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
7642
7643 /*step 5. mwctl dev %s set vlan_policy 0:4*/
7644 vlan_param.direction = 0;
7645 vlan_param.policy = 4;
7646 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7647 if (ret) {
7648 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7649 return RETURN_ERR;
7650 }
7651 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
7652 printf("Nla put attribute error\n");
7653 nlmsg_free(msg);
7654 goto err;
7655 }
7656
7657 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7658 if (ret) {
7659 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7660 goto err;
7661 }
7662 mtk_nl80211_deint(&unl_ins);
7663 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
7664
7665 /*step 6. mwctl dev %s set vlan_policy 1:0*/
7666 vlan_param.direction = 1;
7667 vlan_param.policy = 0;
7668 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7669 if (ret) {
7670 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7671 return RETURN_ERR;
7672 }
7673
7674 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
7675 printf("Nla put attribute error\n");
7676 nlmsg_free(msg);
7677 goto err;
7678 }
7679
7680 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7681 if (ret) {
7682 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7683 goto err;
7684 }
7685 /*deinit mtk nl80211 vendor msg*/
7686 mtk_nl80211_deint(&unl_ins);
7687 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
7688
7689 /*TODO need to modify VLAN config in dat file*/
7690 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7691
7692 return RETURN_OK;
7693err:
7694 mtk_nl80211_deint(&unl_ins);
7695 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7696 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007697}
7698
7699// 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.
7700INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
7701{
7702 return RETURN_ERR;
7703}
7704
7705// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
7706INT wifi_startHostApd()
7707{
7708 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7709 system("systemctl start hostapd.service");
7710 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7711 return RETURN_OK;
7712 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
7713}
7714
7715// stops hostapd
developer69b61b02023-03-07 17:17:44 +08007716INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08007717{
7718 char cmd[128] = {0};
7719 char buf[128] = {0};
7720
7721 sprintf(cmd,"systemctl stop hostapd");
7722 _syscmd(cmd, buf, sizeof(buf));
7723
7724 return RETURN_OK;
7725}
7726
7727// restart hostapd dummy function
7728INT wifi_restartHostApd()
7729{
7730 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7731 system("systemctl restart hostapd-global");
7732 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7733
7734 return RETURN_OK;
7735}
7736
7737static int align_hostapd_config(int index)
7738{
7739 ULONG lval;
7740 wifi_getRadioChannel(index%2, &lval);
7741 wifi_setRadioChannel(index%2, lval);
7742 return RETURN_OK;
7743}
7744
7745// sets the AP enable status variable for the specified ap.
7746INT wifi_setApEnable(INT apIndex, BOOL enable)
7747{
developer7e4a2a62023-04-06 19:56:03 +08007748 char interface_name[16] = {0};
7749 char config_file[MAX_BUF_SIZE] = {0};
7750 char cmd[MAX_CMD_SIZE] = {0};
7751 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08007752 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08007753 int max_radio_num = 0;
7754 int phyId = 0;
developer72fb0bb2023-01-11 09:46:29 +08007755
developer7e4a2a62023-04-06 19:56:03 +08007756 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08007757
developer7e4a2a62023-04-06 19:56:03 +08007758 wifi_getMaxRadioNumber(&max_radio_num);
7759 if (enable == status)
7760 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007761
developer7e4a2a62023-04-06 19:56:03 +08007762 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7763 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007764
developer7e4a2a62023-04-06 19:56:03 +08007765 if (enable == TRUE) {
7766 int radioIndex = apIndex % max_radio_num;
7767 phyId = radio_index_to_phy(radioIndex);
developer8a3bbbf2023-03-15 17:47:23 +08007768
developer7e4a2a62023-04-06 19:56:03 +08007769 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
7770 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
7771 _syscmd(cmd, buf, sizeof(buf));
7772 } else {
7773 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
7774 _syscmd(cmd, buf, sizeof(buf));
7775 }
7776 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
7777 interface_name, interface_name, enable, VAP_STATUS_FILE);
7778 _syscmd(cmd, buf, sizeof(buf));
7779 //Wait for wifi up/down to apply
7780 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007781}
7782
7783// Outputs the setting of the internal variable that is set by wifi_setApEnable().
7784INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
7785{
developer7e4a2a62023-04-06 19:56:03 +08007786 char interface_name[IF_NAME_SIZE] = {0};
7787 char cmd[MAX_CMD_SIZE] = {0};
7788 char buf[MAX_BUF_SIZE] = {0};
developere740c2a2023-05-23 18:34:32 +08007789 int ret;
developer72fb0bb2023-01-11 09:46:29 +08007790
developer7e4a2a62023-04-06 19:56:03 +08007791 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
7792 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007793
developer7e4a2a62023-04-06 19:56:03 +08007794 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08007795
developer7e4a2a62023-04-06 19:56:03 +08007796 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
7797 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
7798 *output_bool = FALSE;
7799 return RETURN_OK;
7800 }
developere740c2a2023-05-23 18:34:32 +08007801 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status", interface_name);
7802 ret = system(cmd);
7803 if (ret == 0)
7804 *output_bool = 1;
developer7e4a2a62023-04-06 19:56:03 +08007805 }
developer72fb0bb2023-01-11 09:46:29 +08007806
developer7e4a2a62023-04-06 19:56:03 +08007807 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007808}
7809
developer69b61b02023-03-07 17:17:44 +08007810// Outputs the AP "Enabled" "Disabled" status from driver
7811INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08007812{
developer7e4a2a62023-04-06 19:56:03 +08007813 char cmd[128] = {0};
7814 char buf[128] = {0};
7815 BOOL output_bool;
developer72fb0bb2023-01-11 09:46:29 +08007816
developer7e4a2a62023-04-06 19:56:03 +08007817 if (!output_string) {
7818 printf("%s: null pointer!", __func__);
7819 return RETURN_ERR;
7820 }
developer72fb0bb2023-01-11 09:46:29 +08007821
developer7e4a2a62023-04-06 19:56:03 +08007822 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08007823
developer7e4a2a62023-04-06 19:56:03 +08007824 if(output_bool == 1)
7825 snprintf(output_string, 32, "Up");
7826 else
7827 snprintf(output_string, 32, "Disable");
7828
7829 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007830}
7831
7832//Indicates whether or not beacons include the SSID name.
7833// outputs a 1 if SSID on the AP is enabled, else outputs 0
7834INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
7835{
7836 //get the running status
7837 char config_file[MAX_BUF_SIZE] = {0};
7838 char buf[16] = {0};
7839
7840 if (!output)
7841 return RETURN_ERR;
7842
7843 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7844 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
7845 // default is enable
7846 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
7847 *output = TRUE;
7848
7849 return RETURN_OK;
7850}
7851
7852// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
7853INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
7854{
7855 //store the config, apply instantly
7856 char config_file[MAX_BUF_SIZE] = {0};
7857 struct params list;
7858
7859 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7860 list.name = "ignore_broadcast_ssid";
7861 list.value = enable?"0":"1";
7862
7863 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7864 wifi_hostapdWrite(config_file, &list, 1);
7865 wifi_hostapdProcessUpdate(apIndex, &list, 1);
7866 //TODO: call hostapd_cli for dynamic_config_control
7867 wifi_reloadAp(apIndex);
7868 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7869
7870 return RETURN_OK;
7871}
7872
7873//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
7874INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
7875{
developer47cc27a2023-05-17 23:09:58 +08007876 /* get the running status */
7877 if(!output_uint)
7878 return RETURN_ERR;
7879
7880 *output_uint = 15;
7881 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007882}
7883
developer47cc27a2023-05-17 23:09:58 +08007884/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +08007885INT wifi_setApRetryLimit(INT apIndex, UINT number)
7886{
developer47cc27a2023-05-17 23:09:58 +08007887 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007888}
7889
developer95c045d2023-05-24 19:26:28 +08007890int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
7891{
7892 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7893 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
7894 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7895 unsigned char *status = (unsigned char * *)data;
7896 int err = 0;
7897 //u16 acl_result_len = 0;
7898
7899 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7900 genlmsg_attrlen(gnlh, 0), NULL);
7901 if (err < 0)
7902 return err;
7903
7904 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7905 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
7906 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7907 if (err < 0)
7908 return err;
7909
7910 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
7911 //acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
7912 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
7913 }
7914 }
7915
7916 return 0;
7917}
7918
developer72fb0bb2023-01-11 09:46:29 +08007919//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
7920INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
7921{
developer95c045d2023-05-24 19:26:28 +08007922 int if_idx, ret = 0;
developer8e6583c2023-05-23 13:36:06 +08007923 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08007924 unsigned char status = 0;
7925 struct nl_msg *msg = NULL;
7926 struct nlattr * msg_data = NULL;
7927 struct mtk_nl80211_param param;
7928 struct unl unl_ins;
7929 struct vlan_policy_param vlan_param;
developer8e6583c2023-05-23 13:36:06 +08007930
7931 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007932 if(!output)
7933 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08007934
developer95c045d2023-05-24 19:26:28 +08007935 if (apIndex > MAX_APS) {
7936 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
7937 return RETURN_ERR;
7938 }
7939
developer8e6583c2023-05-23 13:36:06 +08007940 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7941 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +08007942
7943 if_idx = if_nametoindex(interface_name);
7944 /*init mtk nl80211 vendor cmd*/
7945 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
7946 param.if_type = NL80211_ATTR_IFINDEX;
7947 param.if_idx = if_idx;
7948 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7949
7950 if (ret) {
7951 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7952 return RETURN_ERR;
7953 }
7954
7955 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
7956 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7957 nlmsg_free(msg);
7958 goto err;
7959 }
7960
7961 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
7962 (void *)&status);
7963 if (ret) {
7964 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7965 goto err;
7966 }
7967 mtk_nl80211_deint(&unl_ins);
7968
7969 *output = status == 0 ? FALSE : TRUE;
7970 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +08007971
7972 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007973 return RETURN_OK;
developer95c045d2023-05-24 19:26:28 +08007974err:
7975 mtk_nl80211_deint(&unl_ins);
7976 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7977 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007978}
7979
7980//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
7981INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
7982{
7983 //get the running status from driver
7984 char cmd[128] = {0};
7985 char buf[128] = {0};
7986 int max_radio_num = 0, radioIndex = 0;
7987 int phyId = 0;
7988
7989 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7990
7991 wifi_getMaxRadioNumber(&max_radio_num);
7992 radioIndex = apIndex % max_radio_num;
7993 phyId = radio_index_to_phy(radioIndex);
7994 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
7995 _syscmd(cmd,buf, sizeof(buf));
7996
7997 if (strlen(buf) > 0)
7998 *output = true;
7999
8000 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8001
8002 return RETURN_OK;
8003}
8004
8005//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
8006INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
8007{
developer95c045d2023-05-24 19:26:28 +08008008 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +08008009}
8010
8011// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
8012INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
8013{
developer95c045d2023-05-24 19:26:28 +08008014 int if_idx, ret = 0;
8015 char interface_name[16] = {0};
8016 unsigned char status = 0;
8017 struct nl_msg *msg = NULL;
8018 struct nlattr * msg_data = NULL;
8019 struct mtk_nl80211_param param;
8020 struct unl unl_ins;
8021 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08008022
developer95c045d2023-05-24 19:26:28 +08008023 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008024
developer95c045d2023-05-24 19:26:28 +08008025 if (apIndex > MAX_APS) {
8026 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8027 return RETURN_ERR;
8028 }
developer72fb0bb2023-01-11 09:46:29 +08008029
developer95c045d2023-05-24 19:26:28 +08008030 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8031 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008032
developer95c045d2023-05-24 19:26:28 +08008033 if_idx = if_nametoindex(interface_name);
8034 /*init mtk nl80211 vendor cmd*/
8035 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8036 param.if_type = NL80211_ATTR_IFINDEX;
8037 param.if_idx = if_idx;
8038 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8039
8040 if (ret) {
8041 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8042 return RETURN_ERR;
8043 }
8044
8045 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
8046 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8047 nlmsg_free(msg);
8048 goto err;
8049 }
8050
8051 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8052 if (ret) {
8053 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8054 goto err;
8055 }
8056 mtk_nl80211_deint(&unl_ins);
8057
8058 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8059 return RETURN_OK;
8060err:
8061 mtk_nl80211_deint(&unl_ins);
8062 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8063 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008064}
8065
developer95c045d2023-05-24 19:26:28 +08008066
developer72fb0bb2023-01-11 09:46:29 +08008067//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.
8068INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
8069{
8070 //get the running status from driver
8071 if(!output)
8072 return RETURN_ERR;
8073
8074 char config_file[128] = {0};
8075 char buf[16] = {0};
8076
8077 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8078 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
8079 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
8080 *output = TRUE;
8081 else
8082 *output = FALSE;
8083
8084 return RETURN_OK;
8085}
8086
8087// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
8088INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
8089{
8090 //save config and apply instantly.
8091 char config_file[MAX_BUF_SIZE] = {0};
8092 struct params list;
8093
8094 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8095 list.name = "uapsd_advertisement_enabled";
8096 list.value = enable?"1":"0";
8097
8098 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8099 wifi_hostapdWrite(config_file, &list, 1);
8100 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developere82c0ca2023-05-10 16:25:35 +08008101 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008102 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8103
8104 return RETURN_OK;
8105}
8106
8107// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
8108INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
8109{
8110 char interface_name[16] = {0};
8111 // assume class 0->BE, 1->BK, 2->VI, 3->VO
8112 char cmd[128] = {0};
8113 char buf[128] = {0};
8114 char ack_filepath[128] = {0};
8115 uint16_t bitmap = 0;
8116 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
8117 FILE *f = NULL;
8118
8119 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
8120
8121 // Get current setting
8122 snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
8123 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
8124 _syscmd(cmd, buf, sizeof(buf));
8125 if (strlen(buf) > 0)
8126 bitmap = strtoul(buf, NULL, 10);
8127
8128 bitmap = strtoul(buf, NULL, 10);
8129
8130 if (ackPolicy == TRUE) { // True, unset this class
8131 bitmap &= ~class_map[class];
8132 } else { // False, set this class
8133 bitmap |= class_map[class];
8134 }
8135
8136 f = fopen(ack_filepath, "w");
8137 if (f == NULL) {
8138 fprintf(stderr, "%s: fopen failed\n", __func__);
8139 return RETURN_ERR;
8140 }
8141 fprintf(f, "%hu", bitmap);
8142 fclose(f);
8143
8144 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8145 return RETURN_ERR;
8146 snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
8147 _syscmd(cmd, buf, sizeof(buf));
8148
8149 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
8150 return RETURN_OK;
8151}
8152
8153//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.
8154INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
8155{
8156 //get the running status from driver
8157 if(!output_uint)
8158 return RETURN_ERR;
8159
8160 char output[16]={'\0'};
8161 char config_file[MAX_BUF_SIZE] = {0};
8162
8163 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8164 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
8165 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
8166 else {
8167 int device_num = atoi(output);
8168 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
8169 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
8170 return RETURN_ERR;
8171 }
8172 else {
8173 *output_uint = device_num;
8174 }
8175 }
8176
8177 return RETURN_OK;
8178}
8179
8180INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
8181{
8182 //store to wifi config, apply instantly
8183 char str[MAX_BUF_SIZE]={'\0'};
8184 char cmd[MAX_CMD_SIZE]={'\0'};
8185 struct params params;
8186 char config_file[MAX_BUF_SIZE] = {0};
8187
8188 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8189 if (number > MAX_ASSOCIATED_STA_NUM) {
8190 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
8191 return RETURN_ERR;
8192 }
8193 sprintf(str, "%d", number);
8194 params.name = "max_num_sta";
8195 params.value = str;
8196
8197 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
8198 int ret = wifi_hostapdWrite(config_file, &params, 1);
8199 if (ret) {
8200 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
8201 ,__func__, ret);
8202 }
8203
8204 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
8205 if (ret) {
8206 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
8207 ,__func__, ret);
8208 }
8209 wifi_reloadAp(apIndex);
8210 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8211
8212 return RETURN_OK;
8213}
8214
8215//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.
8216INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
8217{
8218 //get the current threshold
8219 if(!output_uint)
8220 return RETURN_ERR;
8221 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
8222 if (*output_uint == 0)
8223 *output_uint = 50;
8224 return RETURN_OK;
8225}
8226
8227INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
8228{
8229 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
8230 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
8231 return RETURN_OK;
8232 return RETURN_ERR;
8233}
8234
8235//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.
8236INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
8237{
8238 if(!output_uint)
8239 return RETURN_ERR;
8240 *output_uint = 3;
8241 return RETURN_OK;
8242}
8243
8244//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
8245INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
8246{
8247 if(!output_uint)
8248 return RETURN_ERR;
8249 *output_uint = 3;
8250 return RETURN_OK;
8251}
8252
8253//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.
8254INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
8255{
8256 if(!output_in_seconds)
8257 return RETURN_ERR;
8258 *output_in_seconds = 0;
8259 return RETURN_OK;
8260}
8261
8262//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
8263INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
8264{
8265 if(!output || apIndex>=MAX_APS)
8266 return RETURN_ERR;
8267 //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
8268 snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
8269 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008270}
developer72fb0bb2023-01-11 09:46:29 +08008271
8272//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
8273INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
8274{
8275 char config_file[128] = {0};
8276 char wpa[16] = {0};
8277 char key_mgmt[64] = {0};
8278 char buf[16] = {0};
8279 if (!output)
8280 return RETURN_ERR;
8281
8282 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8283 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
8284
8285 strcpy(output, "None");//Copying "None" to output string for default case
8286 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
8287 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
8288 if (!strcmp(wpa, "1"))
8289 snprintf(output, 32, "WPA-Personal");
8290 else if (!strcmp(wpa, "2"))
8291 snprintf(output, 32, "WPA2-Personal");
8292 else if (!strcmp(wpa, "3"))
8293 snprintf(output, 32, "WPA-WPA2-Personal");
8294
developere5750452023-05-15 16:46:42 +08008295 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
8296 snprintf(output, 32, "WPA3-Enterprise");
developer72fb0bb2023-01-11 09:46:29 +08008297 } else if (strstr(key_mgmt, "WPA-EAP")) {
8298 if (!strcmp(wpa, "1"))
8299 snprintf(output, 32, "WPA-Enterprise");
8300 else if (!strcmp(wpa, "2"))
8301 snprintf(output, 32, "WPA2-Enterprise");
8302 else if (!strcmp(wpa, "3"))
8303 snprintf(output, 32, "WPA-WPA2-Enterprise");
8304 } else if (strstr(key_mgmt, "SAE")) {
8305 if (strstr(key_mgmt, "WPA-PSK") == NULL)
8306 snprintf(output, 32, "WPA3-Personal");
8307 else
8308 snprintf(output, 32, "WPA3-Personal-Transition");
developer72fb0bb2023-01-11 09:46:29 +08008309 }
8310
8311 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8312 return RETURN_OK;
8313#if 0
8314 //TODO: need to revisit below implementation
8315 char securityType[32], authMode[32];
8316 int enterpriseMode=0;
8317
8318 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8319 if(!output)
8320 return RETURN_ERR;
8321
8322 wifi_getApBeaconType(apIndex, securityType);
8323 strcpy(output,"None");//By default, copying "None" to output string
8324 if (strncmp(securityType,"None", strlen("None")) == 0)
8325 return RETURN_OK;
8326
8327 wifi_getApBasicAuthenticationMode(apIndex, authMode);
8328 enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0;
8329
8330 if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0)
8331 snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal");
8332 else if (strncmp(securityType, "WPA", strlen("WPA")) == 0)
8333 snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal");
8334 else if (strncmp(securityType, "11i", strlen("11i")) == 0)
8335 snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal");
8336 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8337
8338 return RETURN_OK;
8339#endif
8340}
developer69b61b02023-03-07 17:17:44 +08008341
developer72fb0bb2023-01-11 09:46:29 +08008342INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
8343{
8344 char securityType[32];
8345 char authMode[32];
8346
8347 //store settings and wait for wifi up to apply
8348 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8349 if(!encMode)
8350 return RETURN_ERR;
8351
8352 if (strcmp(encMode, "None")==0)
8353 {
8354 strcpy(securityType,"None");
8355 strcpy(authMode,"None");
8356 }
8357 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
8358 {
8359 strcpy(securityType,"WPAand11i");
8360 strcpy(authMode,"PSKAuthentication");
8361 }
8362 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
8363 {
8364 strcpy(securityType,"WPAand11i");
8365 strcpy(authMode,"EAPAuthentication");
8366 }
8367 else if (strcmp(encMode, "WPA-Personal")==0)
8368 {
8369 strcpy(securityType,"WPA");
8370 strcpy(authMode,"PSKAuthentication");
8371 }
8372 else if (strcmp(encMode, "WPA-Enterprise")==0)
8373 {
8374 strcpy(securityType,"WPA");
8375 strcpy(authMode,"EAPAuthentication");
8376 }
8377 else if (strcmp(encMode, "WPA2-Personal")==0)
8378 {
8379 strcpy(securityType,"11i");
8380 strcpy(authMode,"PSKAuthentication");
8381 }
8382 else if (strcmp(encMode, "WPA2-Enterprise")==0)
8383 {
8384 strcpy(securityType,"11i");
8385 strcpy(authMode,"EAPAuthentication");
8386 }
8387 else if (strcmp(encMode, "WPA3-Personal") == 0)
8388 {
8389 strcpy(securityType,"11i");
8390 strcpy(authMode,"SAEAuthentication");
8391 }
8392 else if (strcmp(encMode, "WPA3-Personal-Transition") == 0)
8393 {
8394 strcpy(securityType, "11i");
8395 strcpy(authMode, "PSK-SAEAuthentication");
8396 }
8397 else if (strcmp(encMode, "WPA3-Enterprise") == 0)
8398 {
8399 strcpy(securityType,"11i");
8400 strcpy(authMode,"EAP_192-bit_Authentication");
8401 }
developer3086e2f2023-01-17 09:40:01 +08008402 else if (strcmp(encMode, "OWE") == 0)
8403 {
8404 strcpy(securityType,"11i");
8405 strcpy(authMode,"Enhanced_Open");
8406 }
developer72fb0bb2023-01-11 09:46:29 +08008407 else
8408 {
8409 strcpy(securityType,"None");
8410 strcpy(authMode,"None");
8411 }
8412 wifi_setApBeaconType(apIndex, securityType);
8413 wifi_setApBasicAuthenticationMode(apIndex, authMode);
8414 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8415
8416 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008417}
developer72fb0bb2023-01-11 09:46:29 +08008418
8419
8420//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
8421// output_string must be pre-allocated as 64 character string by caller
8422// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8423INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
8424{
8425 char buf[16] = {0};
8426 char config_file[MAX_BUF_SIZE] = {0};
8427
8428 if(output_string==NULL)
8429 return RETURN_ERR;
8430
8431 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8432 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8433
8434 if(strcmp(buf,"0")==0)
8435 {
8436 printf("wpa_mode is %s ......... \n",buf);
8437 return RETURN_ERR;
8438 }
8439
8440 wifi_dbg_printf("\nFunc=%s\n",__func__);
8441 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
developere5750452023-05-15 16:46:42 +08008442 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developer72fb0bb2023-01-11 09:46:29 +08008443 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8444
8445 return RETURN_OK;
8446}
8447
8448// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
8449// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8450INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
8451{
8452 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8453 struct params params={'\0'};
8454 int ret;
8455 char config_file[MAX_BUF_SIZE] = {0};
8456
8457 if(NULL == preSharedKey)
8458 return RETURN_ERR;
8459
developere5750452023-05-15 16:46:42 +08008460 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +08008461
developere5750452023-05-15 16:46:42 +08008462 if(strlen(preSharedKey) != 64)
developer72fb0bb2023-01-11 09:46:29 +08008463 {
developere5750452023-05-15 16:46:42 +08008464 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
developer72fb0bb2023-01-11 09:46:29 +08008465 return RETURN_ERR;
8466 }
8467 params.value = preSharedKey;
8468 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8469 ret = wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +08008470 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08008471 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008472 wifi_reloadAp(apIndex);
8473 }
developer72fb0bb2023-01-11 09:46:29 +08008474 return ret;
8475 //TODO: call hostapd_cli for dynamic_config_control
8476}
8477
8478//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
8479// outputs the passphrase, maximum 63 characters
8480INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
8481{
8482 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
8483
8484 wifi_dbg_printf("\nFunc=%s\n",__func__);
8485 if (NULL == output_string)
8486 return RETURN_ERR;
8487
8488 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8489 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8490 if(strcmp(buf,"0")==0)
8491 {
8492 printf("wpa_mode is %s ......... \n",buf);
8493 return RETURN_ERR;
8494 }
8495
8496 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
8497 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8498
8499 return RETURN_OK;
8500}
8501
8502// sets the passphrase enviornment variable, max 63 characters
8503INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
8504{
8505 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8506 struct params params={'\0'};
8507 char config_file[MAX_BUF_SIZE] = {0};
8508 int ret;
8509
8510 if(NULL == passPhrase)
8511 return RETURN_ERR;
8512
8513 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
8514 {
8515 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
8516 return RETURN_ERR;
8517 }
8518 params.name = "wpa_passphrase";
8519 params.value = passPhrase;
8520 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8521 ret=wifi_hostapdWrite(config_file,&params,1);
developere5750452023-05-15 16:46:42 +08008522 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08008523 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008524 wifi_reloadAp(apIndex);
8525 }
developer72fb0bb2023-01-11 09:46:29 +08008526
8527 return ret;
8528}
8529
8530//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.
8531INT wifi_setApSecurityReset(INT apIndex)
8532{
8533 char original_config_file[64] = {0};
8534 char current_config_file[64] = {0};
8535 char buf[64] = {0};
8536 char cmd[64] = {0};
8537 char wpa[4] = {0};
8538 char wpa_psk[64] = {0};
8539 char wpa_passphrase[64] = {0};
8540 char wpa_psk_file[128] = {0};
8541 char wpa_key_mgmt[64] = {0};
8542 char wpa_pairwise[32] = {0};
8543 wifi_band band;
8544 struct params list[6];
8545
8546 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8547
8548 band = wifi_index_to_band(apIndex);
8549 if (band == band_2_4)
8550 sprintf(original_config_file, "/etc/hostapd-2G.conf");
8551 else if (band == band_5)
8552 sprintf(original_config_file, "/etc/hostapd-5G.conf");
8553 else if (band == band_6)
8554 sprintf(original_config_file, "/etc/hostapd-6G.conf");
8555 else
8556 return RETURN_ERR;
8557
8558 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
8559 list[0].name = "wpa";
8560 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +08008561
developer72fb0bb2023-01-11 09:46:29 +08008562 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
8563 list[1].name = "wpa_psk";
8564 list[1].value = wpa_psk;
8565
8566 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
8567 list[2].name = "wpa_passphrase";
8568 list[2].value = wpa_passphrase;
8569
8570 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
8571
8572 if (strlen(wpa_psk_file) == 0)
8573 strcpy(wpa_psk_file, PSK_FILE);
8574
8575 if (access(wpa_psk_file, F_OK) != 0) {
8576 sprintf(cmd, "touch %s", wpa_psk_file);
8577 _syscmd(cmd, buf, sizeof(buf));
8578 }
8579 list[3].name = "wpa_psk_file";
8580 list[3].value = wpa_psk_file;
8581
8582 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
8583 list[4].name = "wpa_key_mgmt";
8584 list[4].value = wpa_key_mgmt;
8585
8586 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
8587 list[5].name = "wpa_pairwise";
8588 list[5].value = wpa_pairwise;
8589
8590 sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8591 wifi_hostapdWrite(current_config_file, list, 6);
8592
8593 wifi_setApEnable(apIndex, FALSE);
8594 wifi_setApEnable(apIndex, TRUE);
8595
8596 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8597 return RETURN_OK;
8598}
8599
8600//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).
8601INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
8602{
8603 char config_file[64] = {0};
8604 char buf[64] = {0};
8605 char cmd[256] = {0};
8606
8607 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8608
8609 if(!IP_output || !Port_output || !RadiusSecret_output)
8610 return RETURN_ERR;
8611
8612 // Read the first matched config
8613 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8614 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
8615 _syscmd(cmd, buf, sizeof(buf));
8616 strncpy(IP_output, buf, 64);
8617
8618 memset(buf, 0, sizeof(buf));
8619 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
8620 _syscmd(cmd, buf, sizeof(buf));
8621 *Port_output = atoi(buf);
8622
8623 memset(buf, 0, sizeof(buf));
8624 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
8625 _syscmd(cmd, buf, sizeof(buf));
8626 strncpy(RadiusSecret_output, buf, 64);
8627
8628 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8629 return RETURN_OK;
8630}
8631
8632INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
8633{
8634 char config_file[64] = {0};
8635 char port_str[8] = {0};
8636 char cmd[256] = {0};
8637 char buf[128] = {0};
8638
8639 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8640
developere5750452023-05-15 16:46:42 +08008641 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
8642 return RETURN_ERR;
8643
8644 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
8645 return RETURN_ERR;
8646
developer72fb0bb2023-01-11 09:46:29 +08008647 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8648
8649 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
8650 _syscmd(cmd, buf, sizeof(buf));
8651 memset(cmd, 0, sizeof(cmd));
8652
8653 snprintf(port_str, sizeof(port_str), "%d", port);
8654 if (strlen(buf) == 0)
8655 // Append
8656 snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
8657 "auth_server_addr=%s\\n"
8658 "auth_server_port=%s\\n"
8659 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
8660 else {
8661 // Delete the three lines setting after the "# radius 1" comment
8662 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
8663 _syscmd(cmd, buf, sizeof(buf));
8664 memset(cmd, 0, sizeof(cmd));
8665 // Use "# radius 1" comment to find the location to insert the radius setting
8666 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
8667 "# radius 1\\n"
8668 "auth_server_addr=%s\\n"
8669 "auth_server_port=%s\\n"
8670 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
8671 }
8672 if(_syscmd(cmd, buf, sizeof(buf))) {
8673 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
8674 return RETURN_ERR;
8675 }
8676
8677 wifi_reloadAp(apIndex);
8678 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8679 return RETURN_OK;
8680}
8681
8682INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
8683{
8684 char config_file[64] = {0};
8685 char buf[64] = {0};
8686 char cmd[256] = {0};
8687
8688 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8689
8690 if(!IP_output || !Port_output || !RadiusSecret_output)
8691 return RETURN_ERR;
8692
8693 // Read the second matched config
8694 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8695 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
8696 _syscmd(cmd, buf, sizeof(buf));
8697 strncpy(IP_output, buf, 64);
8698
8699 memset(buf, 0, sizeof(buf));
8700 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
8701 _syscmd(cmd, buf, sizeof(buf));
8702 *Port_output = atoi(buf);
8703
8704 memset(buf, 0, sizeof(buf));
8705 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
8706 _syscmd(cmd, buf, sizeof(buf));
8707 strncpy(RadiusSecret_output, buf, 64);
8708
8709 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8710 return RETURN_OK;
8711}
8712
8713INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
8714{
8715 char config_file[64] = {0};
8716 char port_str[8] = {0};
8717 char cmd[256] = {0};
8718 char buf[128] = {0};
8719
8720 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8721
developere5750452023-05-15 16:46:42 +08008722 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
8723 return RETURN_ERR;
8724
8725 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
8726 return RETURN_ERR;
8727
developer72fb0bb2023-01-11 09:46:29 +08008728 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8729
8730 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
8731 _syscmd(cmd, buf, sizeof(buf));
8732 memset(cmd, 0, sizeof(cmd));
8733
8734 snprintf(port_str, sizeof(port_str), "%d", port);
8735 if (strlen(buf) == 0)
8736 // Append
8737 snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
8738 "auth_server_addr=%s\\n"
8739 "auth_server_port=%s\\n"
8740 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
8741 else {
8742 // Delete the three lines setting after the "# radius 2" comment
8743 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
8744 _syscmd(cmd, buf, sizeof(buf));
8745 memset(cmd, 0, sizeof(cmd));
8746 // Use "# radius 2" comment to find the location to insert the radius setting
8747 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
8748 "# radius 2\\n"
8749 "auth_server_addr=%s\\n"
8750 "auth_server_port=%s\\n"
8751 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
8752 }
8753 if(_syscmd(cmd, buf, sizeof(buf))) {
8754 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
8755 return RETURN_ERR;
8756 }
8757
8758 wifi_reloadAp(apIndex);
8759 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8760 return RETURN_OK;
8761}
8762
8763//RadiusSettings
8764INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
8765{
8766 if(!output)
8767 return RETURN_ERR;
8768
8769 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
developer69b61b02023-03-07 17:17:44 +08008770 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
8771 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
8772 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
8773 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 +08008774 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 +08008775 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
8776 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
8777 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 +08008778 //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.
8779
8780 return RETURN_OK;
8781}
8782
8783INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
8784{
8785 //store the paramters, and apply instantly
8786 return RETURN_ERR;
8787}
8788
8789//Device.WiFi.AccessPoint.{i}.WPS.Enable
8790//Enables or disables WPS functionality for this access point.
8791// outputs the WPS enable state of this ap in output_bool
8792INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
8793{
8794 char interface_name[16] = {0};
8795 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
8796 if(!output_bool)
8797 return RETURN_ERR;
8798 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8799 return RETURN_ERR;
8800 sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name);
8801 _syscmd(cmd, buf, sizeof(buf));
8802 if(strstr(buf, "configured"))
8803 *output_bool=TRUE;
8804 else
8805 *output_bool=FALSE;
8806
8807 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008808}
developer72fb0bb2023-01-11 09:46:29 +08008809
8810//Device.WiFi.AccessPoint.{i}.WPS.Enable
8811// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
8812INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
8813{
8814 char config_file[MAX_BUF_SIZE] = {0};
developere5750452023-05-15 16:46:42 +08008815 char buf[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008816 struct params params;
8817
8818 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8819 //store the paramters, and wait for wifi up to apply
8820 params.name = "wps_state";
developere5750452023-05-15 16:46:42 +08008821 if (enable == TRUE) {
8822 wifi_getApBeaconType(apIndex, buf);
8823 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
8824 params.value = "1";
8825 else // If ap set encryption
8826 params.value = "2";
8827 } else {
8828 params.value = "0";
8829 }
developer72fb0bb2023-01-11 09:46:29 +08008830
8831 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8832 wifi_hostapdWrite(config_file, &params, 1);
8833 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8834 wifi_reloadAp(apIndex);
8835
8836 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8837 return RETURN_OK;
8838}
8839
8840//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
8841INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
8842{
8843 if(!output)
8844 return RETURN_ERR;
8845 snprintf(output, 128, "PushButton,PIN");
8846 return RETURN_OK;
8847}
8848
8849//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
8850//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.
8851// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
8852INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
8853{
8854 if(!output)
8855 return RETURN_ERR;
8856 snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
8857
8858 return RETURN_OK;
8859}
8860
8861//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
8862// 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
8863INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
8864{
8865 //apply instantly. No setting need to be stored.
8866 char methods[MAX_BUF_SIZE], *token, *next_token;
8867 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
8868 struct params params;
8869
8870 if(!methodString)
8871 return RETURN_ERR;
8872 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8873 //store the paramters, and wait for wifi up to apply
8874
8875 snprintf(methods, sizeof(methods), "%s", methodString);
8876 for(token=methods; *token; token=next_token)
8877 {
8878 strtok_r(token, ",", &next_token);
8879 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
8880 snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
8881 else if(*token=='E')
8882 {
8883 if(!strcmp(methods, "Ethernet"))
8884 snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
8885 else if(!strcmp(methods, "ExternalNFCToken"))
8886 snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
8887 else
8888 printf("%s: Unknown WpsConfigMethod\n", __func__);
8889 }
8890 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
8891 snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
8892 else if(*token=='N' && !strcmp(token, "NFCInterface"))
8893 snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
8894 else if(*token=='P' )
8895 {
8896 if(!strcmp(token, "PushButton"))
developere5750452023-05-15 16:46:42 +08008897 snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developer72fb0bb2023-01-11 09:46:29 +08008898 else if(!strcmp(token, "PIN"))
8899 snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
8900 else
8901 printf("%s: Unknown WpsConfigMethod\n", __func__);
8902 }
8903 else
8904 printf("%s: Unknown WpsConfigMethod\n", __func__);
8905 }
8906 params.name = "config_methods";
8907 params.value = config_methods;
8908 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8909 wifi_hostapdWrite(config_file, &params, 1);
8910 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8911 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8912
8913 return RETURN_OK;
8914}
8915
8916// outputs the pin value, ulong_pin must be allocated by the caller
8917INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
8918{
8919 char buf[MAX_BUF_SIZE] = {0};
8920 char cmd[MAX_CMD_SIZE] = {0};
8921
8922 if(!output_ulong)
8923 return RETURN_ERR;
8924 snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
8925 _syscmd(cmd, buf, sizeof(buf));
8926 if(strlen(buf) > 0)
8927 *output_ulong=strtoul(buf, NULL, 10);
8928
8929 return RETURN_OK;
8930}
8931
8932// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
8933INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
8934{
8935 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
8936 char ap_pin[16] = {0};
8937 char buf[MAX_BUF_SIZE] = {0};
8938 char config_file[MAX_BUF_SIZE] = {0};
8939 ULONG prev_pin = 0;
8940 struct params params;
8941
8942 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8943 snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
8944 params.name = "ap_pin";
8945 params.value = ap_pin;
8946 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8947 wifi_hostapdWrite(config_file, &params, 1);
8948 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8949 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8950
8951 return RETURN_OK;
8952}
8953
8954// Output string is either Not configured or Configured, max 32 characters
8955INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
8956{
8957 char interface_name[16] = {0};
8958 char cmd[MAX_CMD_SIZE];
8959 char buf[MAX_BUF_SIZE]={0};
8960
8961 if(!output_string)
8962 return RETURN_ERR;
8963 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8964 snprintf(output_string, 32, "Not configured");
8965 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8966 return RETURN_ERR;
8967 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
8968 _syscmd(cmd, buf, sizeof(buf));
8969
8970 if(!strncmp(buf, "configured", 10))
8971 snprintf(output_string, 32, "Configured");
8972 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8973
8974 return RETURN_OK;
8975}
8976
8977// sets the WPS pin for this AP
8978INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
8979{
8980 char interface_name[16] = {0};
8981 char cmd[MAX_CMD_SIZE];
8982 char buf[MAX_BUF_SIZE]={0};
8983 BOOL enable;
8984
8985 wifi_getApEnable(apIndex, &enable);
8986 if (!enable)
8987 return RETURN_ERR;
8988 wifi_getApWpsEnable(apIndex, &enable);
8989 if (!enable)
8990 return RETURN_ERR;
8991
8992 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8993 return RETURN_ERR;
8994 snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
8995 _syscmd(cmd, buf, sizeof(buf));
8996 if((strstr(buf, "OK"))!=NULL)
8997 return RETURN_OK;
8998
8999 return RETURN_ERR;
9000}
9001
9002// This function is called when the WPS push button has been pressed for this AP
9003INT wifi_setApWpsButtonPush(INT apIndex)
9004{
9005 char cmd[MAX_CMD_SIZE];
9006 char buf[MAX_BUF_SIZE]={0};
9007 char interface_name[16] = {0};
9008 BOOL enable=FALSE;
9009
9010 wifi_getApEnable(apIndex, &enable);
9011 if (!enable)
9012 return RETURN_ERR;
9013
9014 wifi_getApWpsEnable(apIndex, &enable);
9015 if (!enable)
9016 return RETURN_ERR;
9017
9018 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9019 return RETURN_ERR;
9020
9021 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
9022 _syscmd(cmd, buf, sizeof(buf));
9023
9024 if((strstr(buf, "OK"))!=NULL)
9025 return RETURN_OK;
9026 return RETURN_ERR;
9027}
9028
9029// cancels WPS mode for this AP
9030INT wifi_cancelApWPS(INT apIndex)
9031{
9032 char interface_name[16] = {0};
9033 char cmd[MAX_CMD_SIZE];
9034 char buf[MAX_BUF_SIZE]={0};
9035
9036 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9037 return RETURN_ERR;
9038 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
9039 _syscmd(cmd,buf, sizeof(buf));
9040
9041 if((strstr(buf, "OK"))!=NULL)
9042 return RETURN_OK;
9043 return RETURN_ERR;
9044}
9045
9046//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
9047//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
9048INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
9049{
9050 char interface_name[16] = {0};
9051 FILE *f = NULL;
9052 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
9053 char cmd[256] = {0}, buf[2048] = {0};
9054 char *param = NULL, *value = NULL, *line=NULL;
9055 size_t len = 0;
9056 ssize_t nread = 0;
9057 wifi_associated_dev_t *dev=NULL;
9058
9059 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9060 *associated_dev_array = NULL;
9061 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9062 return RETURN_ERR;
9063 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9064 _syscmd(cmd,buf,sizeof(buf));
9065 *output_array_size = atoi(buf);
9066
9067 if (*output_array_size <= 0)
9068 return RETURN_OK;
9069
9070 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
9071 *associated_dev_array = dev;
9072 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
9073 _syscmd(cmd,buf,sizeof(buf));
9074 f = fopen("/tmp/connected_devices.txt", "r");
9075 if (f==NULL)
9076 {
9077 *output_array_size=0;
9078 return RETURN_ERR;
9079 }
9080 while ((getline(&line, &len, f)) != -1)
9081 {
9082 param = strtok(line,"=");
9083 value = strtok(NULL,"=");
9084
9085 if( strcmp("flags",param) == 0 )
9086 {
9087 value[strlen(value)-1]='\0';
9088 if(strstr (value,"AUTHORIZED") != NULL )
9089 {
9090 dev[auth_temp].cli_AuthenticationState = 1;
9091 dev[auth_temp].cli_Active = 1;
9092 auth_temp++;
9093 read_flag=1;
9094 }
9095 }
9096 if(read_flag==1)
9097 {
9098 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
9099 {
9100 value[strlen(value)-1]='\0';
9101 sscanf(value, "%x:%x:%x:%x:%x:%x",
9102 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
9103 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
9104 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
9105 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
9106 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
9107 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
9108 mac_temp++;
9109 read_flag=0;
9110 }
9111 }
9112 }
9113 *output_array_size = auth_temp;
9114 auth_temp=0;
9115 mac_temp=0;
9116 free(line);
9117 fclose(f);
9118 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9119 return RETURN_OK;
9120}
9121
9122#define MACADDRESS_SIZE 6
9123
9124INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9125{
9126 FILE *fp = NULL;
9127 char str[MAX_BUF_SIZE] = {0};
9128 int wificlientindex = 0 ;
9129 int count = 0;
9130 int signalstrength = 0;
9131 int arr[MACADDRESS_SIZE] = {0};
9132 unsigned char mac[MACADDRESS_SIZE] = {0};
9133 UINT wifi_count = 0;
9134 char virtual_interface_name[MAX_BUF_SIZE] = {0};
9135 char pipeCmd[MAX_CMD_SIZE] = {0};
9136
9137 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9138 *output_array_size = 0;
9139 *associated_dev_array = NULL;
9140
9141 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
9142 fp = popen(pipeCmd, "r");
developer69b61b02023-03-07 17:17:44 +08009143 if (fp == NULL)
developer72fb0bb2023-01-11 09:46:29 +08009144 {
9145 printf("Failed to run command inside function %s\n",__FUNCTION__ );
9146 return RETURN_ERR;
9147 }
9148
9149 /* Read the output a line at a time - output it. */
9150 fgets(str, sizeof(str)-1, fp);
9151 wifi_count = (unsigned int) atoi ( str );
9152 *output_array_size = wifi_count;
9153 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
9154 pclose(fp);
9155
9156 if(wifi_count == 0)
9157 {
9158 return RETURN_OK;
9159 }
9160 else
9161 {
9162 wifi_associated_dev3_t* temp = NULL;
9163 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
9164 if(temp == NULL)
9165 {
9166 printf("Error Statement. Insufficient memory \n");
9167 return RETURN_ERR;
9168 }
9169
9170 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
9171 system(pipeCmd);
9172 memset(pipeCmd,0,sizeof(pipeCmd));
9173 if(apIndex == 0)
9174 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
9175 else if(apIndex == 1)
9176 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
9177 system(pipeCmd);
9178
9179 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
9180 if(fp == NULL)
9181 {
9182 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
9183 free(temp);
9184 return RETURN_ERR;
9185 }
9186 fclose(fp);
9187
9188 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
9189 fp = popen(pipeCmd, "r");
9190 if(fp)
9191 {
9192 for(count =0 ; count < wifi_count; count++)
9193 {
9194 fgets(str, MAX_BUF_SIZE, fp);
9195 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9196 {
9197 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9198 {
9199 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9200
9201 }
9202 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9203 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]);
9204 }
9205 temp[count].cli_AuthenticationState = 1; //TODO
9206 temp[count].cli_Active = 1; //TODO
9207 }
9208 pclose(fp);
9209 }
9210
9211 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
9212 fp = popen(pipeCmd, "r");
9213 if(fp)
developer69b61b02023-03-07 17:17:44 +08009214 {
developer72fb0bb2023-01-11 09:46:29 +08009215 pclose(fp);
9216 }
9217 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
9218 if(fp)
9219 {
9220 for(count =0 ; count < wifi_count ;count++)
9221 {
9222 fgets(str, MAX_BUF_SIZE, fp);
9223 signalstrength = atoi(str);
9224 temp[count].cli_SignalStrength = signalstrength;
9225 temp[count].cli_RSSI = signalstrength;
9226 temp[count].cli_SNR = signalstrength + 95;
9227 }
9228 pclose(fp);
9229 }
9230
9231
9232 if((apIndex == 0) || (apIndex == 4))
9233 {
9234 for(count =0 ; count < wifi_count ;count++)
developer69b61b02023-03-07 17:17:44 +08009235 {
developer72fb0bb2023-01-11 09:46:29 +08009236 strcpy(temp[count].cli_OperatingStandard,"g");
9237 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
9238 }
9239
9240 //BytesSent
9241 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
9242 fp = popen(pipeCmd, "r");
9243 if(fp)
developer69b61b02023-03-07 17:17:44 +08009244 {
developer72fb0bb2023-01-11 09:46:29 +08009245 pclose(fp);
9246 }
9247 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
9248 if(fp)
9249 {
9250 for (count = 0; count < wifi_count; count++)
9251 {
9252 fgets(str, MAX_BUF_SIZE, fp);
9253 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
9254 }
9255 pclose(fp);
9256 }
9257
9258 //BytesReceived
9259 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
9260 fp = popen(pipeCmd, "r");
9261 if (fp)
9262 {
9263 pclose(fp);
9264 }
9265 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
9266 if (fp)
9267 {
9268 for (count = 0; count < wifi_count; count++)
9269 {
9270 fgets(str, MAX_BUF_SIZE, fp);
9271 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
9272 }
9273 pclose(fp);
9274 }
9275
9276 //PacketsSent
9277 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
9278 fp = popen(pipeCmd, "r");
9279 if (fp)
9280 {
9281 pclose(fp);
9282 }
9283
9284 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
9285 if (fp)
9286 {
9287 for (count = 0; count < wifi_count; count++)
9288 {
9289 fgets(str, MAX_BUF_SIZE, fp);
9290 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
9291 }
9292 pclose(fp);
9293 }
9294
9295 //PacketsReceived
9296 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
9297 fp = popen(pipeCmd, "r");
9298 if (fp)
9299 {
9300 pclose(fp);
9301 }
9302 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
9303 if (fp)
9304 {
9305 for (count = 0; count < wifi_count; count++)
9306 {
9307 fgets(str, MAX_BUF_SIZE, fp);
9308 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
9309 }
9310 pclose(fp);
9311 }
9312
9313 //ErrorsSent
9314 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9315 fp = popen(pipeCmd, "r");
9316 if (fp)
9317 {
9318 pclose(fp);
9319 }
9320 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9321 if (fp)
9322 {
9323 for (count = 0; count < wifi_count; count++)
9324 {
9325 fgets(str, MAX_BUF_SIZE, fp);
9326 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9327 }
9328 pclose(fp);
9329 }
9330
9331 //ErrorsSent
9332 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9333 fp = popen(pipeCmd, "r");
9334 if (fp)
9335 {
9336 pclose(fp);
9337 }
9338 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9339 if (fp)
9340 {
9341 for (count = 0; count < wifi_count; count++)
9342 {
9343 fgets(str, MAX_BUF_SIZE, fp);
9344 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9345 }
9346 pclose(fp);
9347 }
9348
9349 //LastDataDownlinkRate
9350 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
9351 fp = popen(pipeCmd, "r");
9352 if (fp)
9353 {
9354 pclose(fp);
9355 }
9356 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
9357 if (fp)
9358 {
9359 for (count = 0; count < wifi_count; count++)
9360 {
9361 fgets(str, MAX_BUF_SIZE, fp);
9362 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
9363 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
9364 }
9365 pclose(fp);
9366 }
9367
9368 //LastDataUplinkRate
9369 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
9370 fp = popen(pipeCmd, "r");
9371 if (fp)
9372 {
9373 pclose(fp);
9374 }
9375 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
9376 if (fp)
9377 {
9378 for (count = 0; count < wifi_count; count++)
9379 {
9380 fgets(str, MAX_BUF_SIZE, fp);
9381 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
9382 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
9383 }
9384 pclose(fp);
9385 }
9386
9387 }
9388 else if ((apIndex == 1) || (apIndex == 5))
9389 {
9390 for (count = 0; count < wifi_count; count++)
9391 {
9392 strcpy(temp[count].cli_OperatingStandard, "a");
9393 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
9394 temp[count].cli_BytesSent = 0;
9395 temp[count].cli_BytesReceived = 0;
9396 temp[count].cli_LastDataUplinkRate = 0;
9397 temp[count].cli_LastDataDownlinkRate = 0;
9398 temp[count].cli_PacketsSent = 0;
9399 temp[count].cli_PacketsReceived = 0;
9400 temp[count].cli_ErrorsSent = 0;
9401 }
9402 }
9403
9404 for (count = 0; count < wifi_count; count++)
9405 {
9406 temp[count].cli_Retransmissions = 0;
9407 temp[count].cli_DataFramesSentAck = 0;
9408 temp[count].cli_DataFramesSentNoAck = 0;
9409 temp[count].cli_MinRSSI = 0;
9410 temp[count].cli_MaxRSSI = 0;
9411 strncpy(temp[count].cli_InterferenceSources, "", 64);
9412 memset(temp[count].cli_IPAddress, 0, 64);
9413 temp[count].cli_RetransCount = 0;
9414 temp[count].cli_FailedRetransCount = 0;
9415 temp[count].cli_RetryCount = 0;
9416 temp[count].cli_MultipleRetryCount = 0;
9417 }
9418 *associated_dev_array = temp;
9419 }
9420 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9421 return RETURN_OK;
9422}
9423
developer7e4a2a62023-04-06 19:56:03 +08009424int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +08009425{
developer7e4a2a62023-04-06 19:56:03 +08009426 char cmd[MAX_CMD_SIZE] = {0};
9427 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009428
developer7e4a2a62023-04-06 19:56:03 +08009429 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
9430
9431 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
9432 interface_name);
9433 _syscmd(cmd, buf, MAX_BUF_SIZE);
9434
9435 strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */
9436
9437 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009438 return RETURN_OK;
9439}
9440
9441/* #define HOSTAPD_STA_PARAM_ENTRIES 29
9442struct hostapd_sta_param {
9443 char key[50];
9444 char value[100];
9445}
9446
9447static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){
9448 int i = 0;
9449
9450 while(i<HOSTAPD_STA_PARAM_ENTRIES) {
9451 if (strncmp(params[i].key,key,50) == 0){
9452 return &params[i].value;
9453 }
9454 i++;
9455 }
9456 return NULL;
9457
9458} */
9459
9460static unsigned int count_occurences(const char *buf, const char *word)
9461{
9462 unsigned int n = 0;
9463 char *ptr = strstr(buf, word);
9464
9465 while (ptr++) {
9466 n++;
9467 ptr = strstr(ptr, word);
9468 }
9469
9470 wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word);
9471 return n;
9472}
9473
9474static const char *get_line_from_str_buf(const char *buf, char *line)
9475{
9476 int i;
9477 int n = strlen(buf);
9478
9479 for (i = 0; i < n; i++) {
9480 line[i] = buf[i];
9481 if (buf[i] == '\n') {
9482 line[i] = '\0';
9483 return &buf[i + 1];
9484 }
9485 }
9486
9487 return NULL;
9488}
9489
9490INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9491{
developer0d26f2c2023-05-25 19:46:36 +08009492 char interface_name[16] = {0};
9493 FILE *f = NULL;
9494 int auth_temp= -1;
9495 char cmd[256] = {0}, buf[2048] = {0};
9496 char *param = NULL, *value = NULL, *line=NULL;
9497 size_t len = 0;
9498 wifi_associated_dev3_t *dev=NULL;
developer72fb0bb2023-01-11 09:46:29 +08009499
9500 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer0d26f2c2023-05-25 19:46:36 +08009501 *associated_dev_array = NULL;
9502 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08009503 return RETURN_ERR;
developer0d26f2c2023-05-25 19:46:36 +08009504 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9505 _syscmd(cmd, buf, sizeof(buf));
9506 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08009507
developer0d26f2c2023-05-25 19:46:36 +08009508 if (*output_array_size <= 0)
9509 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009510
developer0d26f2c2023-05-25 19:46:36 +08009511 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
9512 *associated_dev_array = dev;
9513 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
9514 _syscmd(cmd,buf,sizeof(buf));
9515 f = fopen("/tmp/diagnostic3_devices.txt", "r");
9516 if (f == NULL)
9517 {
9518 *output_array_size=0;
developer72fb0bb2023-01-11 09:46:29 +08009519 return RETURN_ERR;
9520 }
developer0d26f2c2023-05-25 19:46:36 +08009521 while ((getline(&line, &len, f)) != -1)
9522 {
9523 param = strtok(line, "=");
9524 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +08009525
developer0d26f2c2023-05-25 19:46:36 +08009526 if( strcmp("flags",param) == 0 )
9527 {
9528 value[strlen(value)-1]='\0';
9529 if(strstr (value,"AUTHORIZED") != NULL )
9530 {
9531 auth_temp++;
9532 dev[auth_temp].cli_AuthenticationState = 1;
9533 dev[auth_temp].cli_Active = 1;
developer72fb0bb2023-01-11 09:46:29 +08009534 }
developer0d26f2c2023-05-25 19:46:36 +08009535 } else if (auth_temp < 0) {
9536 continue;
9537 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
9538 {
9539 value[strlen(value)-1]='\0';
9540 sscanf(value, "%x:%x:%x:%x:%x:%x",
9541 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
9542 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
9543 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
9544 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
9545 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
9546 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
9547 } else if (strcmp("signal", param) == 0) {
9548 value[strlen(value)-1]='\0';
9549 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
9550 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
developer72fb0bb2023-01-11 09:46:29 +08009551 }
developer0d26f2c2023-05-25 19:46:36 +08009552 }
9553 if (line)
9554 free(line);
9555 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08009556 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009557 return RETURN_OK;
9558}
9559
9560#if 0
9561//To-do
9562INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9563{
9564 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9565
9566 //Using different approach to get required WiFi Parameters from system available commands
developer69b61b02023-03-07 17:17:44 +08009567#if 0
developer72fb0bb2023-01-11 09:46:29 +08009568 FILE *f;
9569 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
9570 char cmd[256], buf[2048];
9571 char *param , *value, *line=NULL;
9572 size_t len = 0;
9573 ssize_t nread;
9574 wifi_associated_dev3_t *dev=NULL;
9575 *associated_dev_array = NULL;
9576 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9577 _syscmd(cmd,buf,sizeof(buf));
9578 *output_array_size = atoi(buf);
9579
9580 if (*output_array_size <= 0)
9581 return RETURN_OK;
9582
9583 dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t));
9584 *associated_dev_array = dev;
9585 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name);
9586 _syscmd(cmd,buf,sizeof(buf));
9587 f = fopen("/tmp/connected_devices.txt", "r");
9588 if (f==NULL)
9589 {
9590 *output_array_size=0;
9591 return RETURN_ERR;
9592 }
9593 while ((nread = getline(&line, &len, f)) != -1)
9594 {
9595 param = strtok(line,"=");
9596 value = strtok(NULL,"=");
9597
9598 if( strcmp("flags",param) == 0 )
9599 {
9600 value[strlen(value)-1]='\0';
9601 if(strstr (value,"AUTHORIZED") != NULL )
9602 {
9603 dev[auth_temp].cli_AuthenticationState = 1;
9604 dev[auth_temp].cli_Active = 1;
9605 auth_temp++;
9606 read_flag=1;
9607 }
9608 }
9609 if(read_flag==1)
9610 {
9611 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
9612 {
9613 value[strlen(value)-1]='\0';
9614 sscanf(value, "%x:%x:%x:%x:%x:%x",
9615 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
9616 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
9617 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
9618 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
9619 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
9620 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
9621
9622 }
9623 else if( strcmp("rx_packets",param) == 0 )
9624 {
9625 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived));
9626 }
9627
9628 else if( strcmp("tx_packets",param) == 0 )
9629 {
developer69b61b02023-03-07 17:17:44 +08009630 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent));
developer72fb0bb2023-01-11 09:46:29 +08009631 }
9632
9633 else if( strcmp("rx_bytes",param) == 0 )
9634 {
9635 sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived));
9636 }
9637
9638 else if( strcmp("tx_bytes",param) == 0 )
9639 {
developer69b61b02023-03-07 17:17:44 +08009640 sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent));
developer72fb0bb2023-01-11 09:46:29 +08009641 mac_temp++;
9642 read_flag=0;
developer69b61b02023-03-07 17:17:44 +08009643 }
developer72fb0bb2023-01-11 09:46:29 +08009644 }
9645 }
9646
9647 *output_array_size = auth_temp;
9648 auth_temp=0;
9649 mac_temp=0;
9650 free(line);
9651 fclose(f);
9652#endif
9653 char interface_name[MAX_BUF_SIZE] = {0};
9654 char wifi_status[MAX_BUF_SIZE] = {0};
9655 char hostapdconf[MAX_BUF_SIZE] = {0};
9656
9657 wifi_associated_dev3_t *dev_array = NULL;
9658 ULONG wifi_count = 0;
9659
9660 *associated_dev_array = NULL;
9661 *output_array_size = 0;
9662
9663 printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex);
9664 //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI.
9665 {
9666 sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex);
9667
9668 wifi_GetInterfaceName(interface_name, hostapdconf);
9669
9670 if(strlen(interface_name) > 1)
9671 {
9672 wifihal_interfacestatus(wifi_status,interface_name);
9673 if(strcmp(wifi_status,"RUNNING") == 0)
9674 {
9675 wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count);
9676
9677 *associated_dev_array = dev_array;
developer69b61b02023-03-07 17:17:44 +08009678 *output_array_size = wifi_count;
developer72fb0bb2023-01-11 09:46:29 +08009679 }
9680 else
9681 {
9682 *associated_dev_array = NULL;
9683 }
9684 }
9685 }
9686
9687 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9688 return RETURN_OK;
9689}
9690#endif
9691
9692/* getIPAddress function */
9693/**
9694* @description Returning IpAddress of the Matched String
9695*
developer69b61b02023-03-07 17:17:44 +08009696* @param
developer72fb0bb2023-01-11 09:46:29 +08009697* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +08009698* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +08009699* @return The status of the operation
9700* @retval RETURN_OK if successful
9701* @retval RETURN_ERR if any error is detected
9702*
9703*/
9704
9705INT getIPAddress(char *str,char *ipaddr)
9706{
9707 FILE *fp = NULL;
9708 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
9709 int LeaseTime = 0,ret = 0;
9710 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
9711 {
9712 return RETURN_ERR;
9713 }
9714
9715 while ( fgets(buf, sizeof(buf), fp)!= NULL )
9716 {
9717 /*
9718 Sample:sss
9719 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
9720 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
9721 */
9722 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
9723 &(LeaseTime),
9724 phyAddr,
9725 ipAddr,
9726 hostName
9727 );
9728 if(ret != 4)
9729 continue;
9730 if(strcmp(str,phyAddr) == 0)
9731 strcpy(ipaddr,ipAddr);
9732 }
9733 fclose(fp);
9734 return RETURN_OK;
9735}
9736
9737/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
9738/**
9739* @description Returning Inactive wireless connected clients informations
9740*
developer69b61b02023-03-07 17:17:44 +08009741* @param
developer72fb0bb2023-01-11 09:46:29 +08009742* @filename Holding private_wifi 2g/5g content files
9743* @associated_dev_array Having inactiv wireless clients informations
9744* @output_array_size Returning Inactive wireless counts
9745* @return The status of the operation
9746* @retval RETURN_OK if successful
9747* @retval RETURN_ERR if any error is detected
9748*
9749*/
9750
9751INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9752{
9753 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9754 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
9755 FILE *fp = NULL;
9756 int arr[MACADDRESS_SIZE] = {0};
9757 unsigned char mac[MACADDRESS_SIZE] = {0};
9758 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
9759 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
9760 fp = popen(buf,"r");
9761 if(fp == NULL)
9762 return RETURN_ERR;
9763 else
9764 {
9765 fgets(path,sizeof(path),fp);
9766 maccount = atoi(path);
9767 }
9768 pclose(fp);
9769 *output_array_size = maccount;
9770 wifi_associated_dev3_t* temp = NULL;
9771 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
9772 *associated_dev_array = temp;
9773 if(temp == NULL)
9774 {
9775 printf("Error Statement. Insufficient memory \n");
9776 return RETURN_ERR;
9777 }
9778 memset(buf,0,sizeof(buf));
9779 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
9780 fp = popen(buf,"r");
9781 if (fp == NULL) {
9782 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
9783 return RETURN_ERR;
9784 }
9785 for(count = 0; count < maccount ; count++)
9786 {
9787 fgets(path,sizeof(path),fp);
9788 for(i = 0; path[i]!='\n';i++)
9789 str[i]=path[i];
9790 str[i]='\0';
9791 getIPAddress(str,ipaddr);
9792 memset(buf,0,sizeof(buf));
9793 if(strlen(ipaddr) > 0)
9794 {
9795 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
9796 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
9797 {
9798 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9799 {
9800 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9801 {
9802 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9803
9804 }
9805 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9806 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]);
9807 }
9808 temp[count].cli_AuthenticationState = 0; //TODO
developer69b61b02023-03-07 17:17:44 +08009809 temp[count].cli_Active = 0; //TODO
developer72fb0bb2023-01-11 09:46:29 +08009810 temp[count].cli_SignalStrength = 0;
9811 }
9812 else //Active wireless clients info
9813 {
9814 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9815 {
9816 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9817 {
9818 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9819
9820 }
9821 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9822 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]);
9823 }
9824 temp[count].cli_Active = 1;
9825 }
9826 }
9827 memset(ipaddr,0,sizeof(ipaddr));
9828 }
9829 pclose(fp);
9830 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9831 return RETURN_OK;
9832}
9833//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
9834//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
9835//To get Band Steering Capability
9836INT wifi_getBandSteeringCapability(BOOL *support)
9837{
9838 *support = FALSE;
9839 return RETURN_OK;
9840}
9841
9842
9843//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
9844//To get Band Steering enable status
9845INT wifi_getBandSteeringEnable(BOOL *enable)
9846{
9847 *enable = FALSE;
9848 return RETURN_OK;
9849}
9850
9851//To turn on/off Band steering
9852INT wifi_setBandSteeringEnable(BOOL enable)
9853{
9854 return RETURN_OK;
9855}
9856
9857//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
9858//To get Band Steering AP group
9859INT wifi_getBandSteeringApGroup(char *output_ApGroup)
9860{
9861 if (NULL == output_ApGroup)
9862 return RETURN_ERR;
9863
9864 strcpy(output_ApGroup, "1,2");
9865 return RETURN_OK;
9866}
9867
9868//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
9869//to set and read the band steering BandUtilizationThreshold parameters
9870INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
9871{
9872 return RETURN_ERR;
9873}
9874
9875INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
9876{
9877 return RETURN_ERR;
9878}
9879
9880//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
9881//to set and read the band steering RSSIThreshold parameters
9882INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
9883{
9884 return RETURN_ERR;
9885}
9886
9887INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
9888{
9889 return RETURN_ERR;
9890}
9891
9892
9893//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
9894//to set and read the band steering physical modulation rate threshold parameters
9895INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
9896{
9897 //If chip is not support, return -1
9898 return RETURN_ERR;
9899}
9900
9901INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
9902{
9903 //If chip is not support, return -1
9904 return RETURN_ERR;
9905}
9906
9907//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
9908//to set and read the inactivity time (in seconds) for steering under overload condition
9909INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
9910{
9911 return RETURN_ERR;
9912}
9913
9914INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
9915{
9916 return RETURN_ERR;
9917}
9918
9919//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
9920//to set and read the inactivity time (in seconds) for steering under Idle condition
9921INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
9922{
9923 return RETURN_ERR;
9924}
9925
9926INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
9927{
9928 return RETURN_ERR;
9929}
9930
9931//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
9932//pClientMAC[64]
9933//pSourceSSIDIndex[64]
9934//pDestSSIDIndex[64]
9935//pSteeringReason[256]
9936INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
9937{
9938 //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
9939 *pSteeringTime=time(NULL);
9940 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
9941 return RETURN_OK;
9942}
9943
9944INT wifi_ifConfigDown(INT apIndex)
9945{
9946 INT status = RETURN_OK;
9947 char cmd[64];
9948
9949 snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
9950 printf("%s: %s\n", __func__, cmd);
9951 system(cmd);
9952
9953 return status;
9954}
9955
9956INT wifi_ifConfigUp(INT apIndex)
9957{
9958 char interface_name[16] = {0};
9959 char cmd[128];
9960 char buf[1024];
9961
9962 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9963 return RETURN_ERR;
9964 snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
9965 _syscmd(cmd, buf, sizeof(buf));
9966 return 0;
9967}
9968
9969//>> Deprecated. Replace with wifi_applyRadioSettings
9970INT wifi_pushBridgeInfo(INT apIndex)
9971{
developerb2977562023-05-24 17:54:12 +08009972 char ip[32] = {0};
9973 char subnet[32] = {0};
9974 char bridge[32] = {0};
9975 char cmd[128] = {0};
9976 char buf[1024] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009977
developerb2977562023-05-24 17:54:12 +08009978 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +08009979
developerb2977562023-05-24 17:54:12 +08009980 snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
9981 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009982
developerb2977562023-05-24 17:54:12 +08009983 return 0;
developer72fb0bb2023-01-11 09:46:29 +08009984}
9985
9986INT wifi_pushChannel(INT radioIndex, UINT channel)
9987{
9988 char interface_name[16] = {0};
9989 char cmd[128];
9990 char buf[1024];
9991 int apIndex;
9992
developer69b61b02023-03-07 17:17:44 +08009993 apIndex=(radioIndex==0)?0:1;
developer72fb0bb2023-01-11 09:46:29 +08009994 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
9995 return RETURN_ERR;
9996 snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
9997 _syscmd(cmd,buf, sizeof(buf));
9998
9999 return 0;
10000}
10001
10002INT wifi_pushChannelMode(INT radioIndex)
10003{
10004 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
10005 return RETURN_ERR;
10006}
10007
10008INT wifi_pushDefaultValues(INT radioIndex)
10009{
10010 //Apply Comcast specified default radio settings instantly
10011 //AMPDU=1
10012 //AMPDUFrames=32
10013 //AMPDULim=50000
10014 //txqueuelen=1000
10015
10016 return RETURN_ERR;
10017}
10018
10019INT wifi_pushTxChainMask(INT radioIndex)
10020{
10021 //Apply default TxChainMask instantly
10022 return RETURN_ERR;
10023}
10024
10025INT wifi_pushRxChainMask(INT radioIndex)
10026{
10027 //Apply default RxChainMask instantly
10028 return RETURN_ERR;
10029}
10030
10031INT wifi_pushSSID(INT apIndex, CHAR *ssid)
10032{
developer7e4a2a62023-04-06 19:56:03 +080010033 INT status;
developer72fb0bb2023-01-11 09:46:29 +080010034
developer7e4a2a62023-04-06 19:56:03 +080010035 status = wifi_setSSIDName(apIndex, ssid);
10036 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010037
developer7e4a2a62023-04-06 19:56:03 +080010038 return status;
developer72fb0bb2023-01-11 09:46:29 +080010039}
10040
10041INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
10042{
10043 //Apply default Ssid Advertisement instantly
10044 return RETURN_ERR;
10045}
10046
10047INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
10048{
developere82c0ca2023-05-10 16:25:35 +080010049 time_t now;
10050
10051 time(&now);
10052 if (now > radio_up_time[radioIndex])
10053 *output = now - radio_up_time[radioIndex];
10054 else {
10055 *output = 0;
10056 return RETURN_ERR;
10057 }
10058
10059 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010060}
10061
10062INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
10063{
10064 return RETURN_OK;
10065}
10066
10067INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
10068{
10069 return RETURN_OK;
10070}
10071
10072//To-do
10073INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
10074{
10075 char output[16]={'\0'};
10076 char config_file[MAX_BUF_SIZE] = {0};
10077
10078 if (!output_string)
10079 return RETURN_ERR;
10080
10081 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10082 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
10083
10084 if (strlen(output) == 0)
10085 snprintf(output_string, 64, "Disabled");
10086 else if (strncmp(output, "0", 1) == 0)
10087 snprintf(output_string, 64, "Disabled");
10088 else if (strncmp(output, "1", 1) == 0)
10089 snprintf(output_string, 64, "Optional");
10090 else if (strncmp(output, "2", 1) == 0)
10091 snprintf(output_string, 64, "Required");
10092 else {
10093 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
10094 return RETURN_ERR;
10095 }
10096
10097 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
10098 return RETURN_OK;
10099}
10100INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
10101{
10102 char str[MAX_BUF_SIZE]={'\0'};
10103 char cmd[MAX_CMD_SIZE]={'\0'};
10104 struct params params;
10105 char config_file[MAX_BUF_SIZE] = {0};
10106
10107 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10108 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
10109 return RETURN_ERR;
10110
10111 params.name = "ieee80211w";
10112 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
10113 params.value = "0";
10114 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
10115 params.value = "1";
10116 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
10117 params.value = "2";
10118 else{
10119 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
10120 return RETURN_ERR;
10121 }
10122 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10123 wifi_hostapdWrite(config_file, &params, 1);
10124 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10125 return RETURN_OK;
10126}
10127INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
10128{
10129 char output[16]={'\0'};
10130 char config_file[MAX_BUF_SIZE] = {0};
10131
10132 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerc0772e62023-05-18 15:10:48 +080010133 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
developer262f4cb2023-05-24 12:22:04 +080010134 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080010135
developer262f4cb2023-05-24 12:22:04 +080010136 if (output == NULL)
10137 *output_bool = FALSE;
10138 else if (strncmp(output, "1", 1) == 0)
10139 *output_bool = TRUE;
10140 else if (strncmp(output, "2", 1) == 0)
10141 *output_bool = TRUE;
10142 else if (strncmp(output, "3", 1) == 0)
10143 *output_bool = TRUE;
10144 else
10145 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010146 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
10147
10148 return RETURN_OK;
10149}
10150
10151INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
10152{
10153 return RETURN_OK;
10154}
10155
10156INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
10157{
10158 return RETURN_OK;
10159}
10160
10161INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
10162{
10163 return RETURN_OK;
10164}
10165
10166INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10167{
10168 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10169 char config_file[MAX_BUF_SIZE] = {0};
10170
10171 if (NULL == output)
10172 return RETURN_ERR;
10173 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10174 wifi_hostapdRead(config_file,"hw_mode",output,64);
10175
10176 if(strcmp(output,"b")==0)
10177 sprintf(output, "%s", "1,2,5.5,11");
10178 else if (strcmp(output,"a")==0)
10179 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
10180 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
10181 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
10182
10183 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10184 return RETURN_OK;
10185}
10186
10187INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10188{
10189 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10190 char *temp;
10191 char temp_output[128];
10192 char temp_TransmitRates[128];
10193 char config_file[MAX_BUF_SIZE] = {0};
10194
10195 if (NULL == output)
10196 return RETURN_ERR;
10197
10198 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10199 wifi_hostapdRead(config_file,"supported_rates",output,64);
10200
10201 if (strlen(output) == 0) {
10202 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
10203 return RETURN_OK;
10204 }
10205 strcpy(temp_TransmitRates,output);
10206 strcpy(temp_output,"");
10207 temp = strtok(temp_TransmitRates," ");
10208 while(temp!=NULL)
10209 {
10210 temp[strlen(temp)-1]=0;
10211 if((temp[0]=='5') && (temp[1]=='\0'))
10212 {
10213 temp="5.5";
10214 }
10215 strcat(temp_output,temp);
10216 temp = strtok(NULL," ");
10217 if(temp!=NULL)
10218 {
10219 strcat(temp_output,",");
10220 }
10221 }
10222 strcpy(output,temp_output);
10223 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10224
10225 return RETURN_OK;
10226}
10227
10228INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10229{
10230 return RETURN_OK;
10231}
10232
10233
10234INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10235{
10236 int i=0;
10237 char *temp;
10238 char temp1[128] = {0};
10239 char temp_output[128] = {0};
10240 char temp_TransmitRates[128] = {0};
10241 struct params params={'\0'};
10242 char config_file[MAX_BUF_SIZE] = {0};
10243 wifi_band band = wifi_index_to_band(wlanIndex);
10244
10245 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10246 if(NULL == output)
10247 return RETURN_ERR;
10248 strcpy(temp_TransmitRates,output);
10249
10250 for(i=0;i<strlen(temp_TransmitRates);i++)
10251 {
10252 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
10253 {
10254 continue;
10255 }
10256 else
10257 {
10258 return RETURN_ERR;
10259 }
10260 }
10261 strcpy(temp_output,"");
10262 temp = strtok(temp_TransmitRates,",");
10263 while(temp!=NULL)
10264 {
10265 strcpy(temp1,temp);
10266 if(band == band_5)
10267 {
10268 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
10269 {
10270 return RETURN_ERR;
10271 }
10272 }
10273
10274 if(strcmp(temp,"5.5")==0)
10275 {
10276 strcpy(temp1,"55");
10277 }
10278 else
10279 {
10280 strcat(temp1,"0");
10281 }
10282 strcat(temp_output,temp1);
10283 temp = strtok(NULL,",");
10284 if(temp!=NULL)
10285 {
10286 strcat(temp_output," ");
10287 }
10288 }
10289 strcpy(output,temp_output);
10290
10291 params.name = "supported_rates";
10292 params.value = output;
10293
10294 wifi_dbg_printf("\n%s:",__func__);
10295 wifi_dbg_printf("params.value=%s\n",params.value);
10296 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10297 wifi_hostapdWrite(config_file,&params,1);
10298 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10299
10300 return RETURN_OK;
10301}
10302
10303
10304static char *sncopy(char *dst, int dst_sz, const char *src)
10305{
10306 if (src && dst && dst_sz > 0) {
10307 strncpy(dst, src, dst_sz);
10308 dst[dst_sz - 1] = '\0';
10309 }
10310 return dst;
10311}
10312
10313static int util_get_sec_chan_offset(int channel, const char* ht_mode)
10314{
10315 if (0 == strcmp(ht_mode, "HT40") ||
10316 0 == strcmp(ht_mode, "HT80") ||
10317 0 == strcmp(ht_mode, "HT160")) {
10318 switch (channel) {
10319 case 1 ... 7:
10320 case 36:
10321 case 44:
10322 case 52:
10323 case 60:
10324 case 100:
10325 case 108:
10326 case 116:
10327 case 124:
10328 case 132:
10329 case 140:
10330 case 149:
10331 case 157:
10332 return 1;
10333 case 8 ... 13:
10334 case 40:
10335 case 48:
10336 case 56:
10337 case 64:
10338 case 104:
10339 case 112:
10340 case 120:
10341 case 128:
10342 case 136:
10343 case 144:
10344 case 153:
10345 case 161:
10346 return -1;
10347 default:
10348 return -EINVAL;
10349 }
10350 }
10351
10352 return -EINVAL;
10353}
10354
10355static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
10356{
10357 int idx = channel%8;
10358 if (0 == strcmp(ht_mode, "HT40") ||
10359 0 == strcmp(ht_mode, "HT80") ||
10360 0 == strcmp(ht_mode, "HT160")) {
10361 switch (idx) {
10362 case 1:
10363 return 1;
10364 case 5:
10365 return -1;
10366 default:
10367 return -EINVAL;
10368 }
10369 }
10370
10371 return -EINVAL;
10372}
10373static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
10374{
10375 if (NULL == hw_mode) return;
10376
10377 if (0 == strcmp(hw_mode, "ac"))
10378 sncopy(bw_mode, bw_mode_len, "ht vht");
10379
10380 if (0 == strcmp(hw_mode, "n"))
10381 sncopy(bw_mode, bw_mode_len, "ht");
10382
10383 return;
10384}
10385
10386static int util_chan_to_freq(int chan)
10387{
10388 if (chan == 14)
10389 return 2484;
10390 else if (chan < 14)
10391 return 2407 + chan * 5;
10392 else if (chan >= 182 && chan <= 196)
10393 return 4000 + chan * 5;
10394 else
10395 return 5000 + chan * 5;
10396 return 0;
10397}
10398
10399static int util_6G_chan_to_freq(int chan)
10400{
10401 if (chan)
10402 return 5950 + chan * 5;
10403 else
10404 return 0;
developer69b61b02023-03-07 17:17:44 +080010405
developer72fb0bb2023-01-11 09:46:29 +080010406}
10407const int *util_unii_5g_chan2list(int chan, int width)
10408{
10409 static const int lists[] = {
10410 // <width>, <chan1>, <chan2>..., 0,
10411 20, 36, 0,
10412 20, 40, 0,
10413 20, 44, 0,
10414 20, 48, 0,
10415 20, 52, 0,
10416 20, 56, 0,
10417 20, 60, 0,
10418 20, 64, 0,
10419 20, 100, 0,
10420 20, 104, 0,
10421 20, 108, 0,
10422 20, 112, 0,
10423 20, 116, 0,
10424 20, 120, 0,
10425 20, 124, 0,
10426 20, 128, 0,
10427 20, 132, 0,
10428 20, 136, 0,
10429 20, 140, 0,
10430 20, 144, 0,
10431 20, 149, 0,
10432 20, 153, 0,
10433 20, 157, 0,
10434 20, 161, 0,
10435 20, 165, 0,
10436 40, 36, 40, 0,
10437 40, 44, 48, 0,
10438 40, 52, 56, 0,
10439 40, 60, 64, 0,
10440 40, 100, 104, 0,
10441 40, 108, 112, 0,
10442 40, 116, 120, 0,
10443 40, 124, 128, 0,
10444 40, 132, 136, 0,
10445 40, 140, 144, 0,
10446 40, 149, 153, 0,
10447 40, 157, 161, 0,
10448 80, 36, 40, 44, 48, 0,
10449 80, 52, 56, 60, 64, 0,
10450 80, 100, 104, 108, 112, 0,
10451 80, 116, 120, 124, 128, 0,
10452 80, 132, 136, 140, 144, 0,
10453 80, 149, 153, 157, 161, 0,
10454 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
10455 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
10456 -1 // final delimiter
10457 };
10458 const int *start;
10459 const int *p;
10460
10461 for (p = lists; *p != -1; p++) {
10462 if (*p == width) {
10463 for (start = ++p; *p != 0; p++) {
10464 if (*p == chan)
10465 return start;
10466 }
10467 }
10468 // move to the end of channel list of given width
10469 while (*p != 0) {
10470 p++;
10471 }
10472 }
10473
10474 return NULL;
10475}
10476
10477static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
10478{
10479 if (NULL == ht_mode)
10480 return 0;
10481
10482 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
10483 const int *chans = util_unii_5g_chan2list(channel, width);
10484 int sum = 0;
10485 int cnt = 0;
10486
10487 if (NULL == chans)
10488 return 0;
10489
10490 while (*chans) {
10491 sum += *chans;
10492 cnt++;
10493 chans++;
10494 }
10495 if (cnt == 0)
10496 return 0;
10497 return sum / cnt;
10498}
10499
10500static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
10501{
10502 if (NULL == ht_mode)
10503 return 0;
10504
10505 int width = strtol((ht_mode + 2), NULL, 10);
10506
10507 int idx = 0 ;
10508 int centerchan = 0;
10509 int chan_ofs = 1;
10510
10511 if (width == 40){
10512 idx = ((channel/4) + chan_ofs)%2;
10513 switch (idx) {
10514 case 0:
10515 centerchan = (channel - 2);
10516 break;
10517 case 1:
10518 centerchan = (channel + 2);
developer69b61b02023-03-07 17:17:44 +080010519 break;
developer72fb0bb2023-01-11 09:46:29 +080010520 default:
10521 return -EINVAL;
10522 }
10523 }else if (width == 80){
developer69b61b02023-03-07 17:17:44 +080010524 idx = ((channel/4) + chan_ofs)%4;
developer72fb0bb2023-01-11 09:46:29 +080010525 switch (idx) {
10526 case 0:
10527 centerchan = (channel - 6);
10528 break;
10529 case 1:
10530 centerchan = (channel + 6);
10531 break;
10532 case 2:
10533 centerchan = (channel + 2);
10534 break;
10535 case 3:
10536 centerchan = (channel - 2);
10537 break;
10538 default:
10539 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080010540 }
developer72fb0bb2023-01-11 09:46:29 +080010541 }else if (width == 160){
10542 switch (channel) {
10543 case 1 ... 29:
10544 centerchan = 15;
10545 break;
10546 case 33 ... 61:
10547 centerchan = 47;
10548 break;
10549 case 65 ... 93:
10550 centerchan = 79;
10551 break;
10552 case 97 ... 125:
10553 centerchan = 111;
10554 break;
10555 case 129 ... 157:
10556 centerchan = 143;
10557 break;
10558 case 161 ... 189:
10559 centerchan = 175;
10560 break;
10561 case 193 ... 221:
10562 centerchan = 207;
10563 break;
10564 default:
10565 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080010566 }
developer72fb0bb2023-01-11 09:46:29 +080010567 }
10568 return centerchan;
10569}
10570static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
10571{
10572 BOOL onlyG, onlyN, onlyA;
10573 CHAR tmp[64];
10574 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
10575 if (ret == RETURN_OK) {
10576 sncopy(hw_mode, hw_mode_size, tmp);
10577 }
10578 return ret;
10579}
10580
10581INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
10582{
10583 // Sample commands:
10584 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
10585 // hostapd_cli -i wifi0 chan_switch 30 2437
10586 char cmd[MAX_CMD_SIZE] = {0};
10587 char buf[MAX_BUF_SIZE] = {0};
10588 int freq = 0, ret = 0;
10589 char center_freq1_str[32] = ""; // center_freq1=%d
10590 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
10591 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
10592 char hw_mode[16] = ""; // n|ac
10593 char bw_mode[16] = ""; // ht|ht vht
10594 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
10595 char interface_name[16] = {0};
10596 int sec_chan_offset;
10597 int width;
10598 char config_file[64] = {0};
10599 BOOL stbcEnable = FALSE;
10600 char *ext_str = "None";
10601 wifi_band band = band_invalid;
10602 int center_chan = 0;
10603 int center_freq1 = 0;
developerd1824452023-05-18 12:30:04 +080010604 struct params mwctl = {0};
10605 char str_channel[8]={0};
developer72fb0bb2023-01-11 09:46:29 +080010606
10607 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
10608
10609 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10610 return RETURN_ERR;
10611
10612 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10613
10614 band = wifi_index_to_band(radioIndex);
10615
10616 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
10617
10618 // Get radio mode HT20|HT40|HT80 etc.
10619 if (channel){
10620 if (band == band_6){
10621 freq = util_6G_chan_to_freq(channel);
10622 }else{
10623 freq = util_chan_to_freq(channel);
10624 }
10625 snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
10626
10627 // Provide bandwith if specified
10628 if (channel_width_MHz > 20) {
10629 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
10630 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
10631 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
10632
10633 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
10634 }else if (channel_width_MHz == 20){
10635 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
10636 }
10637
10638
10639 if (channel_width_MHz > 20) {
10640 if (band == band_6){
10641 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
10642 if(center_chan){
10643 center_freq1 = util_6G_chan_to_freq(center_chan);
10644 }
10645 }else{
10646 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
10647 if(center_chan){
10648 center_freq1 = util_chan_to_freq(center_chan);
10649 }
10650 }
developer69b61b02023-03-07 17:17:44 +080010651
developer72fb0bb2023-01-11 09:46:29 +080010652 if (center_freq1)
10653 snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080010654
developer72fb0bb2023-01-11 09:46:29 +080010655 }
10656
10657 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
10658 if (band == band_6){
10659 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
10660 }else{
10661 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
10662 }
10663 if (sec_chan_offset != -EINVAL)
10664 snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
10665
10666 // Only the first AP, other are hanging on the same radio
10667 int apIndex = radioIndex;
developerd1824452023-05-18 12:30:04 +080010668 /* snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s chan_switch %d %d %s %s %s",
developer72fb0bb2023-01-11 09:46:29 +080010669 interface_name, csa_beacon_count, freq,
developerd1824452023-05-18 12:30:04 +080010670 sec_chan_offset_str, center_freq1_str, opt_chan_info_str); */
10671 snprintf(str_channel, sizeof(str_channel), "%d", channel);
10672 mwctl.name = "channel num=";
10673 mwctl.value = str_channel;
10674 ret = wifi_mwctlSet(radioIndex, &mwctl, BASE_PHY_INDEX);
10675 if (ret != RETURN_OK) {
10676 fprintf(stderr, "%s: wifi_mwctlSet return error.\n", __func__);
10677 return RETURN_ERR;
10678 }
10679 /* wifi_dbg_printf("execute: '%s'\n", cmd);
developerf6a87542023-05-16 15:47:28 +080010680 ret = _syscmd(cmd, buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +080010681 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080010682
10683 ret = wifi_setRadioChannel(radioIndex, channel);
10684 if (ret != RETURN_OK) {
10685 fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__);
10686 return RETURN_ERR;
10687 }
10688
developer262f4cb2023-05-24 12:22:04 +080010689 if (sec_chan_offset == 1)
10690 ext_str = "Above";
10691 else if (sec_chan_offset == -1)
10692 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080010693
developerd1824452023-05-18 12:30:04 +080010694 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080010695
10696 } else {
10697 if (channel_width_MHz > 20)
10698 ext_str = "Above";
10699 }
10700
10701 wifi_setRadioExtChannel(radioIndex, ext_str);
10702
10703 char mhz_str[16];
10704 snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
10705 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
10706
10707 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10708
10709 return RETURN_OK;
10710}
10711
10712INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
10713{
10714 int index = -1;
10715 wifi_neighbor_ap2_t *scan_array = NULL;
10716 char cmd[256]={0};
10717 char buf[128]={0};
10718 char file_name[32] = {0};
10719 char filter_SSID[32] = {0};
10720 char line[256] = {0};
10721 char interface_name[16] = {0};
10722 char *ret = NULL;
10723 int freq=0;
10724 FILE *f = NULL;
10725 size_t len=0;
10726 int channels_num = 0;
10727 int vht_channel_width = 0;
10728 int get_noise_ret = RETURN_ERR;
10729 bool filter_enable = false;
10730 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
10731 int phyId = 0;
10732
10733 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
10734
10735 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
10736 f = fopen(file_name, "r");
10737 if (f != NULL) {
10738 fgets(filter_SSID, sizeof(file_name), f);
10739 if (strlen(filter_SSID) != 0)
10740 filter_enable = true;
10741 fclose(f);
10742 }
10743
10744 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
10745 return RETURN_ERR;
10746
10747 phyId = radio_index_to_phy(radio_index);
10748
10749 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
10750 _syscmd(cmd, buf, sizeof(buf));
10751 channels_num = strtol(buf, NULL, 10);
10752
10753 sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
10754 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
10755 fprintf(stderr, "cmd: %s\n", cmd);
10756 if ((f = popen(cmd, "r")) == NULL) {
10757 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
10758 return RETURN_ERR;
10759 }
developer69b61b02023-03-07 17:17:44 +080010760
developer72fb0bb2023-01-11 09:46:29 +080010761 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
10762 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +080010763
developer72fb0bb2023-01-11 09:46:29 +080010764 ret = fgets(line, sizeof(line), f);
10765 while (ret != NULL) {
10766 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +080010767 // 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 +080010768 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
10769 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
10770
10771 if (!filter_BSS) {
10772 index++;
10773 wifi_neighbor_ap2_t *tmp;
10774 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
10775 if (tmp == NULL) { // no more memory to use
10776 index--;
10777 wifi_dbg_printf("%s: realloc failed\n", __func__);
10778 break;
10779 }
10780 scan_array = tmp;
10781 }
10782 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
10783
10784 filter_BSS = false;
10785 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
10786 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
10787 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
10788 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
10789 } else if (strstr(line, "freq") != NULL) {
10790 sscanf(line," freq: %d", &freq);
10791 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
10792
10793 if (freq >= 2412 && freq <= 2484) {
10794 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
10795 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
10796 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
10797 }
10798 else if (freq >= 5160 && freq <= 5805) {
10799 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
10800 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
10801 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
10802 }
10803
10804 scan_array[index].ap_Noise = 0;
10805 if (get_noise_ret == RETURN_OK) {
10806 for (int i = 0; i < channels_num; i++) {
10807 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
10808 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
10809 break;
10810 }
10811 }
10812 }
10813 } else if (strstr(line, "beacon interval") != NULL) {
10814 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
10815 } else if (strstr(line, "signal") != NULL) {
10816 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
10817 } else if (strstr(line,"SSID") != NULL) {
10818 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
10819 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
10820 filter_BSS = true;
10821 }
10822 } else if (strstr(line, "Supported rates") != NULL) {
10823 char SRate[80] = {0}, *tmp = NULL;
10824 memset(buf, 0, sizeof(buf));
10825 strcpy(SRate, line);
10826 tmp = strtok(SRate, ":");
10827 tmp = strtok(NULL, ":");
10828 strcpy(buf, tmp);
10829 memset(SRate, 0, sizeof(SRate));
10830
10831 tmp = strtok(buf, " \n");
10832 while (tmp != NULL) {
10833 strcat(SRate, tmp);
10834 if (SRate[strlen(SRate) - 1] == '*') {
10835 SRate[strlen(SRate) - 1] = '\0';
10836 }
10837 strcat(SRate, ",");
10838
10839 tmp = strtok(NULL, " \n");
10840 }
10841 SRate[strlen(SRate) - 1] = '\0';
10842 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
10843 } else if (strstr(line, "DTIM") != NULL) {
10844 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
10845 } else if (strstr(line, "VHT capabilities") != NULL) {
10846 strcat(scan_array[index].ap_SupportedStandards, ",ac");
10847 strcpy(scan_array[index].ap_OperatingStandards, "ac");
10848 } else if (strstr(line, "HT capabilities") != NULL) {
10849 strcat(scan_array[index].ap_SupportedStandards, ",n");
10850 strcpy(scan_array[index].ap_OperatingStandards, "n");
10851 } else if (strstr(line, "VHT operation") != NULL) {
10852 ret = fgets(line, sizeof(line), f);
10853 sscanf(line," * channel width: %d", &vht_channel_width);
10854 if(vht_channel_width == 1) {
10855 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
10856 } else {
10857 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
10858 }
10859 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
10860 continue;
10861 } else if (strstr(line, "HT operation") != NULL) {
10862 ret = fgets(line, sizeof(line), f);
10863 sscanf(line," * secondary channel offset: %s", &buf);
10864 if (!strcmp(buf, "above")) {
10865 //40Mhz +
10866 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
10867 }
10868 else if (!strcmp(buf, "below")) {
10869 //40Mhz -
10870 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
10871 } else {
10872 //20Mhz
10873 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
10874 }
10875 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
10876 continue;
10877 } else if (strstr(line, "HE capabilities") != NULL) {
10878 strcat(scan_array[index].ap_SupportedStandards, ",ax");
10879 strcpy(scan_array[index].ap_OperatingStandards, "ax");
10880 ret = fgets(line, sizeof(line), f);
10881 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
10882 if (strstr(line, "HE40/2.4GHz") != NULL)
10883 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
10884 else
10885 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
10886 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
10887 if (strstr(line, "HE80/5GHz") != NULL) {
10888 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
10889 ret = fgets(line, sizeof(line), f);
10890 } else
10891 continue;
10892 if (strstr(line, "HE160/5GHz") != NULL)
10893 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
10894 }
10895 continue;
10896 } else if (strstr(line, "WPA") != NULL) {
10897 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
10898 } else if (strstr(line, "RSN") != NULL) {
10899 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
10900 } else if (strstr(line, "Group cipher") != NULL) {
10901 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
10902 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
10903 strcpy(scan_array[index].ap_EncryptionMode, "AES");
10904 }
10905 }
10906 ret = fgets(line, sizeof(line), f);
10907 }
10908
10909 if (!filter_BSS) {
10910 *output_array_size = index + 1;
10911 } else {
10912 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
10913 *output_array_size = index;
10914 }
10915 *neighbor_ap_array = scan_array;
10916 pclose(f);
10917 free(channels_noise_arr);
10918 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10919 return RETURN_OK;
10920}
10921
10922INT wifi_getApAssociatedDeviceStats(
10923 INT apIndex,
10924 mac_address_t *clientMacAddress,
10925 wifi_associated_dev_stats_t *associated_dev_stats,
10926 u64 *handle)
10927{
10928 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
10929 char interface_name[50] = {0};
10930 char cmd[1024] = {0};
10931 char mac_str[18] = {0};
10932 char *key = NULL;
10933 char *val = NULL;
10934 FILE *f = NULL;
10935 char *line = NULL;
10936 size_t len = 0;
10937
10938 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
10939 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
10940 return RETURN_ERR;
10941 }
10942
10943 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
10944 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
10945 if((f = popen(cmd, "r")) == NULL) {
10946 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
10947 return RETURN_ERR;
10948 }
10949
10950 while ((getline(&line, &len, f)) != -1) {
10951 key = strtok(line,":");
10952 val = strtok(NULL,":");
10953
10954 if(!strncmp(key,"rx bytes",8))
10955 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
10956 if(!strncmp(key,"tx bytes",8))
10957 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
10958 if(!strncmp(key,"rx packets",10))
10959 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
10960 if(!strncmp(key,"tx packets",10))
10961 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
10962 if(!strncmp(key,"tx retries",10))
10963 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
10964 if(!strncmp(key,"tx failed",9))
10965 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
10966 if(!strncmp(key,"rx drop misc",13))
10967 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
10968 if(!strncmp(key,"rx bitrate",10)) {
10969 val = strtok(val, " ");
10970 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
10971 }
10972 if(!strncmp(key,"tx bitrate",10)) {
10973 val = strtok(val, " ");
10974 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
10975 }
10976 }
10977 free(line);
10978 pclose(f);
10979 return RETURN_OK;
10980}
10981
10982INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
10983{
developer7e4a2a62023-04-06 19:56:03 +080010984 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010985 char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0};
10986
developer7e4a2a62023-04-06 19:56:03 +080010987 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
10988
developer72fb0bb2023-01-11 09:46:29 +080010989 if (NULL == output_string)
10990 return RETURN_ERR;
10991
10992 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10993 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080010994
10995 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 +080010996 _syscmd(cmd, buf, sizeof(buf));
10997
10998 //size of SSID name restricted to value less than 32 bytes
10999 snprintf(output_string, 32, "%s", buf);
developer7e4a2a62023-04-06 19:56:03 +080011000 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011001
11002 return RETURN_OK;
11003}
11004
11005INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
11006{
developer2edaf012023-05-24 14:24:53 +080011007 char *mac_arry_buf = NULL;
11008 INT policy = -1;
11009 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080011010
developer2edaf012023-05-24 14:24:53 +080011011 mac_arry_buf = malloc(buf_size);
11012 if (!mac_arry_buf) {
11013 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080011014 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011015 }
11016 memset(mac_arry_buf, 0, buf_size);
11017 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
11018 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
11019 goto err;
11020 }
11021 /*
11022 mtk format to get policy:
11023 "policy=1
11024 00:11:22:33:44:55
11025 00:11:22:33:44:66
11026 "
11027 */
11028 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
11029 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
11030 goto err;
11031 }
11032 if (!(policy >=0 && policy <= 2)){
11033 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
11034 goto err;
11035 }
11036 *output_filterMode = policy;
11037 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
11038 free(mac_arry_buf);
11039 mac_arry_buf = NULL;
11040 return RETURN_OK;
11041err:
11042 free(mac_arry_buf);
11043 mac_arry_buf = NULL;
11044 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
11045 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011046}
11047
developer2edaf012023-05-24 14:24:53 +080011048
developer72fb0bb2023-01-11 09:46:29 +080011049INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
11050{
11051 FILE *fp = NULL;
11052 char str[MAX_BUF_SIZE] = {0};
11053 int wificlientindex = 0 ;
11054 int count = 0;
11055 int signalstrength = 0;
11056 int arr[MACADDRESS_SIZE] = {0};
11057 unsigned char mac[MACADDRESS_SIZE] = {0};
11058 UINT wifi_count = 0;
11059 char virtual_interface_name[MAX_BUF_SIZE] = {0};
11060 char pipeCmd[MAX_CMD_SIZE] = {0};
11061
11062 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11063 *output_array_size = 0;
11064 *associated_dev_array = NULL;
11065 char interface_name[50] = {0};
11066
11067 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11068 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11069 return RETURN_ERR;
11070 }
11071
11072 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
11073 fp = popen(pipeCmd, "r");
11074 if (fp == NULL)
11075 {
11076 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11077 return RETURN_ERR;
11078 }
11079
11080 /* Read the output a line at a time - output it. */
11081 fgets(str, sizeof(str)-1, fp);
11082 wifi_count = (unsigned int) atoi ( str );
11083 *output_array_size = wifi_count;
11084 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11085 pclose(fp);
11086
11087 if(wifi_count == 0)
11088 {
11089 return RETURN_OK;
11090 }
11091 else
11092 {
11093 wifi_associated_dev2_t* temp = NULL;
11094 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
11095 *associated_dev_array = temp;
11096 if(temp == NULL)
11097 {
11098 printf("Error Statement. Insufficient memory \n");
11099 return RETURN_ERR;
11100 }
11101
11102 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11103 system(pipeCmd);
11104
11105 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11106 if(fp == NULL)
11107 {
11108 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11109 return RETURN_ERR;
11110 }
11111 fclose(fp);
11112
11113 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11114 fp = popen(pipeCmd, "r");
11115 if(fp)
11116 {
11117 for(count =0 ; count < wifi_count; count++)
11118 {
11119 fgets(str, MAX_BUF_SIZE, fp);
11120 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11121 {
11122 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11123 {
11124 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
11125
11126 }
11127 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11128 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]);
11129 }
11130 temp[count].cli_AuthenticationState = 1; //TODO
11131 temp[count].cli_Active = 1; //TODO
11132 }
11133 pclose(fp);
11134 }
11135
11136 //Updating RSSI per client
11137 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11138 fp = popen(pipeCmd, "r");
11139 if(fp)
11140 {
11141 pclose(fp);
11142 }
11143 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11144 if(fp)
11145 {
11146 for(count =0 ; count < wifi_count ;count++)
11147 {
11148 fgets(str, MAX_BUF_SIZE, fp);
11149 signalstrength = atoi(str);
11150 temp[count].cli_RSSI = signalstrength;
11151 }
11152 pclose(fp);
11153 }
11154
11155
11156 //LastDataDownlinkRate
11157 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
11158 fp = popen(pipeCmd, "r");
11159 if (fp)
11160 {
11161 pclose(fp);
11162 }
11163 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
11164 if (fp)
11165 {
11166 for (count = 0; count < wifi_count; count++)
11167 {
11168 fgets(str, MAX_BUF_SIZE, fp);
11169 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
11170 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
11171 }
11172 pclose(fp);
11173 }
11174
11175 //LastDataUplinkRate
11176 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
11177 fp = popen(pipeCmd, "r");
11178 if (fp)
11179 {
11180 pclose(fp);
11181 }
11182 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
11183 if (fp)
11184 {
11185 for (count = 0; count < wifi_count; count++)
11186 {
11187 fgets(str, MAX_BUF_SIZE, fp);
11188 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
11189 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
11190 }
11191 pclose(fp);
11192 }
11193 }
11194 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11195 return RETURN_OK;
11196
11197}
11198
11199INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
11200{
11201#if 0
11202 /*char buf[1024] = {0};
11203 sprintf(cmd, "ifconfig %s ", interface_name);
11204 _syscmd(cmd, buf, sizeof(buf));*/
11205
11206 output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters.
11207 output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters.
11208 output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface.
11209 output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface.
11210
11211 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.
11212 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].
11213 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].
11214 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].
11215 output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012].
11216 output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac.
11217
11218 output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors.
11219 output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11220 output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11221 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.
11222 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.
11223 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.
11224 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.
11225 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.
11226 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.
11227 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.
11228 output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol.
11229#endif
11230
11231 FILE *fp = NULL;
11232 char interface_name[50] = {0};
11233 char pipeCmd[128] = {0};
11234 char str[256] = {0};
11235 wifi_ssidTrafficStats2_t *out = output_struct;
11236
11237 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11238 if (!output_struct)
11239 return RETURN_ERR;
11240
11241 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
11242 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
11243 return RETURN_ERR;
11244 sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name);
11245
11246 fp = popen(pipeCmd, "r");
11247 if (fp == NULL) {
11248 fprintf(stderr, "%s: popen failed\n", __func__);
11249 return RETURN_ERR;
11250 }
11251 fgets(str, sizeof(str), fp);
11252 pclose(fp);
11253
11254 if (strlen(str) == 0) // interface not exist
11255 return RETURN_OK;
11256
11257 sscanf(str, "%*[^:]: %lu %lu %lu %lu %* %* %* %* %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
11258 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
11259
11260 memset(str, 0, sizeof(str));
11261 sprintf(pipeCmd, "tail -n1 /proc/net/netstat");
11262 fp = popen(pipeCmd, "r");
11263 if (fp == NULL) {
11264 fprintf(stderr, "%s: popen failed\n", __func__);
11265 return RETURN_ERR;
11266 }
11267 fgets(str, sizeof(str), fp);
11268
11269 sscanf(str, "%*[^:]: %* %* %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
11270 &out->ssid_BroadcastPacketsSent);
11271 pclose(fp);
11272
11273 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
11274 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
11275
11276 // Not supported
11277 output_struct->ssid_RetransCount = 0;
11278 output_struct->ssid_FailedRetransCount = 0;
11279 output_struct->ssid_RetryCount = 0;
11280 output_struct->ssid_MultipleRetryCount = 0;
11281 output_struct->ssid_ACKFailureCount = 0;
11282 output_struct->ssid_AggregatedPacketCount = 0;
11283
11284 return RETURN_OK;
11285}
11286
11287//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).
11288INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
11289{
11290 char output_val[16]={'\0'};
11291 char config_file[MAX_BUF_SIZE] = {0};
11292
11293 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11294 if (!output)
11295 return RETURN_ERR;
11296 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11297 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
11298
11299 if( strcmp(output_val,"1") == 0 )
11300 *output = TRUE;
11301 else
11302 *output = FALSE;
11303 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11304
11305 return RETURN_OK;
11306}
11307
11308INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
11309{
11310 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11311 char str[MAX_BUF_SIZE]={'\0'};
11312 char string[MAX_BUF_SIZE]={'\0'};
11313 char cmd[MAX_CMD_SIZE]={'\0'};
11314 char *ch;
11315 char config_file[MAX_BUF_SIZE] = {0};
11316 struct params params;
11317
11318 if(enable == TRUE)
11319 strcpy(string,"1");
11320 else
11321 strcpy(string,"0");
11322
11323 params.name = "ap_isolate";
11324 params.value = string;
11325
11326 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11327 wifi_hostapdWrite(config_file,&params,1);
11328 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11329
11330 return RETURN_OK;
11331}
11332
11333INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
11334{
developera1255e42023-05-13 17:45:02 +080011335 char mgmtpwr_file[32] = {0};
11336 char cmd[64] = {0};
11337 char buf[32]={0};
11338
developer72fb0bb2023-01-11 09:46:29 +080011339 if (NULL == output_dBm)
11340 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080011341 snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
11342 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
11343 _syscmd(cmd, buf, sizeof(buf));
11344 if (strlen(buf) > 0)
11345 *output_dBm = strtol(buf, NULL, 10);
11346 else
11347 *output_dBm = 23;
developer72fb0bb2023-01-11 09:46:29 +080011348 return RETURN_OK;
11349}
11350
11351INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
11352{
developera1255e42023-05-13 17:45:02 +080011353 char interface_name[16] = {0};
11354 char cmd[128]={0};
11355 char buf[128]={0};
11356 char mgmt_pwr_file[128]={0};
11357 FILE *f = NULL;
11358
11359 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11360
11361 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
11362 return RETURN_ERR;
11363 snprintf(cmd, sizeof(cmd), "mwctl dev %s set pwr mgmt_frame_pwr=%d", interface_name, dBm);
11364 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) {
11365 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
11366 return RETURN_ERR;
11367 }
11368 snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
11369 f = fopen(mgmt_pwr_file, "w");
11370 if (f == NULL) {
11371 fprintf(stderr, "%s: fopen failed\n", __func__);
11372 return RETURN_ERR;
11373 }
11374 fprintf(f, "%d", dBm);
11375 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080011376 return RETURN_OK;
11377}
11378INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
11379{
11380 return RETURN_OK;
11381}
11382INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
11383{
11384 return RETURN_OK;
11385}
11386INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
11387{
11388 return RETURN_OK;
11389}
11390INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
11391{
11392 return RETURN_OK;
11393}
11394INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
11395{
11396 char config_file[MAX_BUF_SIZE] = {0};
11397 struct params list;
11398
11399 list.name = "bss_transition";
11400 list.value = activate?"1":"0";
11401 snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
11402 wifi_hostapdWrite(config_file, &list, 1);
11403
11404 return RETURN_OK;
11405}
11406wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
11407
11408void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
11409{
11410 return;
11411}
11412
11413INT wifi_setApCsaDeauth(INT apIndex, INT mode)
11414{
11415 // TODO Implement me!
11416 return RETURN_OK;
11417}
11418
11419INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
11420{
11421 char file_name[128] = {0};
11422 char buf[128] = {0};
11423 FILE *f = NULL;
11424 int max_num_radios = 0;
11425
11426 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11427
11428 wifi_getMaxRadioNumber(&max_num_radios);
11429 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
11430 for (int index = 0; index < max_num_radios; index++) {
11431 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
11432 f = fopen(file_name, "w");
11433 if (f == NULL)
11434 return RETURN_ERR;
11435 // For mode == 0 is to disable filter, just don't write to the file.
11436 if (mode)
11437 fprintf(f, "%s", essid);
11438
11439 fclose(f);
11440 }
11441 } else { // special case, need to set AP's SSID as filter for each radio.
11442 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
11443 f = fopen(file_name, "w");
11444 if (f == NULL)
11445 return RETURN_ERR;
11446
11447 // For mode == 0 is to disable filter, just don't write to the file.
11448 if (mode)
11449 fprintf(f, "%s", essid);
11450
11451 fclose(f);
11452 }
11453
11454 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11455 return RETURN_OK;
11456}
11457
11458INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
11459{
11460 // TODO Implement me!
11461 //Apply wifi_pushRadioChannel() instantly
11462 return RETURN_ERR;
11463}
11464
11465INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
11466{
11467 // TODO Implement me!
11468 return RETURN_OK;
11469}
11470
11471#ifdef HAL_NETLINK_IMPL
11472static int tidStats_callback(struct nl_msg *msg, void *arg) {
11473 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11474 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11475 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
11476 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
11477 int rem , tid_index = 0;
11478
11479 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
11480 wifi_associated_dev_tid_entry_t *stats_entry;
11481
11482 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
11483 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
11484 };
11485 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
11486 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
11487 };
11488
11489 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11490 genlmsg_attrlen(gnlh, 0), NULL);
11491
11492
11493 if (!tb[NL80211_ATTR_STA_INFO]) {
11494 fprintf(stderr, "station stats missing!\n");
11495 return NL_SKIP;
11496 }
11497
11498 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
11499 tb[NL80211_ATTR_STA_INFO],
11500 stats_policy)) {
11501 fprintf(stderr, "failed to parse nested attributes!\n");
11502 return NL_SKIP;
11503 }
11504
developer386281b2023-05-20 15:43:13 +080011505 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
11506 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
11507 {
11508 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080011509
developer386281b2023-05-20 15:43:13 +080011510 stats_entry->tid = tid_index;
11511 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080011512
developer386281b2023-05-20 15:43:13 +080011513 if(sinfo[NL80211_STA_INFO_TID_STATS])
11514 {
11515 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
11516 printf("failed to parse nested stats attributes!");
11517 return NL_SKIP;
11518 }
developer72fb0bb2023-01-11 09:46:29 +080011519 }
developer386281b2023-05-20 15:43:13 +080011520 if(stats_info[NL80211_TID_STATS_TX_MSDU])
11521 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080011522
developer386281b2023-05-20 15:43:13 +080011523 if(tid_index < (PS_MAX_TID - 1))
11524 tid_index++;
11525 }
developer72fb0bb2023-01-11 09:46:29 +080011526 }
11527 //ToDo: sum_time_ms, ewma_time_ms
11528 return NL_SKIP;
11529}
11530#endif
11531
11532INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
11533{
11534#ifdef HAL_NETLINK_IMPL
11535 Netlink nl;
11536 char if_name[10];
11537 char interface_name[16] = {0};
11538
11539 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
11540 return RETURN_ERR;
11541
11542 snprintf(if_name, sizeof(if_name), "%s", interface_name);
11543
11544 nl.id = initSock80211(&nl);
11545
11546 if (nl.id < 0) {
11547 fprintf(stderr, "Error initializing netlink \n");
11548 return -1;
11549 }
11550
11551 struct nl_msg* msg = nlmsg_alloc();
11552
11553 if (!msg) {
11554 fprintf(stderr, "Failed to allocate netlink message.\n");
11555 nlfree(&nl);
11556 return -2;
11557 }
11558
11559 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080011560 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080011561 NL_AUTO_SEQ,
11562 nl.id,
11563 0,
11564 0,
11565 NL80211_CMD_GET_STATION,
11566 0);
11567
11568 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
11569 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
11570 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
developer8dd72532023-05-17 19:58:35 +080011571 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080011572 nl_recvmsgs(nl.socket, nl.cb);
11573 nlmsg_free(msg);
11574 nlfree(&nl);
11575 return RETURN_OK;
11576#else
11577//iw implementation
11578#define TID_STATS_FILE "/tmp/tid_stats_file.txt"
11579#define TOTAL_MAX_LINES 50
11580
11581 char buf[256] = {'\0'}; /* or other suitable maximum line size */
11582 char if_name[32] = {0};
11583 FILE *fp=NULL;
11584 char pipeCmd[1024]= {'\0'};
11585 int lines,tid_index=0;
11586 char mac_addr[20] = {'\0'};
11587
11588 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
11589 return RETURN_ERR;
11590
11591 wifi_associated_dev_tid_entry_t *stats_entry;
11592
11593 strcpy(mac_addr,clientMacAddress);
11594
11595 snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name);
11596 fp= popen(pipeCmd,"r");
11597 if(fp == NULL)
11598 {
11599 perror("popen for station dump failed\n");
11600 return RETURN_ERR;
11601 }
11602 pclose(fp);
11603
11604 snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1");
11605 fp=popen(pipeCmd,"r");
11606 if(fp == NULL)
11607 {
11608 perror("popen for grep station failed\n");
11609 return RETURN_ERR;
11610 }
11611 else if(fgets(buf,sizeof(buf),fp) != NULL)
11612 lines=atoi(buf);
11613 else
11614 {
11615 pclose(fp);
11616 fprintf(stderr,"No devices are connected \n");
11617 return RETURN_ERR;
11618 }
11619 pclose(fp);
11620
11621 if(lines == 1)
11622 lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output
11623
11624 for(tid_index=0; tid_index<PS_MAX_TID; tid_index++)
11625 {
11626 stats_entry = &tid_stats->tid_array[tid_index];
11627 stats_entry->tid = tid_index;
11628
11629 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);
11630
11631 fp=popen(pipeCmd,"r");
11632 if(fp ==NULL)
11633 {
11634 perror("Failed to read from tid file \n");
11635 return RETURN_ERR;
11636 }
11637 else if(fgets(buf,sizeof(buf),fp) != NULL)
11638 stats_entry->num_msdus = atol(buf);
11639
11640 pclose(fp);
11641 stats_entry->ac = _tid_ac_index_get[tid_index];
11642// TODO:
11643// ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus
11644// ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval
11645 }
11646 return RETURN_OK;
11647#endif
11648}
11649
11650
11651INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
11652{
11653 char interface_name[16] = {0};
11654 char cmd[128]={0};
11655 char buf[128]={0};
11656 int freq = 0;
11657
11658 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11659
11660 // full mode is used to scan all channels.
11661 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
11662 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
11663 ieee80211_channel_to_frequency(chan_list[0], &freq);
11664
11665 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11666 return RETURN_ERR;
11667
11668 if (freq)
11669 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
11670 else
11671 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
11672
11673 _syscmd(cmd, buf, sizeof(buf));
11674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11675
11676 return RETURN_OK;
11677}
11678
11679
11680INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
11681{
11682 // TODO Implement me!
11683 return RETURN_ERR;
11684}
11685
11686INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
11687{
11688 // TODO Implement me!
11689 return RETURN_ERR;
11690}
11691
11692INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
11693{
11694 // TODO Implement me!
11695 return RETURN_ERR;
11696}
11697
11698INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
11699{
11700 // TODO Implement me!
11701 return RETURN_ERR;
11702}
11703
11704INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
11705{
11706 // TODO Implement me!
11707 return RETURN_ERR;
11708}
11709
11710INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
11711{
11712 // TODO Implement me!
11713 return RETURN_ERR;
11714}
11715
11716INT wifi_steering_eventUnregister(void)
11717{
11718 // TODO Implement me!
11719 return RETURN_ERR;
11720}
11721
11722INT wifi_delApAclDevices(INT apIndex)
11723{
developer7e4a2a62023-04-06 19:56:03 +080011724 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080011725 struct unl unl_ins;
11726 int if_idx = 0, ret = 0;
11727 struct nl_msg *msg = NULL;
11728 struct nlattr * msg_data = NULL;
11729 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080011730
developer7e4a2a62023-04-06 19:56:03 +080011731 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
11732 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011733 if_idx = if_nametoindex(inf_name);
11734 if (!if_idx) {
11735 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
11736 return RETURN_ERR;
11737 }
11738 /*init mtk nl80211 vendor cmd*/
11739 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
11740 param.if_type = NL80211_ATTR_IFINDEX;
11741 param.if_idx = if_idx;
11742 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11743 if (ret) {
11744 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11745 return RETURN_ERR;
11746 }
11747 /*add mtk vendor cmd data*/
11748 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
11749 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11750 nlmsg_free(msg);
11751 goto err;
11752 }
11753 /*send mtk nl80211 vendor msg*/
11754 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11755 if (ret) {
11756 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
11757 goto err;
11758 }
11759 /*deinit mtk nl80211 vendor msg*/
11760 mtk_nl80211_deint(&unl_ins);
11761 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
11762 return RETURN_OK;
11763err:
11764 mtk_nl80211_deint(&unl_ins);
11765 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11766 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011767
11768 return RETURN_OK;
11769}
11770
11771#ifdef HAL_NETLINK_IMPL
11772static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
11773 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11774 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11775 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
11776 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
11777 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
11778 char mac_addr[20],dev[20];
11779
11780 nla_parse(tb,
11781 NL80211_ATTR_MAX,
11782 genlmsg_attrdata(gnlh, 0),
11783 genlmsg_attrlen(gnlh, 0),
11784 NULL);
11785
11786 if(!tb[NL80211_ATTR_STA_INFO]) {
11787 fprintf(stderr, "sta stats missing!\n");
11788 return NL_SKIP;
11789 }
11790
11791 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
11792 fprintf(stderr, "failed to parse nested attributes!\n");
11793 return NL_SKIP;
11794 }
11795 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
11796
11797 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
11798
developer386281b2023-05-20 15:43:13 +080011799 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
11800 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
11801 fprintf(stderr, "failed to parse nested rate attributes!");
11802 return NL_SKIP;
11803 }
developer72fb0bb2023-01-11 09:46:29 +080011804 }
11805
11806 if(sinfo[NL80211_STA_INFO_TID_STATS])
11807 {
11808 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
11809 printf("failed to parse nested stats attributes!");
11810 return NL_SKIP;
11811 }
11812 }
developer5a1194f2023-05-24 16:00:03 +080011813 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080011814
developereb1ea832023-05-24 14:46:27 +080011815 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
11816 {
11817 printf("Type is VHT\n");
11818 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
11819 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
developer72fb0bb2023-01-11 09:46:29 +080011820
developereb1ea832023-05-24 14:46:27 +080011821 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
11822 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
11823 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
11824 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
11825 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
11826 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
11827 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
11828 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
11829 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
11830 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
11831 }
11832 else
11833 {
11834 printf(" OFDM or CCK \n");
11835 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
11836 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
11837 }
11838 }
developer72fb0bb2023-01-11 09:46:29 +080011839
11840 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
11841 if(rinfo[NL80211_RATE_INFO_MCS])
11842 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
11843 }
11844 if(sinfo[NL80211_STA_INFO_RX_BYTES64])
11845 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
11846 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
11847 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
11848
11849 if(stats_info[NL80211_TID_STATS_RX_MSDU])
11850 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
11851
11852 if (sinfo[NL80211_STA_INFO_SIGNAL])
11853 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
11854 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
11855 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
11856 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
11857 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
11858 //rssi_array need to be filled
11859 return NL_SKIP;
11860}
11861#endif
11862
11863INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
11864{
11865#ifdef HAL_NETLINK_IMPL
11866 Netlink nl;
11867 char if_name[32];
11868 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
11869 return RETURN_ERR;
11870
11871 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
11872
11873 if (*output_array_size <= 0)
11874 return RETURN_OK;
11875
11876 nl.id = initSock80211(&nl);
11877
11878 if (nl.id < 0) {
11879 fprintf(stderr, "Error initializing netlink \n");
11880 return 0;
11881 }
11882
11883 struct nl_msg* msg = nlmsg_alloc();
11884
11885 if (!msg) {
11886 fprintf(stderr, "Failed to allocate netlink message.\n");
11887 nlfree(&nl);
11888 return 0;
11889 }
11890
11891 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080011892 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080011893 NL_AUTO_SEQ,
11894 nl.id,
11895 0,
11896 0,
11897 NL80211_CMD_GET_STATION,
11898 0);
11899
11900 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
11901 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
11902 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080011903 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080011904 nl_recvmsgs(nl.socket, nl.cb);
11905 nlmsg_free(msg);
11906 nlfree(&nl);
11907 return RETURN_OK;
11908#else
11909 //TODO Implement me
11910 return RETURN_OK;
11911#endif
11912}
11913
11914#ifdef HAL_NETLINK_IMPL
11915static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
11916 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11917 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11918 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
11919 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
11920 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
11921 char mac_addr[20],dev[20];
11922
11923 nla_parse(tb,
11924 NL80211_ATTR_MAX,
11925 genlmsg_attrdata(gnlh, 0),
11926 genlmsg_attrlen(gnlh, 0),
11927 NULL);
11928
11929 if(!tb[NL80211_ATTR_STA_INFO]) {
11930 fprintf(stderr, "sta stats missing!\n");
11931 return NL_SKIP;
11932 }
11933
11934 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
11935 fprintf(stderr, "failed to parse nested attributes!\n");
11936 return NL_SKIP;
11937 }
11938
11939 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
11940
11941 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
11942
developer386281b2023-05-20 15:43:13 +080011943 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
11944 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
11945 fprintf(stderr, "failed to parse nested rate attributes!");
11946 return NL_SKIP;
11947 }
developer72fb0bb2023-01-11 09:46:29 +080011948 }
11949
11950 if(sinfo[NL80211_STA_INFO_TID_STATS])
11951 {
11952 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
11953 printf("failed to parse nested stats attributes!");
11954 return NL_SKIP;
11955 }
11956 }
developera6beea42023-05-24 16:44:05 +080011957 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developereb1ea832023-05-24 14:46:27 +080011958 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
11959 {
11960 printf("Type is VHT\n");
11961 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
11962 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
developer72fb0bb2023-01-11 09:46:29 +080011963
developereb1ea832023-05-24 14:46:27 +080011964 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
11965 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
11966 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
11967 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
11968 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
11969 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
11970 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
11971 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
11972 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
11973 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
11974 }
11975 else
11976 {
11977 printf(" OFDM or CCK \n");
developer72fb0bb2023-01-11 09:46:29 +080011978 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
developereb1ea832023-05-24 14:46:27 +080011979 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
11980 }
developer72fb0bb2023-01-11 09:46:29 +080011981 }
11982
11983 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
11984 if(rinfo[NL80211_RATE_INFO_MCS])
11985 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
11986 }
11987
11988 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
11989 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
11990 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
11991 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
11992
11993 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
11994 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
11995 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
11996
11997 if(stats_info[NL80211_TID_STATS_TX_MSDU])
11998 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
11999
12000 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
12001 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
12002
12003 if(sinfo[NL80211_STA_INFO_TX_FAILED])
12004 ((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]);
12005
12006 return NL_SKIP;
12007}
12008#endif
12009
12010INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12011{
12012#ifdef HAL_NETLINK_IMPL
12013 Netlink nl;
12014 char if_name[10];
12015 char interface_name[16] = {0};
12016 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12017 return RETURN_ERR;
12018
12019 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
12020
12021 if (*output_array_size <= 0)
12022 return RETURN_OK;
12023
12024 snprintf(if_name, sizeof(if_name), "%s", interface_name);
12025
12026 nl.id = initSock80211(&nl);
12027
12028 if(nl.id < 0) {
12029 fprintf(stderr, "Error initializing netlink \n");
12030 return 0;
12031 }
12032
12033 struct nl_msg* msg = nlmsg_alloc();
12034
12035 if(!msg) {
12036 fprintf(stderr, "Failed to allocate netlink message.\n");
12037 nlfree(&nl);
12038 return 0;
12039 }
12040
12041 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012042 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012043 NL_AUTO_SEQ,
12044 nl.id,
12045 0,
12046 0,
12047 NL80211_CMD_GET_STATION,
12048 0);
12049
12050 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12051 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12052 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012053 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012054 nl_recvmsgs(nl.socket, nl.cb);
12055 nlmsg_free(msg);
12056 nlfree(&nl);
12057 return RETURN_OK;
12058#else
12059 //TODO Implement me
12060 return RETURN_OK;
12061#endif
12062}
12063
12064INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
12065{
12066 // TODO Implement me!
12067 char buf[MAX_BUF_SIZE] = {0};
12068 char config_file[MAX_BUF_SIZE] = {0};
12069
12070 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12071 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
12072 *activate = (strncmp("1",buf,1) == 0);
12073
12074 return RETURN_OK;
12075}
12076
12077INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
12078{
12079 char config_file[MAX_BUF_SIZE] = {0};
12080 struct params list;
12081
12082 list.name = "rrm_neighbor_report";
12083 list.value = activate?"1":"0";
12084 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12085 wifi_hostapdWrite(config_file, &list, 1);
12086
12087 return RETURN_OK;
12088}
12089
12090INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
12091{
12092 char buf[32] = {0};
12093 char config_file[MAX_BUF_SIZE] = {0};
12094
12095 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12096 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
12097 *activate = (strncmp("1",buf,1) == 0);
12098
12099 return RETURN_OK;
12100}
12101#undef HAL_NETLINK_IMPL
12102#ifdef HAL_NETLINK_IMPL
12103static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
12104 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12105 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12106 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
12107 char dev[20];
12108 int freq =0 ;
12109 static int i=0;
12110
12111 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
12112
12113 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
12114 };
12115
12116 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
12117
12118 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12119
12120 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
12121 fprintf(stderr, "survey data missing!\n");
12122 return NL_SKIP;
12123 }
12124
12125 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
12126 {
12127 fprintf(stderr, "failed to parse nested attributes!\n");
12128 return NL_SKIP;
12129 }
12130
12131
12132 if(out[0].array_size == 1 )
12133 {
12134 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
12135 {
12136 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12137 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12138 out[0].ch_number = ieee80211_frequency_to_channel(freq);
12139
12140 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12141 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12142 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12143 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12144 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12145 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12146 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12147 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12148 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12149 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12150 if (sinfo[NL80211_SURVEY_INFO_TIME])
12151 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12152 return NL_STOP;
12153 }
12154 }
12155 else
12156 {
12157 if ( i <= out[0].array_size )
12158 {
12159 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12160 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12161 out[i].ch_number = ieee80211_frequency_to_channel(freq);
12162
12163 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12164 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12165 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12166 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12167 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12168 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12169 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12170 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12171 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12172 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12173 if (sinfo[NL80211_SURVEY_INFO_TIME])
12174 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12175 }
12176 }
12177
12178 i++;
12179 return NL_SKIP;
12180}
12181#endif
12182
12183static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
12184{
12185 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
12186 FILE *fp;
12187
12188 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
12189 {
12190 printf("Creating Frequency-Channel Map\n");
12191 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
12192 }
12193 snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
12194 if((fp = popen(command, "r")))
12195 {
12196 fgets(output, sizeof(output), fp);
12197 *freqMHz = atoi(output);
12198 pclose(fp);
12199 }
12200
12201 return 0;
12202}
12203
12204static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz)
12205{
12206 int freqMHz = -1;
12207 char cmd[MAX_CMD_SIZE] = {'\0'};
12208 char interface_name[16] = {0};
12209
12210 ieee80211_channel_to_frequency(channel, &freqMHz);
12211 if (freqMHz == -1) {
12212 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
12213 return -1;
12214 }
12215
12216 wifi_GetInterfaceName(radioIndex, interface_name);
12217 if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) {
12218 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
12219 radioIndex, freqMHz);
12220 return -1;
12221 }
12222
12223 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
12224 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
12225 return -1;
12226 }
12227
12228 return 0;
12229}
12230
12231static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
12232{
12233 const char *ptr = buf;
12234 char *key = NULL;
12235 char *val = NULL;
12236 char line[256] = { '\0' };
12237
12238 while (ptr = get_line_from_str_buf(ptr, line)) {
12239 if (strstr(line, "Frequency")) continue;
12240
12241 key = strtok(line, ":");
12242 val = strtok(NULL, " ");
12243 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
12244
12245 if (!strcmp(key, "noise")) {
12246 sscanf(val, "%d", &stats->ch_noise);
12247 if (stats->ch_noise == 0) {
12248 // Workaround for missing noise information.
12249 // Assume -95 for 2.4G and -103 for 5G
12250 if (radioIndex == 0) stats->ch_noise = -95;
12251 if (radioIndex == 1) stats->ch_noise = -103;
12252 }
12253 }
12254 else if (!strcmp(key, "channel active time")) {
12255 sscanf(val, "%llu", &stats->ch_utilization_total);
12256 }
12257 else if (!strcmp(key, "channel busy time")) {
12258 sscanf(val, "%llu", &stats->ch_utilization_busy);
12259 }
12260 else if (!strcmp(key, "channel receive time")) {
12261 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
12262 }
12263 else if (!strcmp(key, "channel transmit time")) {
12264 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
12265 }
12266 };
12267
12268 return 0;
12269}
12270
12271INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
12272{
12273 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12274#ifdef HAL_NETLINK_IMPL
12275 Netlink nl;
12276 wifi_channelStats_t_loc local[array_size];
12277 char if_name[32];
12278
12279 local[0].array_size = array_size;
12280
12281 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12282 return RETURN_ERR;
12283
12284 nl.id = initSock80211(&nl);
12285
12286 if (nl.id < 0) {
12287 fprintf(stderr, "Error initializing netlink \n");
12288 return -1;
12289 }
12290
12291 struct nl_msg* msg = nlmsg_alloc();
12292
12293 if (!msg) {
12294 fprintf(stderr, "Failed to allocate netlink message.\n");
12295 nlfree(&nl);
12296 return -2;
12297 }
12298
12299 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012300 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012301 NL_AUTO_SEQ,
12302 nl.id,
12303 0,
12304 NLM_F_DUMP,
12305 NL80211_CMD_GET_SURVEY,
12306 0);
12307
12308 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +080012309 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012310 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
12311 nl_recvmsgs(nl.socket, nl.cb);
12312 nlmsg_free(msg);
12313 nlfree(&nl);
12314 //Copying the Values
12315 for(int i=0;i<array_size;i++)
12316 {
12317 input_output_channelStats_array[i].ch_number = local[i].ch_number;
12318 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
12319 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
12320 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
12321 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
12322 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
12323 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
12324 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
12325 }
12326#else
12327 ULONG channel = 0;
12328 int i;
12329 int number_of_channels = array_size;
12330 char buf[512];
12331 INT ret;
12332 wifi_channelStats_t tmp_stats;
12333
12334 if (number_of_channels == 0) {
12335 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
12336 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
12337 return RETURN_ERR;
12338 }
12339 number_of_channels = 1;
12340 input_output_channelStats_array[0].ch_number = channel;
12341 }
12342
12343 for (i = 0; i < number_of_channels; i++) {
12344
12345 input_output_channelStats_array[i].ch_noise = 0;
12346 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
12347 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
12348 input_output_channelStats_array[i].ch_utilization_busy = 0;
12349 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
12350 input_output_channelStats_array[i].ch_utilization_total = 0;
12351
12352 memset(buf, 0, sizeof(buf));
12353 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
12354 return RETURN_ERR;
12355 }
12356 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
12357 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
12358 return RETURN_ERR;
12359 }
12360
12361 // XXX: fake missing 'self' counter which is not available in iw survey output
12362 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
12363 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
12364
12365 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
12366 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
12367 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
12368 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
12369 input_output_channelStats_array[i].ch_utilization_total *= 1000;
12370
12371 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",
12372 __func__,
12373 input_output_channelStats_array[i].ch_number,
12374 input_output_channelStats_array[i].ch_noise,
12375 input_output_channelStats_array[i].ch_utilization_total,
12376 input_output_channelStats_array[i].ch_utilization_busy,
12377 input_output_channelStats_array[i].ch_utilization_busy_rx,
12378 input_output_channelStats_array[i].ch_utilization_busy_tx,
12379 input_output_channelStats_array[i].ch_utilization_busy_self,
12380 input_output_channelStats_array[i].ch_utilization_busy_ext);
12381 }
12382#endif
12383 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12384 return RETURN_OK;
12385}
12386#define HAL_NETLINK_IMPL
12387
12388/* Hostapd events */
12389
12390#ifndef container_of
12391#define offset_of(st, m) ((size_t)&(((st *)0)->m))
12392#define container_of(ptr, type, member) \
12393 ((type *)((char *)ptr - offset_of(type, member)))
12394#endif /* container_of */
12395
12396struct ctrl {
12397 char sockpath[128];
12398 char sockdir[128];
12399 char bss[IFNAMSIZ];
12400 char reply[4096];
12401 int ssid_index;
12402 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
12403 void (*overrun)(struct ctrl *ctrl);
12404 struct wpa_ctrl *wpa;
12405 unsigned int ovfl;
12406 size_t reply_len;
12407 int initialized;
12408 ev_timer retry;
12409 ev_timer watchdog;
12410 ev_stat stat;
12411 ev_io io;
12412};
12413static wifi_newApAssociatedDevice_callback clients_connect_cb;
12414static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
12415static struct ctrl wpa_ctrl[MAX_APS];
12416static int initialized;
12417
12418static unsigned int ctrl_get_drops(struct ctrl *ctrl)
12419{
12420 char cbuf[256] = {};
12421 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
12422 struct cmsghdr *cmsg;
12423 unsigned int ovfl = ctrl->ovfl;
12424 unsigned int drop;
12425
12426 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
12427 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
12428 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
12429 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
12430
12431 drop = ovfl - ctrl->ovfl;
12432 ctrl->ovfl = ovfl;
12433
12434 return drop;
12435}
12436
12437static void ctrl_close(struct ctrl *ctrl)
12438{
12439 if (ctrl->io.cb)
12440 ev_io_stop(EV_DEFAULT_ &ctrl->io);
12441 if (ctrl->retry.cb)
12442 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
12443 if (!ctrl->wpa)
12444 return;
12445
12446 wpa_ctrl_detach(ctrl->wpa);
12447 wpa_ctrl_close(ctrl->wpa);
12448 ctrl->wpa = NULL;
12449 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
12450}
12451
12452static void ctrl_process(struct ctrl *ctrl)
12453{
12454 const char *str;
12455 int drops;
12456 int level;
12457 int err;
12458
12459 /* Example events:
12460 *
12461 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
12462 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
12463 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
12464 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
12465 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
12466 */
12467 if (!(str = index(ctrl->reply, '>')))
12468 return;
12469 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
12470 return;
12471
12472 str++;
12473
12474 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
12475 if (!(str = index(ctrl->reply, ' ')))
12476 return;
12477 wifi_associated_dev_t sta;
12478 memset(&sta, 0, sizeof(sta));
12479
12480 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
12481 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
12482 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
12483
12484 sta.cli_Active=true;
12485
12486 (clients_connect_cb)(ctrl->ssid_index, &sta);
12487 goto handled;
12488 }
12489
12490 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
12491 if (!(str = index(ctrl->reply, ' ')))
12492 return;
12493
12494 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
12495 goto handled;
12496 }
12497
12498 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
12499 printf("CTRL_WPA: handle TERMINATING event\n");
12500 goto retry;
12501 }
12502
12503 if (strncmp("AP-DISABLED", str, 11) == 0) {
12504 printf("CTRL_WPA: handle AP-DISABLED\n");
12505 goto retry;
12506 }
12507
12508 printf("Event not supported!!\n");
12509
12510handled:
12511
12512 if ((drops = ctrl_get_drops(ctrl))) {
12513 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
12514 if (ctrl->overrun)
12515 ctrl->overrun(ctrl);
12516 }
12517
12518 return;
12519
12520retry:
12521 printf("WPA_CTRL: closing\n");
12522 ctrl_close(ctrl);
12523 printf("WPA_CTRL: retrying from ctrl prcoess\n");
12524 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
12525}
12526
12527static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
12528{
12529 struct ctrl *ctrl = container_of(io, struct ctrl, io);
12530 int err;
12531
12532 memset(ctrl->reply, 0, sizeof(ctrl->reply));
12533 ctrl->reply_len = sizeof(ctrl->reply) - 1;
12534 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
12535 ctrl->reply[ctrl->reply_len] = 0;
12536 if (err < 0) {
12537 if (errno == EAGAIN || errno == EWOULDBLOCK)
12538 return;
12539 ctrl_close(ctrl);
12540 ev_timer_again(EV_A_ &ctrl->retry);
12541 return;
12542 }
12543
12544 ctrl_process(ctrl);
12545}
12546
12547static int ctrl_open(struct ctrl *ctrl)
12548{
12549 int fd;
12550
12551 if (ctrl->wpa)
12552 return 0;
12553
12554 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
12555 if (!ctrl->wpa)
12556 goto err;
12557
12558 if (wpa_ctrl_attach(ctrl->wpa) < 0)
12559 goto err_close;
12560
12561 fd = wpa_ctrl_get_fd(ctrl->wpa);
12562 if (fd < 0)
12563 goto err_detach;
12564
12565 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
12566 goto err_detach;
12567
12568 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
12569 ev_io_start(EV_DEFAULT_ &ctrl->io);
12570
12571 return 0;
12572
12573err_detach:
12574 wpa_ctrl_detach(ctrl->wpa);
12575err_close:
12576 wpa_ctrl_close(ctrl->wpa);
12577err:
12578 ctrl->wpa = NULL;
12579 return -1;
12580}
12581
12582static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
12583{
12584 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
12585
12586 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
12587 ctrl_open(ctrl);
12588}
12589
12590static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
12591{
12592 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
12593
12594 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
12595 if (ctrl_open(ctrl) == 0) {
12596 printf("WPA_CTRL: retry successful\n");
12597 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
12598 }
12599}
12600
12601int ctrl_enable(struct ctrl *ctrl)
12602{
12603 if (ctrl->wpa)
12604 return 0;
12605
12606 if (!ctrl->stat.cb) {
12607 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
12608 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
12609 }
12610
12611 if (!ctrl->retry.cb) {
12612 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
12613 }
12614
12615 return ctrl_open(ctrl);
12616}
12617
12618static void
12619ctrl_msg_cb(char *buf, size_t len)
12620{
12621 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
12622
12623 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
12624 ctrl_process(ctrl);
12625}
12626
12627static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
12628{
12629 int err;
12630
12631 if (!ctrl->wpa)
12632 return -1;
12633 if (*reply_len < 2)
12634 return -1;
12635
12636 (*reply_len)--;
12637 ctrl->reply_len = sizeof(ctrl->reply);
12638 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
12639 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
12640 if (err < 0)
12641 return err;
12642
12643 if (ctrl->reply_len > *reply_len)
12644 ctrl->reply_len = *reply_len;
12645
12646 *reply_len = ctrl->reply_len;
12647 memcpy(reply, ctrl->reply, *reply_len);
12648 reply[*reply_len - 1] = 0;
12649 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
12650 return 0;
12651}
12652
12653static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
12654{
12655 const char *pong = "PONG";
12656 const char *ping = "PING";
12657 char reply[1024];
12658 size_t len = sizeof(reply);
12659 int err;
12660 ULONG s, snum;
12661 INT ret;
12662 BOOL status;
12663
12664 printf("WPA_CTRL: watchdog cb\n");
12665
12666 ret = wifi_getSSIDNumberOfEntries(&snum);
12667 if (ret != RETURN_OK) {
12668 printf("%s: failed to get SSID count", __func__);
12669 return;
12670 }
12671
12672 if (snum > MAX_APS) {
12673 printf("more ssid than supported! %lu\n", snum);
12674 return;
12675 }
12676
12677 for (s = 0; s < snum; s++) {
12678 if (wifi_getApEnable(s, &status) != RETURN_OK) {
12679 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
12680 continue;
12681 }
12682 if (status == false) continue;
12683
12684 memset(reply, 0, sizeof(reply));
12685 len = sizeof(reply);
12686 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
12687 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
12688 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
12689 continue;
12690
12691 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
12692 ctrl_close(&wpa_ctrl[s]);
12693 printf("WPA_CTRL: ev_timer_again %lu\n", s);
12694 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
12695 }
12696}
12697
12698static int init_wpa()
12699{
12700 int ret = 0, i = 0;
12701 ULONG s, snum;
12702
12703 ret = wifi_getSSIDNumberOfEntries(&snum);
12704 if (ret != RETURN_OK) {
12705 printf("%s: failed to get SSID count", __func__);
12706 return RETURN_ERR;
12707 }
12708
12709 if (snum > MAX_APS) {
12710 printf("more ssid than supported! %lu\n", snum);
12711 return RETURN_ERR;
12712 }
12713
12714 for (s = 0; s < snum; s++) {
12715 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
12716 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
12717 wpa_ctrl[s].ssid_index = s;
12718 ctrl_enable(&wpa_ctrl[s]);
12719 }
12720
12721 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
12722 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
12723
12724 initialized = 1;
12725 printf("WPA_CTRL: initialized\n");
12726
12727 return RETURN_OK;
12728}
12729
12730void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
12731{
12732 clients_connect_cb = callback_proc;
12733 if (!initialized)
12734 init_wpa();
12735}
12736
12737void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
12738{
12739 clients_disconnect_cb = callback_proc;
12740 if (!initialized)
12741 init_wpa();
12742}
12743
12744INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
12745{
12746 // TODO Implement me!
12747 return RETURN_ERR;
12748}
12749
12750INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
12751{
12752 // TODO Implement me!
12753 return RETURN_ERR;
12754}
12755
12756INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
12757{
12758 int i;
developerd1824452023-05-18 12:30:04 +080012759 int phyId = -1;
12760 char cmd[256] = {0};
12761 char channel_numbers_buf[256] = {0};
12762 char dfs_state_buf[256] = {0};
12763 char line[256] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012764 const char *ptr;
developerd1824452023-05-18 12:30:04 +080012765 BOOL dfs_enable = false;
developer72fb0bb2023-01-11 09:46:29 +080012766
developerd1824452023-05-18 12:30:04 +080012767 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080012768
developerd1824452023-05-18 12:30:04 +080012769 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
12770 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080012771
developerd1824452023-05-18 12:30:04 +080012772 snprintf(cmd, sizeof (cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v '%sno IR\\|5340\\|5480' | awk '{print $4}' | tr -d '[]'", phyId, dfs_enable?"":"radar\\|");
developer72fb0bb2023-01-11 09:46:29 +080012773
developerd1824452023-05-18 12:30:04 +080012774 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
12775 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
12776 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012777 }
12778
developerd1824452023-05-18 12:30:04 +080012779 ptr = channel_numbers_buf;
12780 i = 0;
12781 while (ptr = get_line_from_str_buf(ptr, line)) {
12782 if (i >= outputMapSize) {
12783 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
12784 return RETURN_ERR;
12785 }
12786 sscanf(line, "%d", &outputMap[i].ch_number);
12787
12788 memset(cmd, 0, sizeof(cmd));
12789 // Below command should fetch string for DFS state (usable, available or unavailable)
12790 // Example line: "DFS state: usable (for 78930 sec)"
12791 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) {
12792 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
developer72fb0bb2023-01-11 09:46:29 +080012793 return RETURN_ERR;
12794 }
12795
developerd1824452023-05-18 12:30:04 +080012796 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
12797 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
developer72fb0bb2023-01-11 09:46:29 +080012798 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
12799 return RETURN_ERR;
12800 }
12801
developerd1824452023-05-18 12:30:04 +080012802 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080012803
developerd1824452023-05-18 12:30:04 +080012804 if (!strcmp(dfs_state_buf, "usable")) {
12805 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
12806 } else if (!strcmp(dfs_state_buf, "available")) {
12807 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
12808 } else if (!strcmp(dfs_state_buf, "unavailable")) {
12809 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
12810 } else {
12811 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
developer72fb0bb2023-01-11 09:46:29 +080012812 }
developerd1824452023-05-18 12:30:04 +080012813 i++;
developer59fda4f2023-05-16 15:47:38 +080012814 }
developer40ba1762023-05-13 11:03:49 +080012815
developerd1824452023-05-18 12:30:04 +080012816 return RETURN_OK;
12817
developer72fb0bb2023-01-11 09:46:29 +080012818 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
12819 return RETURN_ERR;
12820}
12821
12822INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
12823{
12824 // TODO Implement me!
12825 return RETURN_ERR;
12826}
12827
12828INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
12829{
12830 return RETURN_OK;
12831}
12832
12833INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
12834{
12835 // TODO Implement me!
12836 return RETURN_ERR;
12837}
12838
12839INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
12840{
12841 // TODO API refrence Implementaion is present on RPI hal
12842 return RETURN_ERR;
12843}
12844
12845INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
12846{
developera1255e42023-05-13 17:45:02 +080012847/*
developer72fb0bb2023-01-11 09:46:29 +080012848 char interface_name[16] = {0};
12849 char cmd[128]={'\0'};
12850 char buf[128]={'\0'};
12851 char *support;
12852 int maximum_tx = 0, current_tx = 0;
developera1255e42023-05-13 17:45:02 +080012853*/ ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080012854
12855 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12856 if(txpwr_pcntg == NULL)
12857 return RETURN_ERR;
12858
developera1255e42023-05-13 17:45:02 +080012859 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
12860 *txpwr_pcntg = pwr_percentage;
12861/* if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +080012862 return RETURN_ERR;
12863
12864 // Get the maximum tx power of the device
12865 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
12866 _syscmd(cmd, buf, sizeof(buf));
12867 maximum_tx = strtol(buf, NULL, 10);
12868
12869 // Get the current tx power
12870 memset(cmd, 0, sizeof(cmd));
12871 memset(buf, 0, sizeof(buf));
12872 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
12873 _syscmd(cmd, buf, sizeof(buf));
12874 current_tx = strtol(buf, NULL, 10);
12875
12876 // Get the power supported list and find the current power percentage in supported list
12877 memset(buf, 0, sizeof(buf));
12878 wifi_getRadioTransmitPowerSupported(apIndex, buf);
12879 support = strtok(buf, ",");
12880 while(true)
12881 {
12882 if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal.
12883 *txpwr_pcntg = 100;
12884 wifi_dbg_printf("current power is not in supported list\n");
12885 return RETURN_OK;
12886 }
12887 int tmp = maximum_tx*strtol(support, NULL, 10)/100;
12888 if (tmp == current_tx) {
12889 *txpwr_pcntg = strtol(support, NULL, 10);
12890 break;
12891 }
12892 support = strtok(NULL, ",");
12893 }
developera1255e42023-05-13 17:45:02 +080012894*/
developer72fb0bb2023-01-11 09:46:29 +080012895 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12896 return RETURN_OK;
12897}
12898
12899INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
12900{
12901 // TODO precac feature.
developerd1824452023-05-18 12:30:04 +080012902 struct params params[2] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012903 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080012904 BOOL dfs_enable = false;
12905 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080012906
12907 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerd1824452023-05-18 12:30:04 +080012908 band = wifi_index_to_band(radioIndex);
12909 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080012910
developerd1824452023-05-18 12:30:04 +080012911 if (dfs_enable == false) {
12912 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
12913 return RETURN_ERR;
12914 }
12915 params[0].name = "DfsZeroWaitDefault";
12916 params[0].value = enable?"1":"0";
12917 params[1].name = "DfsDedicatedZeroWait";
12918 params[1].value = enable?"1":"0";
12919 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
12920 wifi_datfileWrite(config_file, params, 2);
developerc0772e62023-05-18 15:10:48 +080012921 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080012922 /* TODO precac feature */
12923
12924 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12925 return RETURN_OK;
12926}
12927
12928INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
12929{
12930 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080012931 char buf1[32] = {0};
12932 char buf2[32] = {0};
12933 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080012934
12935 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12936 if (NULL == enable || NULL == precac)
12937 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +080012938 band = wifi_index_to_band(radioIndex);
12939 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
12940 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
12941 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
12942 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
developer72fb0bb2023-01-11 09:46:29 +080012943 *enable = true;
12944 else
12945 *enable = false;
12946
12947 /* TODO precac feature */
12948
12949 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12950 return RETURN_OK;
12951}
12952
12953INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
12954{
12955 *supported = TRUE;
12956 return RETURN_OK;
12957}
12958
12959INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
12960{
developera1255e42023-05-13 17:45:02 +080012961 UCHAR dat_file[64] = {0};
12962 wifi_band band = band_invalid;
12963 char cmd[128] = {0};
12964 char buf[256] = {0};
12965 char ofdmabuf[32] = {'\0'};
12966 char mimobuf[32] = {'\0'};
12967 char new_ofdmabuf[32] = {'\0'};
12968 char new_mimobuf[32] = {'\0'};
12969 struct params params[2];
12970 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
12971 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
12972 UCHAR bss_cnt = 0;
12973 UCHAR val_cnt = 0;
12974 char *token = NULL;
developer72fb0bb2023-01-11 09:46:29 +080012975
developera1255e42023-05-13 17:45:02 +080012976 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12977 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
12978 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
12979 printf("%s:mu_type input Error", __func__);
12980 return RETURN_ERR;
12981 }
12982 band = wifi_index_to_band(radio_index);
12983 if (band == band_invalid) {
12984 printf("%s:Band Error\n", __func__);
12985 return RETURN_ERR;
12986 }
12987 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
12988 /*get current value in dat file*/
12989 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
12990 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
12991 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
12992 get_bssnum_byindex(radio_index, &bss_cnt);
12993 val_cnt = 2*bss_cnt - 1;
12994 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
12995 if ((val_cnt >= sizeof(new_ofdmabuf))
12996 || (val_cnt >= sizeof(new_mimobuf))) {
12997 printf("%s:bss cnt Error", __func__, bss_cnt);
12998 return RETURN_ERR;
12999 }
13000 /*translate set value*/
13001 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
13002 strncpy(new_ofdmabuf, str_zero, val_cnt);
13003 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013004 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080013005 strncpy(new_ofdmabuf, str_one, val_cnt);
13006 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013007 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080013008 strncpy(new_ofdmabuf, str_zero, val_cnt);
13009 strncpy(new_mimobuf, str_one, val_cnt);
13010 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
13011 strncpy(new_ofdmabuf, str_one, val_cnt);
13012 strncpy(new_mimobuf, str_one, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013013 }
developera1255e42023-05-13 17:45:02 +080013014 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13015 /*same value, not operation*/
13016 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13017 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13018 printf("%s:Reduntant value\n", __func__);
13019 return RETURN_OK;
13020 }
13021 /*modify dat file to new file*/
13022 params[0].name="MuOfdmaDlEnable";
13023 params[0].value=new_ofdmabuf;
13024 params[1].name="MuMimoDlEnable";
13025 params[1].value=new_mimobuf;
13026 wifi_datfileWrite(dat_file, params, 2);
13027 /*hostapd control restarp ap to take effect on these new value*/
13028 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013029 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13030 return RETURN_OK;
13031}
13032
13033INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
13034{
13035 struct params params={0};
13036 char config_file[64] = {0};
13037 char buf[64] = {0};
13038 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080013039 UCHAR dat_file[64] = {0};
13040 wifi_band band = band_invalid;
13041 char ofdmabuf[32] = {'\0'};
13042 char mimobuf[32] = {'\0'};
13043 char *token = NULL;
13044 UCHAR ofdma = 0;
13045 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013046
13047 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13048
13049 if (mu_type == NULL)
13050 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013051 band = wifi_index_to_band(radio_index);
13052 if (band == band_invalid) {
13053 printf("%s:Band Error\n", __func__);
13054 return RETURN_ERR;
13055 }
13056 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13057 /*get current value in dat file*/
13058 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13059 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013060
developera1255e42023-05-13 17:45:02 +080013061 token = strtok(ofdmabuf, ";");
13062 ofdma = strtol(token, NULL, 10);
13063 token = strtok(mimobuf, ";");
13064 mimo = strtol(token, NULL, 10);
13065 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
13066 if ((ofdma == 1) && (mimo == 1))
13067 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
13068 else if ((ofdma == 0) && (mimo == 1))
13069 *mu_type = WIFI_DL_MU_TYPE_MIMO;
13070 else if ((ofdma == 1) && (mimo == 0))
13071 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
13072 else
13073 *mu_type = WIFI_DL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013074 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13075 return RETURN_OK;
13076}
13077
13078INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
13079{
13080 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developera1255e42023-05-13 17:45:02 +080013081 UCHAR dat_file[64] = {0};
13082 wifi_band band = band_invalid;
13083 char cmd[128] = {0};
13084 char buf[256] = {0};
13085 char ofdmabuf[32] = {'\0'};
13086 char mimobuf[32] = {'\0'};
13087 char new_ofdmabuf[32] = {'\0'};
13088 char new_mimobuf[32] = {'\0'};
13089 struct params params[2];
13090 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13091 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13092 UCHAR bss_cnt = 0;
13093 UCHAR val_cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013094
developera1255e42023-05-13 17:45:02 +080013095 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13096 band = wifi_index_to_band(radio_index);
13097 if (band == band_invalid) {
13098 printf("%s:Band Error\n", __func__);
13099 return RETURN_ERR;
13100 }
13101 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
13102 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
13103 printf("%s:mu_type input Error\n", __func__);
13104 return RETURN_ERR;
13105 }
13106 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13107 /*get current value in dat file*/
13108 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13109 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
13110 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13111 get_bssnum_byindex(radio_index, &bss_cnt);
13112 val_cnt = 2*bss_cnt - 1;
13113 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
13114 if ((val_cnt >= sizeof(new_ofdmabuf))
13115 || (val_cnt >= sizeof(new_mimobuf))) {
13116 printf("%s:bss cnt Error\n", __func__, val_cnt);
13117 return RETURN_ERR;
13118 }
13119 /*translate set value*/
13120 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
13121 strncpy(new_ofdmabuf, str_zero, val_cnt);
13122 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013123 }
developera1255e42023-05-13 17:45:02 +080013124 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
13125 strncpy(new_ofdmabuf, str_one, val_cnt);
13126 strncpy(new_mimobuf, str_zero, val_cnt);
13127 }
13128 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13129 /*same value, not operation*/
13130 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13131 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13132 printf("%s:Reduntant value\n", __func__);
13133 return RETURN_OK;
13134 }
13135 /*modify dat file to new file*/
13136 params[0].name="MuOfdmaUlEnable";
13137 params[0].value=new_ofdmabuf;
13138 params[1].name="MuMimoUlEnable";
13139 params[1].value=new_mimobuf;
13140 wifi_datfileWrite(dat_file, params, 2);
13141 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013142 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13143 return RETURN_OK;
13144}
13145
13146INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
13147{
13148 struct params params={0};
13149 char config_file[64] = {0};
13150 char buf[64] = {0};
13151 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080013152 UCHAR dat_file[64] = {0};
13153 wifi_band band = band_invalid;
13154 char ofdmabuf[32] = {'\0'};
13155 char mimobuf[32] = {'\0'};
13156 char *token = NULL;
13157 UCHAR ofdma = 0;
13158 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013159
13160 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13161
13162 if (mu_type == NULL)
13163 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013164 band = wifi_index_to_band(radio_index);
13165 if (band == band_invalid) {
13166 printf("%s:Band Error", __func__);
13167 return RETURN_ERR;
13168 }
13169 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13170 /*get current value in dat file*/
13171 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13172 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013173
developera1255e42023-05-13 17:45:02 +080013174 token = strtok(ofdmabuf, ";");
13175 ofdma = strtol(token, NULL, 10);
13176 token = strtok(mimobuf, ";");
13177 mimo = strtol(token, NULL, 10);
13178 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
13179 if ((ofdma == 1) && (mimo == 0))
13180 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
13181 else
13182 *mu_type = WIFI_UL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013183 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13184 return RETURN_OK;
13185}
13186
13187
13188INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
13189{
13190 char cmd[128] = {0};
13191 char buf[256] = {0};
13192 char config_file[64] = {0};
13193 char GI[8] = {0};
13194 int mode_map = 0;
13195 FILE *f = NULL;
13196 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080013197 char dat_file[64] = {'\0'};
13198 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080013199
13200 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13201
13202 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
13203 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
13204 return RETURN_ERR;
13205 }
developera1255e42023-05-13 17:45:02 +080013206 /*sanity check*/
13207 if (((guard_interval == wifi_guard_interval_1600)
13208 || (guard_interval == wifi_guard_interval_3200))
13209 && (mode_map & (WIFI_MODE_BE | WIFI_MODE_AX) == 0)) {
13210 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
13211 return RETURN_ERR;
13212 }
developer72fb0bb2023-01-11 09:46:29 +080013213 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
13214 band = wifi_index_to_band(radio_index);
13215
13216 // Hostapd are not supported HE mode GI 1600, 3200 ns.
13217 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
13218 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
13219 _syscmd(cmd, buf, sizeof(buf));
13220 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
13221 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
13222 if (strstr(buf, "[SHORT-GI-") == NULL) {
13223 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
13224 _syscmd(cmd, buf, sizeof(buf));
13225 }
13226 if (band == band_5) {
13227 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
13228 if (strstr(buf, "[SHORT-GI-") == NULL) {
13229 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
13230 _syscmd(cmd, buf, sizeof(buf));
13231 }
13232 }
13233 }
developera1255e42023-05-13 17:45:02 +080013234 /*wifi_reloadAp(radio_index);
13235 caller "wifi_setRadioOperatingParameters" have done this step.
13236 */
13237 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13238 if (guard_interval == wifi_guard_interval_400) {
13239 params[0].name = "HT_GI";
13240 params[0].value = "1";
13241 params[1].name = "VHT_SGI";
13242 params[1].value = "1";
13243 wifi_datfileWrite(dat_file, params, 2);
developer72fb0bb2023-01-11 09:46:29 +080013244 strcpy(GI, "0.4");
developera1255e42023-05-13 17:45:02 +080013245 } else {
13246 params[0].name = "HT_GI";
13247 params[0].value = "0";
13248 params[1].name = "VHT_SGI";
13249 params[1].value = "0";
13250 /*should enable FIXED_HE_GI_SUPPORT in driver*/
13251 params[2].name = "FgiFltf";
13252 if (guard_interval == wifi_guard_interval_800) {
13253 params[2].value = "800";
13254 strcpy(GI, "0.8");
13255 } else if (guard_interval == wifi_guard_interval_1600) {
13256 params[2].value = "1600";
13257 strcpy(GI, "1.6");
13258 } else if (guard_interval == wifi_guard_interval_3200) {
13259 params[2].value = "3200";
13260 strcpy(GI, "3.2");
13261 } else if (guard_interval == wifi_guard_interval_auto) {
13262 params[2].value = "0";
13263 strcpy(GI, "auto");
13264 }
13265 wifi_datfileWrite(dat_file, params, 3);
13266 }
developer72fb0bb2023-01-11 09:46:29 +080013267 // Record GI for get GI function
13268 snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
13269 f = fopen(buf, "w");
13270 if (f == NULL)
13271 return RETURN_ERR;
13272 fprintf(f, "%s", GI);
13273 fclose(f);
13274 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13275 return RETURN_OK;
13276}
13277
13278INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
13279{
13280 char buf[32] = {0};
13281 char cmd[64] = {0};
13282
13283 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13284
13285 if (guard_interval == NULL)
13286 return RETURN_ERR;
13287
developera1255e42023-05-13 17:45:02 +080013288 snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013289 _syscmd(cmd, buf, sizeof(buf));
13290
13291 if (strncmp(buf, "0.4", 3) == 0)
13292 *guard_interval = wifi_guard_interval_400;
13293 else if (strncmp(buf, "0.8", 3) == 0)
13294 *guard_interval = wifi_guard_interval_800;
13295 else if (strncmp(buf, "1.6", 3) == 0)
13296 *guard_interval = wifi_guard_interval_1600;
13297 else if (strncmp(buf, "3.2", 3) == 0)
13298 *guard_interval = wifi_guard_interval_3200;
13299 else
13300 *guard_interval = wifi_guard_interval_auto;
13301
13302 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13303 return RETURN_OK;
13304}
13305
13306INT wifi_setBSSColor(INT radio_index, UCHAR color)
13307{
13308 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13309 struct params params = {0};
13310 char config_file[128] = {0};
13311 char bss_color[4] ={0};
13312
developera1255e42023-05-13 17:45:02 +080013313 if (color < 1 || color > 63) {
13314 wifi_dbg_printf("color value is err:%d.\n", color);
13315 return RETURN_ERR;
13316 }
developer72fb0bb2023-01-11 09:46:29 +080013317 params.name = "he_bss_color";
13318 snprintf(bss_color, sizeof(bss_color), "%hhu", color);
13319 params.value = bss_color;
13320 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13321 wifi_hostapdWrite(config_file, &params, 1);
developera1255e42023-05-13 17:45:02 +080013322 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
13323 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080013324
developer72fb0bb2023-01-11 09:46:29 +080013325 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13326 return RETURN_OK;
13327}
13328
13329INT wifi_getBSSColor(INT radio_index, UCHAR *color)
13330{
13331 char config_file[128] = {0};
13332 char buf[64] = {0};
13333 char temp_output[128] = {'\0'};
13334
13335 wifi_dbg_printf("\nFunc=%s\n", __func__);
13336 if (NULL == color)
13337 return RETURN_ERR;
13338
13339 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13340 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
13341
13342 if(strlen(buf) > 0) {
13343 snprintf(temp_output, sizeof(temp_output), "%s", buf);
13344 } else {
13345 snprintf(temp_output, sizeof(temp_output), "1"); // default value
13346 }
13347
13348 *color = (UCHAR)strtoul(temp_output, NULL, 10);
13349 wifi_dbg_printf("\noutput_string=%s\n", color);
13350
13351 return RETURN_OK;
13352}
13353
13354/* multi-psk support */
13355INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
13356{
13357 char cmd[256];
13358 char interface_name[16] = {0};
13359
13360 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13361 return RETURN_ERR;
13362
13363 sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
13364 interface_name,
13365 mac[0],
13366 mac[1],
13367 mac[2],
13368 mac[3],
13369 mac[4],
13370 mac[5]
13371 );
13372 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
13373 _syscmd(cmd, key->wifi_keyId, 64);
13374
13375
13376 return RETURN_OK;
13377}
13378
13379INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13380{
13381 char interface_name[16] = {0};
13382 FILE *fd = NULL;
13383 char fname[100];
13384 char cmd[128] = {0};
13385 char out[64] = {0};
13386 wifi_key_multi_psk_t * key = NULL;
13387 if(keysNumber < 0)
13388 return RETURN_ERR;
13389
13390 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13391 fd = fopen(fname, "w");
13392 if (!fd) {
13393 return RETURN_ERR;
13394 }
13395 key= (wifi_key_multi_psk_t *) keys;
13396 for(int i=0; i<keysNumber; ++i, key++) {
13397 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
13398 }
13399 fclose(fd);
13400
13401 //reload file
13402 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13403 return RETURN_ERR;
13404 sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
13405 _syscmd(cmd, out, 64);
13406 return RETURN_OK;
13407}
13408
13409INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13410{
13411 FILE *fd = NULL;
13412 char fname[100];
13413 char * line = NULL;
13414 char * pos = NULL;
13415 size_t len = 0;
13416 ssize_t read = 0;
13417 INT ret = RETURN_OK;
13418 wifi_key_multi_psk_t *keys_it = NULL;
13419
13420 if (keysNumber < 1) {
13421 return RETURN_ERR;
13422 }
13423
13424 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13425 fd = fopen(fname, "r");
13426 if (!fd) {
13427 return RETURN_ERR;
13428 }
13429
13430 if (keys == NULL) {
13431 ret = RETURN_ERR;
13432 goto close;
13433 }
13434
13435 keys_it = keys;
13436 while ((read = getline(&line, &len, fd)) != -1) {
13437 //Strip trailing new line if present
13438 if (read > 0 && line[read-1] == '\n') {
13439 line[read-1] = '\0';
13440 }
13441
13442 if(strcmp(line,"keyid=")) {
13443 sscanf(line, "keyid=%s", &(keys_it->wifi_keyId));
13444 if (!(pos = index(line, ' '))) {
13445 ret = RETURN_ERR;
13446 goto close;
13447 }
13448 pos++;
13449 //Here should be 00:00:00:00:00:00
13450 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
13451 printf("Not supported MAC: %s\n", pos);
13452 }
13453 if (!(pos = index(pos, ' '))) {
13454 ret = RETURN_ERR;
13455 goto close;
13456 }
13457 pos++;
13458
13459 //The rest is PSK
13460 snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
13461 keys_it++;
13462
13463 if(--keysNumber <= 0)
13464 break;
13465 }
13466 }
13467
13468close:
13469 free(line);
13470 fclose(fd);
13471 return ret;
13472}
13473/* end of multi-psk support */
13474
13475INT wifi_setNeighborReports(UINT apIndex,
13476 UINT numNeighborReports,
13477 wifi_NeighborReport_t *neighborReports)
13478{
13479 char cmd[256] = { 0 };
13480 char hex_bssid[13] = { 0 };
13481 char bssid[18] = { 0 };
13482 char nr[256] = { 0 };
13483 char ssid[256];
13484 char hex_ssid[256];
13485 char interface_name[16] = {0};
13486 INT ret;
13487
13488 /*rmeove all neighbors*/
13489 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
13490 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13491 return RETURN_ERR;
13492 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);
13493 system(cmd);
13494
13495 for(unsigned int i = 0; i < numNeighborReports; i++)
13496 {
13497 memset(ssid, 0, sizeof(ssid));
13498 ret = wifi_getSSIDName(apIndex, ssid);
13499 if (ret != RETURN_OK)
13500 return RETURN_ERR;
13501
13502 memset(hex_ssid, 0, sizeof(hex_ssid));
13503 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
13504 sprintf(hex_ssid + k,"%02x", ssid[j]);
13505
13506 snprintf(hex_bssid, sizeof(hex_bssid),
13507 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
13508 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
13509 snprintf(bssid, sizeof(bssid),
13510 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
13511 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
13512
13513 snprintf(nr, sizeof(nr),
13514 "%s" // bssid
13515 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
13516 "%02hhx" // operclass
13517 "%02hhx" // channel
13518 "%02hhx", // phy_mode
13519 hex_bssid,
13520 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
13521 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
13522 neighborReports[i].opClass,
13523 neighborReports[i].channel,
13524 neighborReports[i].phyTable);
13525
13526 snprintf(cmd, sizeof(cmd),
13527 "hostapd_cli set_neighbor "
13528 "%s " // bssid
13529 "ssid=%s " // ssid
13530 "nr=%s " // nr
13531 "-i %s",
13532 bssid,hex_ssid,nr, interface_name);
13533
13534 if (WEXITSTATUS(system(cmd)) != 0)
13535 {
13536 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
13537 }
13538 }
13539
13540 return RETURN_OK;
13541}
13542
13543INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
13544{
13545 return RETURN_OK;
13546}
13547
13548#ifdef _WIFI_HAL_TEST_
13549int main(int argc,char **argv)
13550{
13551 int index;
13552 INT ret=0;
13553 char buf[1024]="";
13554
13555 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13556 if(argc<3)
13557 {
13558 if(argc==2)
13559 {
13560 if(!strcmp(argv[1], "init"))
13561 return wifi_init();
13562 if(!strcmp(argv[1], "reset"))
13563 return wifi_reset();
13564 if(!strcmp(argv[1], "wifi_getHalVersion"))
13565 {
13566 char buffer[64];
13567 if(wifi_getHalVersion(buffer)==RETURN_OK)
13568 printf("Version: %s\n", buffer);
13569 else
13570 printf("Error in wifi_getHalVersion\n");
13571 return RETURN_OK;
13572 }
13573 }
13574 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
13575 exit(-1);
13576 }
13577
13578 index = atoi(argv[2]);
13579 if(strstr(argv[1], "wifi_getApName")!=NULL)
13580 {
13581 wifi_getApName(index,buf);
13582 printf("Ap name is %s \n",buf);
13583 return 0;
13584 }
developer2edaf012023-05-24 14:24:53 +080013585 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080013586 if(argc <= 3 )
13587 {
developer2edaf012023-05-24 14:24:53 +080013588 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
developer49b17232023-05-19 16:35:19 +080013589 exit(-1);
13590 }
13591 wifi_addApAclDevice(index, argv[3]);
13592 return 0;
13593 }
developer2edaf012023-05-24 14:24:53 +080013594 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
13595 wifi_getApAclDevices(index, buf, 1024);
13596 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080013597 return 0;
13598 }
developer2edaf012023-05-24 14:24:53 +080013599 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
13600 if(argc <= 3 )
13601 {
13602 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13603 exit(-1);
13604 }
13605 wifi_delApAclDevice(index, argv[3]);
13606 return 0;
13607 }
13608 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
13609 wifi_delApAclDevices(index);
13610 return 0;
13611 }
13612 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
13613 int acl_num = 0;
13614 wifi_getApAclDeviceNum(index, &acl_num);
13615 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
13616 return 0;
13617 }
13618 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
13619 wifi_getApDenyAclDevices(index, buf, 1024);
13620 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
13621 return 0;
13622 }
13623 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
13624 int filter_mode = 0;
13625 if(argc <= 3 )
13626 {
13627 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13628 exit(-1);
13629 }
13630 filter_mode = atoi(argv[3]);
13631 wifi_setApMacAddressControlMode(index,filter_mode);
13632 return 0;
13633 }
developer121a8e72023-05-22 09:19:39 +080013634
developer95c045d2023-05-24 19:26:28 +080013635 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
13636 int enable = 0;
13637 if(argc <= 3)
13638 {
13639 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13640 exit(-1);
13641 }
13642 enable = atoi(argv[3]);
13643 wifi_setApWmmEnable(index,enable);
13644 return 0;
13645 }
13646
13647 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
13648 BOOL enable = 0;
13649
13650 wifi_getApWMMCapability(index, &enable);
13651 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
13652 return 0;
13653 }
13654
13655 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
13656 BOOL enable = 0;
13657
13658 wifi_getApWmmEnable(index, &enable);
13659 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
13660 return 0;
13661 }
13662
developer2edaf012023-05-24 14:24:53 +080013663 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
13664 int filter_mode = 0;
13665 wifi_getApMacAddressControlMode(index, &filter_mode);
13666 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
13667 return 0;
13668 }
developer0f10c772023-05-16 21:43:39 +080013669 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
13670 {
13671 int mode = 0;
13672
13673 wifi_getRadioMode(index, buf, &mode);
13674 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
13675 return 0;
13676 }
developer72fb0bb2023-01-11 09:46:29 +080013677 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
13678 {
13679 BOOL b = FALSE;
13680 BOOL *output_bool = &b;
13681 wifi_getRadioAutoChannelEnable(index,output_bool);
13682 printf("Channel enabled = %d \n",b);
13683 return 0;
13684 }
13685 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
13686 {
13687 wifi_getApWpaEncryptionMode(index,buf);
13688 printf("encryption enabled = %s\n",buf);
13689 return 0;
13690 }
13691 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
13692 {
13693 BOOL b = FALSE;
13694 BOOL *output_bool = &b;
13695 wifi_getApSsidAdvertisementEnable(index,output_bool);
13696 printf("advertisment enabled = %d\n",b);
13697 return 0;
13698 }
13699 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
13700 {
13701 if(argc <= 3 )
13702 {
13703 printf("Insufficient arguments \n");
13704 exit(-1);
13705 }
13706
13707 char sta[20] = {'\0'};
13708 ULLONG handle= 0;
13709 strcpy(sta,argv[3]);
13710 mac_address_t st;
13711 mac_addr_aton(st,sta);
13712
13713 wifi_associated_dev_tid_stats_t tid_stats;
13714 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
13715 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
13716 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);
13717 }
13718
13719 if(strstr(argv[1], "getApEnable")!=NULL) {
13720 BOOL enable;
13721 ret=wifi_getApEnable(index, &enable);
13722 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
13723 }
13724 else if(strstr(argv[1], "setApEnable")!=NULL) {
13725 BOOL enable = atoi(argv[3]);
13726 ret=wifi_setApEnable(index, enable);
13727 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
13728 }
13729 else if(strstr(argv[1], "getApStatus")!=NULL) {
developer69b61b02023-03-07 17:17:44 +080013730 char status[64];
developer72fb0bb2023-01-11 09:46:29 +080013731 ret=wifi_getApStatus(index, status);
13732 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
13733 }
13734 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
13735 {
13736 wifi_getSSIDNameStatus(index,buf);
13737 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
13738 return 0;
developer2202b332023-05-24 16:23:22 +080013739 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
13740 wifi_resetApVlanCfg(index);
13741 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
13742 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013743 }
13744 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
13745 wifi_ssidTrafficStats2_t stats={0};
13746 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
13747 printf("%s %d: returns %d\n", argv[1], index, ret);
13748 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
13749 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
13750 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
13751 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
13752 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
13753 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
13754 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
13755 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
13756 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
13757 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
13758 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
13759 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
13760 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
13761 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
13762 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
13763 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
13764 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
13765 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
13766 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
13767 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
13768 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
13769 }
13770 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
13771 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
13772 UINT array_size=0;
13773 UINT i=0;
13774 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
13775 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080013776 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080013777 printf(" neighbor %d:\n", i);
13778 printf(" ap_SSID =%s\n", pt->ap_SSID);
13779 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
13780 printf(" ap_Mode =%s\n", pt->ap_Mode);
13781 printf(" ap_Channel =%d\n", pt->ap_Channel);
13782 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
13783 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
13784 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
13785 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
13786 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
13787 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
13788 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
13789 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
13790 printf(" ap_Noise =%d\n", pt->ap_Noise);
13791 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
13792 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
13793 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
developer69b61b02023-03-07 17:17:44 +080013794 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
developer72fb0bb2023-01-11 09:46:29 +080013795 }
13796 if(neighbor_ap_array)
13797 free(neighbor_ap_array); //make sure to free the list
13798 }
13799 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
13800 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
13801 UINT array_size=0;
13802 UINT i=0;
13803 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
13804 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080013805 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080013806 printf(" associated_dev %d:\n", i);
13807 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
13808 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
13809 printf(" cli_SNR =%d\n", pt->cli_SNR);
13810 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
13811 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
13812 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
13813 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
13814 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
13815 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
13816 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
13817 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
13818 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
13819 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
13820 }
13821 if(associated_dev_array)
13822 free(associated_dev_array); //make sure to free the list
13823 }
13824
13825 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
13826 {
13827#define MAX_ARRAY_SIZE 64
13828 int i, array_size;
13829 char *p, *ch_str;
13830 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
13831
13832 if(argc != 5)
13833 {
13834 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
13835 exit(-1);
13836 }
13837 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
13838
13839 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
13840 {
13841 strtok_r(ch_str, ",", &p);
13842 input_output_channelStats_array[i].ch_number = atoi(ch_str);
13843 }
13844 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
13845 if(!array_size)
13846 array_size=1;//Need to print current channel statistics
13847 for(i=0; i<array_size; i++)
13848 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
13849 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
13850 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
13851 input_output_channelStats_array[i].ch_number,\
13852 input_output_channelStats_array[i].ch_noise,\
13853 input_output_channelStats_array[i].ch_utilization_busy_rx,\
13854 input_output_channelStats_array[i].ch_utilization_busy_tx,\
13855 input_output_channelStats_array[i].ch_utilization_busy,\
13856 input_output_channelStats_array[i].ch_utilization_busy_ext,\
13857 input_output_channelStats_array[i].ch_utilization_total);
13858 }
13859
13860 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
13861 {
13862 if(argc <= 3 )
13863 {
13864 printf("Insufficient arguments \n");
13865 exit(-1);
13866 }
13867 char mac_addr[20] = {'\0'};
13868 wifi_device_t output_struct;
13869 int dev_index = atoi(argv[3]);
13870
13871 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
13872 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
13873 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);
13874 }
13875
13876 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
13877 {
13878 if (argc <= 3)
13879 {
13880 printf("Insufficient arguments\n");
13881 exit(-1);
13882 }
13883 char args[256];
13884 wifi_NeighborReport_t *neighborReports;
13885
13886 neighborReports = calloc(argc - 2, sizeof(neighborReports));
13887 if (!neighborReports)
13888 {
13889 printf("Failed to allocate memory");
13890 exit(-1);
13891 }
13892
13893 for (int i = 3; i < argc; ++i)
13894 {
13895 char *val;
13896 int j = 0;
13897 memset(args, 0, sizeof(args));
13898 strncpy(args, argv[i], sizeof(args));
13899 val = strtok(args, ";");
13900 while (val != NULL)
13901 {
13902 if (j == 0)
13903 {
13904 mac_addr_aton(neighborReports[i - 3].bssid, val);
13905 } else if (j == 1)
13906 {
13907 neighborReports[i - 3].info = strtol(val, NULL, 16);
13908 } else if (j == 2)
13909 {
13910 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
13911 } else if (j == 3)
13912 {
13913 neighborReports[i - 3].channel = strtol(val, NULL, 16);
13914 } else if (j == 4)
13915 {
13916 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
13917 } else {
13918 printf("Insufficient arguments]n\n");
13919 exit(-1);
13920 }
13921 val = strtok(NULL, ";");
13922 j++;
13923 }
13924 }
13925
13926 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
13927 if (ret != RETURN_OK)
13928 {
13929 printf("wifi_setNeighborReports ret = %d", ret);
13930 exit(-1);
13931 }
13932 }
13933 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
13934 {
13935 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
13936 printf("%s.\n", buf);
13937 else
13938 printf("Error returned\n");
13939 }
13940 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
13941 {
13942 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
13943 printf("%s.\n", buf);
13944 else
13945 printf("Error returned\n");
13946 }
13947 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
13948 {
13949 if (argc <= 2)
13950 {
13951 printf("Insufficient arguments\n");
13952 exit(-1);
13953 }
13954 char buf[64]= {'\0'};
13955 wifi_getRadioOperatingChannelBandwidth(index,buf);
13956 printf("Current bandwidth is %s \n",buf);
13957 return 0;
13958 }
13959 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
13960 {
13961 if (argc <= 5)
13962 {
13963 printf("Insufficient arguments\n");
13964 exit(-1);
13965 }
13966 UINT channel = atoi(argv[3]);
13967 UINT width = atoi(argv[4]);
13968 UINT beacon = atoi(argv[5]);
13969 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
13970 printf("Result = %d", ret);
13971 }
13972
13973 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13974 return 0;
13975}
13976
13977#endif
13978
13979#ifdef WIFI_HAL_VERSION_3
13980
13981INT BitMapToTransmitRates(UINT bitMap, char *BasicRate)
13982{
13983 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13984 if (bitMap & WIFI_BITRATE_1MBPS)
13985 strcat(BasicRate, "1,");
13986 if (bitMap & WIFI_BITRATE_2MBPS)
13987 strcat(BasicRate, "2,");
13988 if (bitMap & WIFI_BITRATE_5_5MBPS)
13989 strcat(BasicRate, "5.5,");
13990 if (bitMap & WIFI_BITRATE_6MBPS)
13991 strcat(BasicRate, "6,");
13992 if (bitMap & WIFI_BITRATE_9MBPS)
13993 strcat(BasicRate, "9,");
13994 if (bitMap & WIFI_BITRATE_11MBPS)
13995 strcat(BasicRate, "11,");
13996 if (bitMap & WIFI_BITRATE_12MBPS)
13997 strcat(BasicRate, "12,");
13998 if (bitMap & WIFI_BITRATE_18MBPS)
13999 strcat(BasicRate, "18,");
14000 if (bitMap & WIFI_BITRATE_24MBPS)
14001 strcat(BasicRate, "24,");
14002 if (bitMap & WIFI_BITRATE_36MBPS)
14003 strcat(BasicRate, "36,");
14004 if (bitMap & WIFI_BITRATE_48MBPS)
14005 strcat(BasicRate, "48,");
14006 if (bitMap & WIFI_BITRATE_54MBPS)
14007 strcat(BasicRate, "54,");
14008 if (strlen(BasicRate) != 0) // remove last comma
14009 BasicRate[strlen(BasicRate) - 1] = '\0';
14010 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14011 return RETURN_OK;
14012}
14013
14014INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
14015{
14016 UINT BitMap = 0;
14017 char *rate;
14018
14019 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14020 rate = strtok(BasicRatesList, ",");
14021 while(rate != NULL)
14022 {
14023 if (strcmp(rate, "1") == 0)
14024 BitMap |= WIFI_BITRATE_1MBPS;
14025 else if (strcmp(rate, "2") == 0)
14026 BitMap |= WIFI_BITRATE_2MBPS;
14027 else if (strcmp(rate, "5.5") == 0)
14028 BitMap |= WIFI_BITRATE_5_5MBPS;
14029 else if (strcmp(rate, "6") == 0)
14030 BitMap |= WIFI_BITRATE_6MBPS;
14031 else if (strcmp(rate, "9") == 0)
14032 BitMap |= WIFI_BITRATE_9MBPS;
14033 else if (strcmp(rate, "11") == 0)
14034 BitMap |= WIFI_BITRATE_11MBPS;
14035 else if (strcmp(rate, "12") == 0)
14036 BitMap |= WIFI_BITRATE_12MBPS;
14037 else if (strcmp(rate, "18") == 0)
14038 BitMap |= WIFI_BITRATE_18MBPS;
14039 else if (strcmp(rate, "24") == 0)
14040 BitMap |= WIFI_BITRATE_24MBPS;
14041 else if (strcmp(rate, "36") == 0)
14042 BitMap |= WIFI_BITRATE_36MBPS;
14043 else if (strcmp(rate, "48") == 0)
14044 BitMap |= WIFI_BITRATE_48MBPS;
14045 else if (strcmp(rate, "54") == 0)
14046 BitMap |= WIFI_BITRATE_54MBPS;
14047 rate = strtok(NULL, ",");
14048 }
14049 *basicRateBitMap = BitMap;
14050 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14051 return RETURN_OK;
14052}
14053
14054// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
14055INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14056{
14057 char buf[128] = {0};
14058 char cmd[128] = {0};
14059 char config_file[64] = {0};
14060 int bandwidth;
14061 int set_mode = 0;
14062 wifi_radio_operationParam_t current_param;
14063
14064 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14065
14066 multiple_set = TRUE;
14067 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
14068 fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__);
14069 return RETURN_ERR;
14070 }
14071 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
14072 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
14073 fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__);
14074 return RETURN_ERR;
14075 }
14076 }
14077
14078 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
14079 bandwidth = 20;
14080 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
14081 bandwidth = 40;
14082 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
14083 bandwidth = 80;
14084 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
14085 bandwidth = 160;
14086 if (operationParam->autoChannelEnabled){
14087 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14088 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14089 return RETURN_ERR;
14090 }
developer69b61b02023-03-07 17:17:44 +080014091 }else{
developer72fb0bb2023-01-11 09:46:29 +080014092 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14093 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14094 return RETURN_ERR;
14095 }
14096 }
14097
14098 if (current_param.variant != operationParam->variant) {
14099 // Two different definition bit map, so need to check every bit.
14100 if (operationParam->variant & WIFI_80211_VARIANT_A)
14101 set_mode |= WIFI_MODE_A;
14102 if (operationParam->variant & WIFI_80211_VARIANT_B)
14103 set_mode |= WIFI_MODE_B;
14104 if (operationParam->variant & WIFI_80211_VARIANT_G)
14105 set_mode |= WIFI_MODE_G;
14106 if (operationParam->variant & WIFI_80211_VARIANT_N)
14107 set_mode |= WIFI_MODE_N;
14108 if (operationParam->variant & WIFI_80211_VARIANT_AC)
14109 set_mode |= WIFI_MODE_AC;
14110 if (operationParam->variant & WIFI_80211_VARIANT_AX)
14111 set_mode |= WIFI_MODE_AX;
14112 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
14113 memset(buf, 0, sizeof(buf));
developer0f10c772023-05-16 21:43:39 +080014114 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014115 fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__);
14116 return RETURN_ERR;
14117 }
14118 }
14119 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
14120 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
14121 fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__);
14122 return RETURN_ERR;
14123 }
14124 }
14125 if (current_param.beaconInterval != operationParam->beaconInterval) {
14126 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
14127 fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__);
14128 return RETURN_ERR;
14129 }
14130 }
14131 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
14132 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf);
14133 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14134 fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__);
14135 return RETURN_ERR;
14136 }
14137 }
14138 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
14139 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
14140 fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__);
14141 return RETURN_ERR;
14142 }
14143 }
14144 if (current_param.guardInterval != operationParam->guardInterval) {
14145 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
14146 fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__);
14147 return RETURN_ERR;
14148 }
14149 }
14150 if (current_param.transmitPower != operationParam->transmitPower) {
14151 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
14152 fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__);
14153 return RETURN_ERR;
14154 }
14155 }
14156 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
14157 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
14158 fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__);
14159 return RETURN_ERR;
14160 }
14161 }
14162 if (current_param.obssCoex != operationParam->obssCoex) {
14163 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
14164 fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__);
14165 return RETURN_ERR;
14166 }
14167 }
14168 if (current_param.stbcEnable != operationParam->stbcEnable) {
14169 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
14170 fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__);
14171 return RETURN_ERR;
14172 }
14173 }
14174 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
14175 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
14176 fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__);
14177 return RETURN_ERR;
14178 }
14179 }
14180
14181 // if enable is true, then restart the radio
14182 wifi_setRadioEnable(index, FALSE);
14183 if (operationParam->enable == TRUE)
14184 wifi_setRadioEnable(index, TRUE);
14185 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14186
14187 return RETURN_OK;
14188}
14189
14190INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14191{
14192 char band[64] = {0};
14193 char buf[256] = {0};
14194 char config_file[64] = {0};
14195 char cmd[128] = {0};
14196 int ret = RETURN_ERR;
14197 int mode = 0;
14198 ULONG channel = 0;
14199 BOOL enabled = FALSE;
14200
14201 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14202 printf("Entering %s index = %d\n", __func__, (int)index);
14203
14204 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
14205 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
14206 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
14207 {
14208 fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__);
14209 return RETURN_ERR;
14210 }
14211 operationParam->enable = enabled;
14212
14213 memset(band, 0, sizeof(band));
14214 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
14215 {
14216 fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__);
14217 return RETURN_ERR;
14218 }
14219
14220 if (!strcmp(band, "2.4GHz"))
14221 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
14222 else if (!strcmp(band, "5GHz"))
14223 operationParam->band = WIFI_FREQUENCY_5_BAND;
14224 else if (!strcmp(band, "6GHz"))
14225 operationParam->band = WIFI_FREQUENCY_6_BAND;
14226 else
14227 {
14228 fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
14229 band);
14230 }
14231
14232 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
14233 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
14234 operationParam->channel = 0;
14235 operationParam->autoChannelEnabled = TRUE;
14236 } else {
14237 operationParam->channel = strtol(buf, NULL, 10);
14238 operationParam->autoChannelEnabled = FALSE;
14239 }
14240
14241 memset(buf, 0, sizeof(buf));
14242 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
14243 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__);
14244 return RETURN_ERR;
14245 }
14246 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
14247 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
14248 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
14249 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
14250 else
14251 {
14252 fprintf(stderr, "Unknown channel bandwidth: %s\n", buf);
14253 return false;
14254 }
14255
14256 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
14257 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
14258 return RETURN_ERR;
14259 }
14260 // Two different definition bit map, so need to check every bit.
14261 if (mode & WIFI_MODE_A)
14262 operationParam->variant |= WIFI_80211_VARIANT_A;
14263 if (mode & WIFI_MODE_B)
14264 operationParam->variant |= WIFI_80211_VARIANT_B;
14265 if (mode & WIFI_MODE_G)
14266 operationParam->variant |= WIFI_80211_VARIANT_G;
14267 if (mode & WIFI_MODE_N)
14268 operationParam->variant |= WIFI_80211_VARIANT_N;
14269 if (mode & WIFI_MODE_AC)
14270 operationParam->variant |= WIFI_80211_VARIANT_AC;
14271 if (mode & WIFI_MODE_AX)
14272 operationParam->variant |= WIFI_80211_VARIANT_AX;
14273 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
14274 fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__);
14275 return RETURN_ERR;
14276 }
14277 if (wifi_getApDTIMInterval(index, &operationParam->dtimPeriod) != RETURN_OK) {
14278 fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__);
14279 return RETURN_ERR;
14280 }
14281 if (wifi_getRadioBeaconPeriod(index, &operationParam->dtimPeriod) != RETURN_OK) {
14282 fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__);
14283 return RETURN_ERR;
14284 }
14285
14286 memset(buf, 0, sizeof(buf));
14287 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
14288 fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__);
14289 return RETURN_ERR;
14290 }
14291 TransmitRatesToBitMap(buf, &operationParam->basicDataTransmitRates);
14292
14293 memset(buf, 0, sizeof(buf));
14294 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14295 fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__);
14296 return RETURN_ERR;
14297 }
14298 TransmitRatesToBitMap(buf, &operationParam->operationalDataTransmitRates);
14299
14300 memset(buf, 0, sizeof(buf));
14301 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
14302 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
14303
14304 if (wifi_getGuardInterval(index, &operationParam->guardInterval) != RETURN_OK) {
14305 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
14306 return RETURN_ERR;
14307 }
developera1255e42023-05-13 17:45:02 +080014308 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&operationParam->transmitPower) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014309 fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__);
14310 return RETURN_ERR;
14311 }
14312
14313 memset(buf, 0, sizeof(buf));
14314 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
14315 if (strcmp(buf, "-1") == 0) {
14316 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
14317 operationParam->ctsProtection = FALSE;
14318 } else {
14319 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
14320 operationParam->ctsProtection = TRUE;
14321 }
14322
14323 memset(buf, 0, sizeof(buf));
14324 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
14325 if (strcmp(buf, "0") == 0)
14326 operationParam->obssCoex = FALSE;
14327 else
14328 operationParam->obssCoex = TRUE;
14329
14330 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
14331 _syscmd(cmd, buf, sizeof(buf));
14332 if (strlen(buf) != 0)
14333 operationParam->stbcEnable = TRUE;
14334 else
14335 operationParam->stbcEnable = FALSE;
14336
14337 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
14338 fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__);
14339 return RETURN_ERR;
14340 }
14341
14342 // Below value is hardcoded
14343
14344 operationParam->numSecondaryChannels = 0;
14345 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
14346 operationParam->channelSecondary[i] = 0;
14347 }
14348 operationParam->csa_beacon_count = 15;
14349 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
14350
14351 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14352 return RETURN_OK;
14353}
14354
14355static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
14356{
14357 int max_radio_num = 0;
14358
14359 wifi_getMaxRadioNumber(&max_radio_num);
14360 if (radioIndex >= max_radio_num) {
14361 fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex);
14362 return RETURN_ERR;
14363 }
14364
14365 return (arrayIndex * max_radio_num) + radioIndex;
14366}
14367
developer96b38512023-02-22 11:17:45 +080014368static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
14369{
14370 int max_radio_num = 0;
14371
14372 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
14373 return -1;
14374
14375 wifi_getMaxRadioNumber(&max_radio_num);
14376
14377 (*radioIndex) = vapIndex % max_radio_num;
14378 (*arrayIndex) = vapIndex / max_radio_num;
14379
14380 return 0;
14381}
14382
14383
developer72fb0bb2023-01-11 09:46:29 +080014384wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
14385 if (strncmp(beaconRate, "1Mbps", 5) == 0)
14386 return WIFI_BITRATE_1MBPS;
14387 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
14388 return WIFI_BITRATE_2MBPS;
14389 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
14390 return WIFI_BITRATE_5_5MBPS;
14391 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
14392 return WIFI_BITRATE_6MBPS;
14393 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
14394 return WIFI_BITRATE_9MBPS;
14395 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
14396 return WIFI_BITRATE_11MBPS;
14397 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
14398 return WIFI_BITRATE_12MBPS;
14399 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
14400 return WIFI_BITRATE_18MBPS;
14401 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
14402 return WIFI_BITRATE_24MBPS;
14403 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
14404 return WIFI_BITRATE_36MBPS;
14405 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
14406 return WIFI_BITRATE_48MBPS;
14407 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
14408 return WIFI_BITRATE_54MBPS;
14409 return WIFI_BITRATE_DEFAULT;
14410}
14411
14412INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str)
14413{
14414 if (beacon == WIFI_BITRATE_1MBPS)
14415 strcpy(beacon_str, "1Mbps");
14416 else if (beacon == WIFI_BITRATE_2MBPS)
14417 strcpy(beacon_str, "2Mbps");
14418 else if (beacon == WIFI_BITRATE_5_5MBPS)
14419 strcpy(beacon_str, "5.5Mbps");
14420 else if (beacon == WIFI_BITRATE_6MBPS)
14421 strcpy(beacon_str, "6Mbps");
14422 else if (beacon == WIFI_BITRATE_9MBPS)
14423 strcpy(beacon_str, "9Mbps");
14424 else if (beacon == WIFI_BITRATE_11MBPS)
14425 strcpy(beacon_str, "11Mbps");
14426 else if (beacon == WIFI_BITRATE_12MBPS)
14427 strcpy(beacon_str, "12Mbps");
14428 else if (beacon == WIFI_BITRATE_18MBPS)
14429 strcpy(beacon_str, "18Mbps");
14430 else if (beacon == WIFI_BITRATE_24MBPS)
14431 strcpy(beacon_str, "24Mbps");
14432 else if (beacon == WIFI_BITRATE_36MBPS)
14433 strcpy(beacon_str, "36Mbps");
14434 else if (beacon == WIFI_BITRATE_48MBPS)
14435 strcpy(beacon_str, "48Mbps");
14436 else if (beacon == WIFI_BITRATE_54MBPS)
14437 strcpy(beacon_str, "54Mbps");
14438 return RETURN_OK;
14439}
14440
14441INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
14442{
14443 INT mode = 0;
14444 INT ret = -1;
14445 INT output = 0;
14446 int i = 0;
14447 int vap_index = 0;
14448 BOOL enabled = FALSE;
14449 char buf[256] = {0};
14450 wifi_vap_security_t security = {0};
developer72fb0bb2023-01-11 09:46:29 +080014451
14452 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14453 printf("Entering %s index = %d\n", __func__, (int)index);
14454
developerfde01262023-05-22 15:15:24 +080014455 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
14456 if (ret != 0) {
14457 fprintf(stderr, "%s: wifi_BandProfileRead BssidNum failed\n", __func__);
14458 return RETURN_ERR;
14459 }
14460
14461 map->num_vaps = atoi(buf);
14462 if (map->num_vaps <= 0) {
14463 fprintf(stderr, "%s: invalid BssidNum %s\n", __func__, buf);
14464 return RETURN_ERR;
14465 }
14466
14467 for (i = 0; i < map->num_vaps; i++)
developer72fb0bb2023-01-11 09:46:29 +080014468 {
14469 map->vap_array[i].radio_index = index;
14470
14471 vap_index = array_index_to_vap_index(index, i);
14472 if (vap_index < 0)
14473 return RETURN_ERR;
14474
14475 strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME);
14476
14477 map->vap_array[i].vap_index = vap_index;
14478
14479 memset(buf, 0, sizeof(buf));
14480 ret = wifi_getApName(vap_index, buf);
14481 if (ret != RETURN_OK) {
14482 printf("%s: wifi_getApName return error\n", __func__);
14483 return RETURN_ERR;
14484 }
14485 snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
14486
14487 memset(buf, 0, sizeof(buf));
14488 ret = wifi_getSSIDName(vap_index, buf);
14489 if (ret != RETURN_OK) {
14490 printf("%s: wifi_getSSIDName return error\n", __func__);
14491 return RETURN_ERR;
14492 }
14493 snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
14494
developere740c2a2023-05-23 18:34:32 +080014495#if 0
developer72fb0bb2023-01-11 09:46:29 +080014496 ret = wifi_getSSIDEnable(vap_index, &enabled);
14497 if (ret != RETURN_OK) {
14498 printf("%s: wifi_getSSIDEnable return error\n", __func__);
14499 return RETURN_ERR;
14500 }
developere740c2a2023-05-23 18:34:32 +080014501#endif
14502 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080014503
14504 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
14505 if (ret != RETURN_OK) {
14506 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
14507 return RETURN_ERR;
14508 }
14509 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080014510
developer72fb0bb2023-01-11 09:46:29 +080014511 ret = wifi_getApIsolationEnable(vap_index, &enabled);
14512 if (ret != RETURN_OK) {
14513 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
14514 return RETURN_ERR;
14515 }
14516 map->vap_array[i].u.bss_info.isolation = enabled;
14517
14518 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
14519 if (ret != RETURN_OK) {
14520 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
14521 return RETURN_ERR;
14522 }
14523 map->vap_array[i].u.bss_info.bssMaxSta = output;
14524
14525 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
14526 if (ret != RETURN_OK) {
14527 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
14528 return RETURN_ERR;
14529 }
14530 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
14531
14532 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
14533 if (ret != RETURN_OK) {
14534 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
14535 return RETURN_ERR;
14536 }
14537 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
14538
14539 ret = wifi_getApSecurity(vap_index, &security);
14540 if (ret != RETURN_OK) {
14541 printf("%s: wifi_getApSecurity return error\n", __func__);
14542 return RETURN_ERR;
14543 }
14544 map->vap_array[i].u.bss_info.security = security;
14545
14546 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
14547 if (ret != RETURN_OK) {
14548 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
14549 return RETURN_ERR;
14550 }
developer69b61b02023-03-07 17:17:44 +080014551 if (mode == 0)
developer72fb0bb2023-01-11 09:46:29 +080014552 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
developer69b61b02023-03-07 17:17:44 +080014553 else
developer72fb0bb2023-01-11 09:46:29 +080014554 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
developer69b61b02023-03-07 17:17:44 +080014555 if (mode == 1)
developer72fb0bb2023-01-11 09:46:29 +080014556 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
developer69b61b02023-03-07 17:17:44 +080014557 else if (mode == 2)
developer72fb0bb2023-01-11 09:46:29 +080014558 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
14559
14560 ret = wifi_getApWmmEnable(vap_index, &enabled);
14561 if (ret != RETURN_OK) {
14562 printf("%s: wifi_getApWmmEnable return error\n", __func__);
14563 return RETURN_ERR;
14564 }
14565 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
14566
14567 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
14568 if (ret != RETURN_OK) {
14569 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
14570 return RETURN_ERR;
14571 }
14572 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
14573
14574 memset(buf, 0, sizeof(buf));
14575 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
14576 if (ret != RETURN_OK) {
14577 printf("%s: wifi_getApBeaconRate return error\n", __func__);
14578 return RETURN_ERR;
14579 }
14580 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
14581
14582 memset(buf, 0, sizeof(buf));
14583 ret = wifi_getBaseBSSID(vap_index, buf);
14584 if (ret != RETURN_OK) {
14585 printf("%s: wifi_getBaseBSSID return error\n", __func__);
14586 return RETURN_ERR;
14587 }
developer5b2f10c2023-05-25 17:02:21 +080014588 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
14589 printf("%s: hwaddr_aton2 fail\n", __func__);
14590 return RETURN_ERR;
14591 }
developer72fb0bb2023-01-11 09:46:29 +080014592
14593 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
14594 if (ret != RETURN_OK) {
14595 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
14596 return RETURN_ERR;
14597 }
14598 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
14599
14600 // TODO: wps, noack
14601 }
14602 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14603 return RETURN_OK;
14604}
14605
developer47cc27a2023-05-17 23:09:58 +080014606void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080014607{
14608 char if_name[16] = {0};
14609 char cmd[128] = {0};
14610 char buf[128] = {0};
14611
14612 *enable = FALSE;
14613 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
14614 return;
14615
14616 snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
14617 _syscmd(cmd, buf, sizeof(buf));
14618 if (strlen(buf) > 0)
14619 *enable = TRUE;
14620 return;
14621}
14622
14623static int prepareInterface(UINT apIndex, char *new_interface)
14624{
14625 char cur_interface[16] = {0};
14626 char config_file[128] = {0};
developer8a3bbbf2023-03-15 17:47:23 +080014627 char cmd[MAX_CMD_SIZE] = {0};
14628 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080014629 int max_radio_num = 0;
14630 int radioIndex = -1;
14631 int phyIndex = -1;
developer8a3bbbf2023-03-15 17:47:23 +080014632 struct params params;
developer72fb0bb2023-01-11 09:46:29 +080014633
14634 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14635 wifi_hostapdRead(config_file, "interface", cur_interface, sizeof(cur_interface));
14636
14637 if (strncmp(cur_interface, new_interface, sizeof(cur_interface)) != 0) {
developer8a3bbbf2023-03-15 17:47:23 +080014638 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +080014639 radioIndex = apIndex % max_radio_num;
14640 phyIndex = radio_index_to_phy(radioIndex);
14641 // disable and del old interface, then add new interface
14642 wifi_setApEnable(apIndex, FALSE);
developer8a3bbbf2023-03-15 17:47:23 +080014643
14644 params.name = "interface";
14645 params.value = new_interface;
14646 wifi_hostapdWrite(config_file, &params, 1);
14647
14648 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyIndex, config_file);
14649 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080014650 }
developer8a3bbbf2023-03-15 17:47:23 +080014651
developer72fb0bb2023-01-11 09:46:29 +080014652 // update the vap status file
14653 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=1' %s", cur_interface, new_interface, VAP_STATUS_FILE);
14654 _syscmd(cmd, buf, sizeof(buf));
14655 return RETURN_OK;
14656}
14657
14658INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
14659{
14660 char interface_name[16] = {0};
14661 unsigned int i;
14662 wifi_vap_info_t *vap_info = NULL;
14663 int acl_mode;
14664 int ret = 0;
14665 char *sec_str = NULL;
14666 char buf[256] = {0};
14667 char cmd[128] = {0};
14668 char config_file[64] = {0};
14669 char bssid[32] = {0};
14670 char psk_file[64] = {0};
developer47cc27a2023-05-17 23:09:58 +080014671 BOOL enable = FALSE;
developere740c2a2023-05-23 18:34:32 +080014672 int band_idx;
14673
developer72fb0bb2023-01-11 09:46:29 +080014674
14675 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14676 printf("Entering %s index = %d\n", __func__, (int)index);
14677 for (i = 0; i < map->num_vaps; i++)
14678 {
14679 multiple_set = TRUE;
14680 vap_info = &map->vap_array[i];
14681
14682 // Check vap status file to enable multiple ap if the system boot.
14683 checkVapStatus(vap_info->vap_index, &enable);
14684 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
14685 continue;
14686
14687 fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
14688
developere740c2a2023-05-23 18:34:32 +080014689 band_idx = radio_index_to_band(index);
14690 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
14691 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
14692 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080014693
developere740c2a2023-05-23 18:34:32 +080014694 struct params params[4];
developer72fb0bb2023-01-11 09:46:29 +080014695 params[0].name = "interface";
14696 params[0].value = vap_info->vap_name;
14697 mac_addr_ntoa(bssid, vap_info->u.bss_info.bssid);
14698 params[1].name = "bssid";
14699 params[1].value = bssid;
14700 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
14701 params[2].name = "wpa_psk_file";
14702 params[2].value = psk_file;
developere740c2a2023-05-23 18:34:32 +080014703 params[3].name = "ssid";
14704 params[3].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080014705
14706 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
developere740c2a2023-05-23 18:34:32 +080014707 wifi_hostapdWrite(config_file, params, 4);
developer72fb0bb2023-01-11 09:46:29 +080014708
14709 snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
14710 _syscmd(cmd, buf, sizeof(buf));
14711
14712 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
14713 if (ret != RETURN_OK) {
14714 fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__);
14715 return RETURN_ERR;
14716 }
14717
14718 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
14719 if (ret != RETURN_OK) {
14720 fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__);
14721 return RETURN_ERR;
14722 }
14723
14724 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
14725 if (ret != RETURN_OK) {
14726 fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__);
14727 return RETURN_ERR;
14728 }
14729
14730 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
14731 if (ret != RETURN_OK) {
14732 fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__);
14733 return RETURN_ERR;
14734 }
14735
14736 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
14737 if (ret != RETURN_OK) {
14738 fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__);
14739 return RETURN_ERR;
14740 }
14741
14742 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
14743 if (ret != RETURN_OK) {
14744 fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__);
14745 return RETURN_ERR;
14746 }
14747
14748 if (vap_info->u.bss_info.mac_filter_enable == false){
14749 acl_mode = 0;
14750 }else {
14751 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
14752 acl_mode = 2;
14753 snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
14754 _syscmd(cmd, buf, sizeof(buf));
14755 }else{
14756 acl_mode = 1;
14757 }
14758 }
14759
14760 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
14761 if (ret != RETURN_OK) {
14762 fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__);
14763 return RETURN_ERR;
14764 }
14765
14766 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
14767 if (ret != RETURN_OK) {
14768 fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__);
14769 return RETURN_ERR;
14770 }
14771
developer0f10c772023-05-16 21:43:39 +080014772 memset(buf, 0, sizeof(buf));
14773 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf);
14774 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
14775 if (ret != RETURN_OK) {
14776 fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__);
14777 return RETURN_ERR;
14778 }
developer72fb0bb2023-01-11 09:46:29 +080014779
14780 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
14781 if (ret != RETURN_OK) {
14782 fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__);
14783 return RETURN_ERR;
14784 }
14785
developer72fb0bb2023-01-11 09:46:29 +080014786 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
14787 if (ret != RETURN_OK) {
14788 fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__);
14789 return RETURN_ERR;
14790 }
14791
developer23e71282023-01-18 10:25:19 +080014792 wifi_setApEnable(vap_info->vap_index, FALSE);
14793 wifi_setApEnable(vap_info->vap_index, TRUE);
14794 multiple_set = FALSE;
14795
14796 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
developer72fb0bb2023-01-11 09:46:29 +080014797 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
14798 if (ret != RETURN_OK) {
14799 fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__);
14800 return RETURN_ERR;
14801 }
14802
14803 // TODO mgmtPowerControl, interworking, wps
14804 }
14805 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14806 return RETURN_OK;
14807}
14808
14809int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
14810{
14811 char *token, *next;
14812 const char s[2] = ",";
14813 int count =0;
14814
14815 /* get the first token */
14816 token = strtok_r(pchannels, s, &next);
14817
14818 /* walk through other tokens */
14819 while( token != NULL && count < MAX_CHANNELS) {
14820 chlistptr->channels_list[count++] = atoi(token);
14821 token = strtok_r(NULL, s, &next);
14822 }
14823
14824 return count;
14825}
14826
14827static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
14828{
14829 INT status;
14830 wifi_channels_list_t *chlistp;
14831 CHAR output_string[64];
14832 CHAR pchannels[128];
14833 CHAR interface_name[16] = {0};
14834 wifi_band band;
14835
14836 if(rcap == NULL)
14837 {
14838 return RETURN_ERR;
14839 }
14840
14841 rcap->numSupportedFreqBand = 1;
14842 band = wifi_index_to_band(radioIndex);
14843
14844 if (band == band_2_4)
14845 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
14846 else if (band == band_5)
14847 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
14848 else if (band == band_6)
14849 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
14850
14851 chlistp = &(rcap->channel_list[0]);
14852 memset(pchannels, 0, sizeof(pchannels));
14853
14854 /* possible number of radio channels */
14855 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
14856 {
14857 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
14858 }
14859 /* Number of channels and list*/
14860 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
14861
14862 /* autoChannelSupported */
14863 /* always ON with wifi_getRadioAutoChannelSupported */
14864 rcap->autoChannelSupported = TRUE;
14865
14866 /* DCSSupported */
14867 /* always ON with wifi_getRadioDCSSupported */
14868 rcap->DCSSupported = TRUE;
14869
14870 /* zeroDFSSupported - TBD */
14871 rcap->zeroDFSSupported = FALSE;
14872
14873 /* Supported Country List*/
14874 memset(output_string, 0, sizeof(output_string));
14875 status = wifi_getRadioCountryCode(radioIndex, output_string);
14876 if( status != 0 ) {
14877 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
14878 return RETURN_ERR;
14879 } else {
14880 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
14881 }
14882 if(!strcmp(output_string,"US")){
14883 rcap->countrySupported[0] = wifi_countrycode_US;
14884 rcap->countrySupported[1] = wifi_countrycode_CA;
14885 } else if (!strcmp(output_string,"CA")) {
14886 rcap->countrySupported[0] = wifi_countrycode_CA;
14887 rcap->countrySupported[1] = wifi_countrycode_US;
14888 } else {
14889 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
14890 }
14891
14892 rcap->numcountrySupported = 2;
14893
14894 /* csi */
14895 rcap->csi.maxDevices = 8;
14896 rcap->csi.soudingFrameSupported = TRUE;
14897
14898 wifi_GetInterfaceName(radioIndex, interface_name);
14899 snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
14900
14901 /* channelWidth - all supported bandwidths */
14902 int i=0;
14903 rcap->channelWidth[i] = 0;
14904 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
14905 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
14906 WIFI_CHANNELBANDWIDTH_40MHZ);
14907
14908 }
14909 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
14910 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
14911 WIFI_CHANNELBANDWIDTH_40MHZ |
14912 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
14913 }
14914
14915
14916 /* mode - all supported variants */
14917 // rcap->mode[i] = WIFI_80211_VARIANT_H;
14918 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
14919 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
14920 }
14921 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
14922 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
14923 }
14924 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
14925 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
14926 }
14927 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
14928 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
14929
14930 /* supportedBitRate - all supported bitrates */
14931 rcap->supportedBitRate[i] = 0;
14932 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
14933 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
14934 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
14935 }
14936 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) | rcap->band[i] & (WIFI_FREQUENCY_6_BAND )) {
14937 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
14938 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
14939 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
14940 }
14941
14942
14943 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
14944 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
14945 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
14946 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
14947 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
14948 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
14949 rcap->cipherSupported = 0;
14950 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
14951 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
14952
14953 return RETURN_OK;
14954}
14955
14956INT wifi_getHalCapability(wifi_hal_capability_t *cap)
14957{
14958 INT status = 0, radioIndex = 0;
14959 char cmd[MAX_BUF_SIZE] = {0}, output[MAX_BUF_SIZE] = {0};
14960 int iter = 0;
14961 unsigned int j = 0;
14962 int max_num_radios;
14963 wifi_interface_name_idex_map_t *iface_info = NULL;
14964
14965 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14966
14967 memset(cap, 0, sizeof(wifi_hal_capability_t));
14968
14969 /* version */
14970 cap->version.major = WIFI_HAL_MAJOR_VERSION;
14971 cap->version.minor = WIFI_HAL_MINOR_VERSION;
14972
14973 /* number of radios platform property */
14974 wifi_getMaxRadioNumber(&max_num_radios);
14975 cap->wifi_prop.numRadios = max_num_radios;
14976
14977 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
14978 {
14979 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
14980 if (status != 0) {
14981 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
14982 return RETURN_ERR;
14983 }
14984
14985 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
14986 {
14987 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
14988 {
14989 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
14990 return RETURN_ERR;
14991 }
14992 iface_info = &cap->wifi_prop.interface_map[iter];
14993 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
14994 iface_info->rdk_radio_index = radioIndex;
14995 memset(output, 0, sizeof(output));
14996 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
14997 {
14998 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
14999 }
15000 // TODO: bridge name
15001 // TODO: vlan id
15002 // TODO: primary
15003 iface_info->index = array_index_to_vap_index(radioIndex, j);
15004 memset(output, 0, sizeof(output));
15005 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
15006 {
15007 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
15008 }
15009 iter++;
15010 }
15011 }
15012
15013 cap->BandSteeringSupported = FALSE;
15014 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15015 return RETURN_OK;
15016}
15017
15018INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
15019{
15020 struct params h_config={0};
15021 char config_file[64] = {0};
15022
15023 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15024
15025 h_config.name = "okc";
15026 h_config.value = okc_enable?"1":"0";
15027
15028 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15029 wifi_hostapdWrite(config_file, &h_config, 1);
15030 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15031
15032 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15033 return RETURN_OK;
15034}
15035
15036INT wifi_setSAEMFP(int ap_index, BOOL enable)
15037{
15038 struct params h_config={0};
15039 char config_file[64] = {0};
15040 char buf[128] = {0};
15041
15042 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15043
15044 h_config.name = "sae_require_mfp";
15045 h_config.value = enable?"1":"0";
15046
15047 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15048 wifi_hostapdWrite(config_file, &h_config, 1);
15049 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15050
15051 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15052 return RETURN_OK;
15053}
15054
15055INT wifi_setSAEpwe(int ap_index, int sae_pwe)
15056{
15057 struct params h_config={0};
15058 char config_file[64] = {0};
15059 char buf[128] = {0};
15060
15061 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15062
15063 h_config.name = "sae_pwe";
15064 snprintf(buf, sizeof(buf), "%d", sae_pwe);
15065 h_config.value = buf;
15066
15067 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15068 wifi_hostapdWrite(config_file, &h_config, 1);
15069 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15070
15071 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15072 return RETURN_OK;
15073}
15074
15075INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
15076{
15077 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
15078 struct params h_config={0};
15079 char config_file[64] = {0};
15080
15081 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15082
15083 h_config.name = "wpa_disable_eapol_key_retries";
15084 h_config.value = disable_EAPOL_retries?"1":"0";
15085
15086 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15087 wifi_hostapdWrite(config_file, &h_config, 1);
15088 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15089
15090 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15091 return RETURN_OK;
15092}
15093
15094INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
15095{
15096 char buf[128] = {0};
15097 char config_file[128] = {0};
developere5750452023-05-15 16:46:42 +080015098 char cmd[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015099 char password[64] = {0};
15100 char mfp[32] = {0};
15101 char wpa_mode[32] = {0};
15102 BOOL okc_enable = FALSE;
15103 BOOL sae_MFP = FALSE;
15104 BOOL disable_EAPOL_retries = TRUE;
15105 int sae_pwe = 0;
15106 struct params params = {0};
15107 wifi_band band = band_invalid;
15108
15109 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15110
15111 multiple_set = TRUE;
15112 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15113 if (security->mode == wifi_security_mode_none) {
15114 strcpy(wpa_mode, "None");
15115 } else if (security->mode == wifi_security_mode_wpa_personal)
15116 strcpy(wpa_mode, "WPA-Personal");
15117 else if (security->mode == wifi_security_mode_wpa2_personal)
15118 strcpy(wpa_mode, "WPA2-Personal");
15119 else if (security->mode == wifi_security_mode_wpa_wpa2_personal)
15120 strcpy(wpa_mode, "WPA-WPA2-Personal");
15121 else if (security->mode == wifi_security_mode_wpa_enterprise)
15122 strcpy(wpa_mode, "WPA-Enterprise");
15123 else if (security->mode == wifi_security_mode_wpa2_enterprise)
15124 strcpy(wpa_mode, "WPA2-Enterprise");
15125 else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise)
15126 strcpy(wpa_mode, "WPA-WPA2-Enterprise");
15127 else if (security->mode == wifi_security_mode_wpa3_personal) {
15128 strcpy(wpa_mode, "WPA3-Personal");
15129 okc_enable = TRUE;
15130 sae_MFP = TRUE;
15131 sae_pwe = 2;
15132 disable_EAPOL_retries = FALSE;
15133 } else if (security->mode == wifi_security_mode_wpa3_transition) {
15134 strcpy(wpa_mode, "WPA3-Personal-Transition");
15135 okc_enable = TRUE;
15136 sae_MFP = TRUE;
15137 sae_pwe = 2;
15138 disable_EAPOL_retries = FALSE;
15139 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
15140 strcpy(wpa_mode, "WPA3-Enterprise");
15141 sae_MFP = TRUE;
15142 sae_pwe = 2;
15143 disable_EAPOL_retries = FALSE;
developerd01e3e82023-04-26 19:10:38 +080015144 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer3086e2f2023-01-17 09:40:01 +080015145 strcpy(wpa_mode, "OWE");
15146 sae_MFP = TRUE;
15147 sae_pwe = 2;
15148 disable_EAPOL_retries = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015149 }
15150
15151 band = wifi_index_to_band(ap_index);
15152 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
15153 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
15154 return RETURN_ERR;
15155 }
15156
15157 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
15158 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
15159 wifi_setSAEMFP(ap_index, sae_MFP);
15160 wifi_setSAEpwe(ap_index, sae_pwe);
15161 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
15162
developerd01e3e82023-04-26 19:10:38 +080015163 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
developere5750452023-05-15 16:46:42 +080015164 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) {
15165 int key_len = strlen(security->u.key.key);
15166 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
15167 if (key_len == 64) { // set wpa_psk
15168 strncpy(password, security->u.key.key, 64); // 64 characters
15169 password[64] = '\0';
15170 wifi_setApSecurityPreSharedKey(ap_index, password);
15171 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
15172 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
15173 strncpy(password, security->u.key.key, 63);
15174 password[63] = '\0';
15175 wifi_setApSecurityKeyPassphrase(ap_index, password);
15176 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
15177 } else
15178 return RETURN_ERR;
15179 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015180 }
15181 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
15182 params.name = "sae_password";
15183 params.value = security->u.key.key;
15184 wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +080015185 } else { // remove sae_password
15186 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
15187 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015188 }
15189 }
15190
15191 if (security->mode != wifi_security_mode_none) {
15192 memset(&params, 0, sizeof(params));
15193 params.name = "wpa_pairwise";
15194 if (security->encr == wifi_encryption_tkip)
15195 params.value = "TKIP";
15196 else if (security->encr == wifi_encryption_aes)
15197 params.value = "CCMP";
15198 else if (security->encr == wifi_encryption_aes_tkip)
15199 params.value = "TKIP CCMP";
15200 wifi_hostapdWrite(config_file, &params, 1);
15201 }
15202
15203 if (security->mfp == wifi_mfp_cfg_disabled)
15204 strcpy(mfp, "Disabled");
15205 else if (security->mfp == wifi_mfp_cfg_optional)
15206 strcpy(mfp, "Optional");
15207 else if (security->mfp == wifi_mfp_cfg_required)
15208 strcpy(mfp, "Required");
15209 wifi_setApSecurityMFPConfig(ap_index, mfp);
15210
15211 memset(&params, 0, sizeof(params));
15212 params.name = "transition_disable";
15213 if (security->wpa3_transition_disable == TRUE)
15214 params.value = "0x01";
15215 else
15216 params.value = "0x00";
15217 wifi_hostapdWrite(config_file, &params, 1);
15218
15219 memset(&params, 0, sizeof(params));
15220 params.name = "wpa_group_rekey";
15221 snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
15222 params.value = buf;
15223 wifi_hostapdWrite(config_file, &params, 1);
15224
15225 memset(&params, 0, sizeof(params));
15226 params.name = "wpa_strict_rekey";
15227 params.value = security->strict_rekey?"1":"0";
15228 wifi_hostapdWrite(config_file, &params, 1);
15229
15230 memset(&params, 0, sizeof(params));
15231 params.name = "wpa_pairwise_update_count";
developere5750452023-05-15 16:46:42 +080015232 if (security->eapol_key_retries == 0)
15233 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developer72fb0bb2023-01-11 09:46:29 +080015234 snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
15235 params.value = buf;
15236 wifi_hostapdWrite(config_file, &params, 1);
15237
15238 memset(&params, 0, sizeof(params));
15239 params.name = "disable_pmksa_caching";
15240 params.value = security->disable_pmksa_caching?"1":"0";
15241 wifi_hostapdWrite(config_file, &params, 1);
15242
developer23e71282023-01-18 10:25:19 +080015243 if (multiple_set == FALSE) {
15244 wifi_setApEnable(ap_index, FALSE);
15245 wifi_setApEnable(ap_index, TRUE);
15246 }
developer72fb0bb2023-01-11 09:46:29 +080015247
15248 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15249
15250 return RETURN_OK;
15251}
15252
15253INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
15254{
15255 char buf[256] = {0};
15256 char config_file[128] = {0};
15257 int disable = 0;
developere5750452023-05-15 16:46:42 +080015258 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015259
15260 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15261 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15262 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
15263 security->mode = wifi_security_mode_none;
15264 if (strlen(buf) != 0) {
15265 if (!strcmp(buf, "WPA-Personal"))
15266 security->mode = wifi_security_mode_wpa_personal;
15267 else if (!strcmp(buf, "WPA2-Personal"))
15268 security->mode = wifi_security_mode_wpa2_personal;
15269 else if (!strcmp(buf, "WPA-WPA2-Personal"))
15270 security->mode = wifi_security_mode_wpa_wpa2_personal;
15271 else if (!strcmp(buf, "WPA-Enterprise"))
15272 security->mode = wifi_security_mode_wpa_enterprise;
15273 else if (!strcmp(buf, "WPA2-Enterprise"))
15274 security->mode = wifi_security_mode_wpa2_enterprise;
15275 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
15276 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
15277 else if (!strcmp(buf, "WPA3-Personal"))
15278 security->mode = wifi_security_mode_wpa3_personal;
15279 else if (!strcmp(buf, "WPA3-Personal-Transition"))
15280 security->mode = wifi_security_mode_wpa3_transition;
15281 else if (!strcmp(buf, "WPA3-Enterprise"))
15282 security->mode = wifi_security_mode_wpa3_enterprise;
developer3086e2f2023-01-17 09:40:01 +080015283 else if (!strcmp(buf, "OWE"))
developerd01e3e82023-04-26 19:10:38 +080015284 security->mode = wifi_security_mode_enhanced_open;
developer72fb0bb2023-01-11 09:46:29 +080015285 }
15286
15287 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
15288 if (security->mode == wifi_security_mode_none)
15289 security->encr = wifi_encryption_none;
15290 else {
15291 if (strcmp(buf, "TKIP") == 0)
15292 security->encr = wifi_encryption_tkip;
15293 else if (strcmp(buf, "CCMP") == 0)
15294 security->encr = wifi_encryption_aes;
15295 else
15296 security->encr = wifi_encryption_aes_tkip;
15297 }
15298
15299 if (security->mode != wifi_encryption_none) {
15300 memset(buf, 0, sizeof(buf));
15301 // wpa3 can use one or both configs as password, so we check sae_password first.
15302 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
developere5750452023-05-15 16:46:42 +080015303 if (strlen(buf) != 0) {
15304 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
15305 security->u.key.type = wifi_security_key_type_sae;
15306 set_sae = TRUE;
15307 strncpy(security->u.key.key, buf, sizeof(buf));
15308 }
15309 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
15310 if (strlen(buf) != 0){
15311 if (set_sae == TRUE)
15312 security->u.key.type = wifi_security_key_type_psk_sae;
15313 else if (strlen(buf) == 64)
15314 security->u.key.type = wifi_security_key_type_psk;
15315 else
15316 security->u.key.type = wifi_security_key_type_pass;
15317 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
developer72fb0bb2023-01-11 09:46:29 +080015318 }
developer72fb0bb2023-01-11 09:46:29 +080015319 security->u.key.key[255] = '\0';
15320 }
15321
15322 memset(buf, 0, sizeof(buf));
15323 wifi_getApSecurityMFPConfig(ap_index, buf);
15324 if (strcmp(buf, "Disabled") == 0)
15325 security->mfp = wifi_mfp_cfg_disabled;
15326 else if (strcmp(buf, "Optional") == 0)
15327 security->mfp = wifi_mfp_cfg_optional;
15328 else if (strcmp(buf, "Required") == 0)
15329 security->mfp = wifi_mfp_cfg_required;
15330
15331 memset(buf, 0, sizeof(buf));
15332 security->wpa3_transition_disable = FALSE;
15333 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
15334 disable = strtol(buf, NULL, 16);
15335 if (disable != 0)
15336 security->wpa3_transition_disable = TRUE;
15337
15338 memset(buf, 0, sizeof(buf));
15339 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
15340 if (strlen(buf) == 0)
15341 security->rekey_interval = 86400;
15342 else
15343 security->rekey_interval = strtol(buf, NULL, 10);
15344
15345 memset(buf, 0, sizeof(buf));
15346 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
15347 if (strlen(buf) == 0)
15348 security->strict_rekey = 1;
15349 else
15350 security->strict_rekey = strtol(buf, NULL, 10);
15351
15352 memset(buf, 0, sizeof(buf));
15353 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
15354 if (strlen(buf) == 0)
15355 security->eapol_key_retries = 4;
15356 else
15357 security->eapol_key_retries = strtol(buf, NULL, 10);
15358
15359 memset(buf, 0, sizeof(buf));
15360 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
15361 if (strlen(buf) == 0)
15362 security->disable_pmksa_caching = FALSE;
15363 else
15364 security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE;
15365
15366 /* TODO
15367 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
15368 */
15369 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
15370 security->eap_identity_req_timeout = 0;
15371 security->eap_identity_req_retries = 0;
15372 security->eap_req_timeout = 0;
15373 security->eap_req_retries = 0;
15374 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15375 return RETURN_OK;
15376}
15377
15378#endif /* WIFI_HAL_VERSION_3 */
15379
15380#ifdef WIFI_HAL_VERSION_3_PHASE2
15381INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
15382{
15383 char interface_name[16] = {0};
15384 char cmd[128] = {0};
15385 char buf[128] = {0};
15386 char *mac_addr = NULL;
15387 BOOL status = FALSE;
15388 size_t len = 0;
15389
15390 if(ap_index > MAX_APS)
15391 return RETURN_ERR;
15392
15393 *output_numDevices = 0;
15394 wifi_getApEnable(ap_index, &status);
15395 if (status == FALSE)
15396 return RETURN_OK;
15397
15398 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
15399 return RETURN_ERR;
15400 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
15401 _syscmd(cmd, buf, sizeof(buf));
15402
15403 mac_addr = strtok(buf, "\n");
15404 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
15405 *output_numDevices = i + 1;
15406 fprintf(stderr, "mac_addr: %s\n", mac_addr);
15407 addr_ptr = output_deviceMacAddressArray[i];
15408 mac_addr_aton(addr_ptr, mac_addr);
15409 mac_addr = strtok(NULL, "\n");
15410 }
15411
15412 return RETURN_OK;
15413}
15414#else
15415INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
15416{
15417 char interface_name[16] = {0};
15418 char cmd[128];
15419 BOOL status = false;
15420
15421 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
15422 return RETURN_ERR;
15423
15424 output_buf[0] = '\0';
15425
15426 wifi_getApEnable(ap_index,&status);
15427 if (!status)
15428 return RETURN_OK;
15429
15430 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
15431 return RETURN_ERR;
15432 sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
15433 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080015434
developer72fb0bb2023-01-11 09:46:29 +080015435 return RETURN_OK;
15436}
15437#endif
15438
15439INT wifi_getProxyArp(INT apIndex, BOOL *enable)
15440{
15441 char output[16]={'\0'};
15442 char config_file[MAX_BUF_SIZE] = {0};
15443
15444 if (!enable)
15445 return RETURN_ERR;
15446
15447 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
15448 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
15449
15450 if (strlen(output) == 0)
15451 *enable = FALSE;
15452 else if (strncmp(output, "1", 1) == 0)
15453 *enable = TRUE;
15454 else
15455 *enable = FALSE;
15456
15457 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
15458 return RETURN_OK;
15459}
15460
15461INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
15462{
15463 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
15464 return RETURN_ERR;
15465 *output_enable=TRUE;
15466 return RETURN_OK;
15467}
15468
15469INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
15470{
15471 char cmd[128] = {0};
15472 char buf[128] = {0};
15473 char line[128] = {0};
15474 size_t len = 0;
15475 FILE *f = NULL;
15476 int index = 0;
15477 int exp = 0;
15478 int mantissa = 0;
15479 int duration = 0;
15480 int radio_index = 0;
15481 int max_radio_num = 0;
15482 uint twt_wake_interval = 0;
15483 int phyId = 0;
15484 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15485
15486 wifi_getMaxRadioNumber(&max_radio_num);
15487
15488 radio_index = ap_index % max_radio_num;
15489
15490 phyId = radio_index_to_phy(radio_index);
15491 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
15492 _syscmd(cmd, buf, sizeof(buf));
15493 *numSessionReturned = strtol(buf, NULL, 10) - 1;
15494 if (*numSessionReturned > maxNumberSessions)
15495 *numSessionReturned = maxNumberSessions;
15496 else if (*numSessionReturned < 1) {
15497 *numSessionReturned = 0;
15498 return RETURN_OK;
15499 }
15500
15501 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
15502 if ((f = popen(cmd, "r")) == NULL) {
15503 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
15504 return RETURN_ERR;
15505 }
15506
15507 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
15508 while((fgets(line, sizeof(line), f)) != NULL) {
15509 char *tmp = NULL;
15510 strcpy(buf, line);
15511 tmp = strtok(buf, " ");
15512 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
15513 tmp = strtok(NULL, " ");
15514 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
15515 tmp = strtok(NULL, " ");
15516 if (strstr(tmp, "t")) {
15517 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
15518 }
15519 if (strstr(tmp, "a")) {
15520 twtSessions[index].twtParameters.operation.announced = TRUE;
15521 }
15522 tmp = strtok(NULL, " ");
15523 exp = strtol(tmp, NULL, 10);
15524 tmp = strtok(NULL, " ");
15525 mantissa = strtol(tmp, NULL, 10);
15526 tmp = strtok(NULL, " ");
15527 duration = strtol(tmp, NULL, 10);
15528
15529 // only implicit supported
15530 twtSessions[index].twtParameters.operation.implicit = TRUE;
15531 // only individual agreement supported
15532 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
15533
15534 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
15535 twt_wake_interval = mantissa * (1 << exp);
15536 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
15537 // Overflow handling
15538 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
15539 } else {
15540 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
15541 }
15542 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
15543 index++;
15544 }
15545
15546 pclose(f);
15547 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15548 return RETURN_OK;
15549}