blob: 4fe7e3c8656bef1659768dac1dc547c1ea7829de [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:
developera3511852023-06-14 14:12:59 +080031Copyright (c) 2007, 2008 Johannes Berg
32Copyright (c) 2007 Andy Lutomirski
33Copyright (c) 2007 Mike Kershaw
34Copyright (c) 2008-2009 Luis R. Rodriguez
developer72fb0bb2023-01-11 09:46:29 +080035Licensed 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>
developercc5cbfb2023-06-13 18:29:52 +080066
67#include <sys/socket.h>
68#include <sys/ioctl.h>
69#include <arpa/inet.h>
70#include <linux/if.h>
71#include <linux/if_bridge.h>
72#include <linux/sockios.h>
developer86035662023-06-28 19:21:12 +080073#include <errno.h>
74#include <limits.h>
developercc5cbfb2023-06-13 18:29:52 +080075
developer72fb0bb2023-01-11 09:46:29 +080076#define MAC_ALEN 6
77
78#define MAX_BUF_SIZE 256
79#define MAX_CMD_SIZE 256
developerb149d9d2023-06-06 16:14:22 +080080#define MAX_SUB_CMD_SIZE 200
81
developer72fb0bb2023-01-11 09:46:29 +080082#define IF_NAME_SIZE 16
83#define CONFIG_PREFIX "/nvram/hostapd"
84#define ACL_PREFIX "/nvram/hostapd-acl"
85#define DENY_PREFIX "/nvram/hostapd-deny"
86//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
87#define SOCK_PREFIX "/var/run/hostapd/wifi"
88#define VAP_STATUS_FILE "/nvram/vap-status"
89#define ESSID_FILE "/tmp/essid"
90#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
91#define CHANNEL_STATS_FILE "/tmp/channel_stats"
92#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
93#define VLAN_FILE "/nvram/hostapd.vlan"
94#define PSK_FILE "/nvram/hostapd"
95#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080096#define POWER_PERCENTAGE "/tmp/POWER"
97#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
98/*LOGAN_DAT_FILE: may be different on customer's platform.*/
99#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +0800100#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +0800101
developer72fb0bb2023-01-11 09:46:29 +0800102#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +0800103#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +0800104
developer72fb0bb2023-01-11 09:46:29 +0800105#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +0800106#define BASE_PHY_INDEX 1
107#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +0800108
109/*
110 MAX_APS - Number of all AP available in system
111 2x Home AP
112 2x Backhaul AP
113 2x Guest AP
114 2x Secure Onboard AP
115 2x Service AP
116
117*/
118
119
120#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800121
122#define PREFIX_WIFI2G "ra"
123#define PREFIX_WIFI5G "rai"
124#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800125
developer47cc27a2023-05-17 23:09:58 +0800126#define PREFIX_SSID_2G "RDKB_2G"
127#define PREFIX_SSID_5G "RDKB_5G"
128#define PREFIX_SSID_6G "RDKB_6G"
129
developer72fb0bb2023-01-11 09:46:29 +0800130#ifndef RADIO_PREFIX
131#define RADIO_PREFIX "wlan"
132#endif
133
134#define MAX_ASSOCIATED_STA_NUM 2007
135
136//Uncomment to enable debug logs
137//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800138enum {
139 DEBUG_OFF = 0,
140 DEBUG_ERROR = 1,
141 DEBUG_WARN = 2,
142 DEBUG_NOTICE = 3,
143 DEBUG_INFO = 4
144};
145int wifi_debug_level = DEBUG_NOTICE;
146#define wifi_debug(level, fmt, args...) \
147{ \
148 if (level <= wifi_debug_level) \
149 { \
developer2edaf012023-05-24 14:24:53 +0800150 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800151 } \
152}
developer72fb0bb2023-01-11 09:46:29 +0800153
154#ifdef WIFI_DEBUG
155#define wifi_dbg_printf printf
156#define WIFI_ENTRY_EXIT_DEBUG printf
157#else
developer2f79c922023-06-02 17:33:42 +0800158#define wifi_dbg_printf(format, args...)
159#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
developer72fb0bb2023-01-11 09:46:29 +0800160#endif
161
162#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
163#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
164#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
165#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
166#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
167#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
168#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
169#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
170#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
171#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
172
173#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
174
175#define BW_FNAME "/nvram/bw_file.txt"
176
177#define PS_MAX_TID 16
178
developer96b38512023-02-22 11:17:45 +0800179#define MAX_CARD_INDEX 3
180
developer72fb0bb2023-01-11 09:46:29 +0800181static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
developera3511852023-06-14 14:12:59 +0800182 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
183 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
184 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
185 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
186 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
187 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
188 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
189 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
190 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
191 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
192 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
193 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
194 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
195 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
196 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
197 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
developer72fb0bb2023-01-11 09:46:29 +0800198};
199
200typedef unsigned long long u64;
201
202/* Enum to define WiFi Bands */
203typedef enum
204{
developera3511852023-06-14 14:12:59 +0800205 band_invalid = -1,
206 band_2_4 = 0,
207 band_5 = 1,
208 band_6 = 2,
developer72fb0bb2023-01-11 09:46:29 +0800209} wifi_band;
210
developer17038e62023-03-02 14:43:43 +0800211char* wifi_band_str[] = {
developera3511852023-06-14 14:12:59 +0800212 "2G",
213 "5G",
214 "6G",
developer17038e62023-03-02 14:43:43 +0800215};
216
developer72fb0bb2023-01-11 09:46:29 +0800217typedef enum {
developera3511852023-06-14 14:12:59 +0800218 WIFI_MODE_A = 0x01,
219 WIFI_MODE_B = 0x02,
220 WIFI_MODE_G = 0x04,
221 WIFI_MODE_N = 0x08,
222 WIFI_MODE_AC = 0x10,
223 WIFI_MODE_AX = 0x20,
224 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800225} wifi_ieee80211_Mode;
226
developer2f79c922023-06-02 17:33:42 +0800227typedef enum {
developera3511852023-06-14 14:12:59 +0800228 HT_BW_20,
229 HT_BW_40,
developer2f79c922023-06-02 17:33:42 +0800230} ht_config_bw;
developerd1824452023-05-18 12:30:04 +0800231
developer2f79c922023-06-02 17:33:42 +0800232typedef enum {
developera3511852023-06-14 14:12:59 +0800233 VHT_BW_2040,
234 VHT_BW_80,
235 VHT_BW_160,
236 VHT_BW_8080,
developer2f79c922023-06-02 17:33:42 +0800237} vht_config_bw;
developerd1824452023-05-18 12:30:04 +0800238
developer2f79c922023-06-02 17:33:42 +0800239typedef enum {
developera3511852023-06-14 14:12:59 +0800240 EHT_BW_20,
241 EHT_BW_40,
242 EHT_BW_80,
243 EHT_BW_160,
244 EHT_BW_320,
developer2f79c922023-06-02 17:33:42 +0800245} eht_config_bw;
developerd1824452023-05-18 12:30:04 +0800246
developer72fb0bb2023-01-11 09:46:29 +0800247#ifdef WIFI_HAL_VERSION_3
248
249// Return number of elements in array
250#ifndef ARRAY_SIZE
developera3511852023-06-14 14:12:59 +0800251#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
developer72fb0bb2023-01-11 09:46:29 +0800252#endif /* ARRAY_SIZE */
253
254#ifndef ARRAY_AND_SIZE
developera3511852023-06-14 14:12:59 +0800255#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
developer72fb0bb2023-01-11 09:46:29 +0800256#endif /* ARRAY_AND_SIZE */
257
developera3511852023-06-14 14:12:59 +0800258#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
developer72fb0bb2023-01-11 09:46:29 +0800259
260typedef struct {
developera3511852023-06-14 14:12:59 +0800261 int32_t value;
262 int32_t param;
263 intptr_t key;
264 intptr_t data;
developer72fb0bb2023-01-11 09:46:29 +0800265} wifi_secur_list;
266
developer0155a502023-06-19 20:33:57 +0800267typedef struct GNU_PACKED _wdev_extended_ap_metrics {
268 unsigned int uc_tx;
269 unsigned int uc_rx;
270 unsigned int mc_tx;
271 unsigned int mc_rx;
272 unsigned int bc_tx;
273 unsigned int bc_rx;
274} wdev_extended_ap_metric;
275
276typedef struct GNU_PACKED _wdev_ap_metric {
277 unsigned char bssid[6];
278 unsigned char cu;
279 unsigned char ESPI_AC[4][3];
280 wdev_extended_ap_metric ext_ap_metric;
281} wdev_ap_metric;
282
283
developer72fb0bb2023-01-11 09:46:29 +0800284static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
285static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
developera3511852023-06-14 14:12:59 +0800286wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
287wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
288char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
developer72fb0bb2023-01-11 09:46:29 +0800289static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developerd14dff12023-06-28 22:47:44 +0800290static void wifi_PrepareDefaultHostapdConfigs(bool reset);
developer47cc27a2023-05-17 23:09:58 +0800291static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800292static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800293static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer2f79c922023-06-02 17:33:42 +0800294int hostapd_raw_add_bss(int apIndex);
295int hostapd_raw_remove_bss(int apIndex);
developerd14dff12023-06-28 22:47:44 +0800296INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size);
297
developer86035662023-06-28 19:21:12 +0800298static inline int hal_strtol(char *src, int base, long int *out)
299{
300 long int res = 0;
301 char *end_ptr = NULL;
302
303 errno = 0;
304 res = strtol(src, &end_ptr, base);
305
306 if ((errno == ERANGE && (res == LONG_MIN || res == LONG_MAX))
developer5fbf2ff2023-06-30 10:51:56 +0800307 || (errno != 0 && res == 0) || /*ignore end_ptr!=0 error*/ /**end_ptr != '\0' ||*/src == end_ptr ) {
308 *out = res;
developer86035662023-06-28 19:21:12 +0800309 return -1;
developer5fbf2ff2023-06-30 10:51:56 +0800310 } else
developer86035662023-06-28 19:21:12 +0800311 *out = res;
312
313 return 0;
314}
315
316static inline int hal_strtoul(char *src, int base, unsigned long *out)
317{
318 unsigned long res = 0;
319 char *end_ptr = NULL;
320
321 errno = 0;
322 res = strtoul(src, &end_ptr, base);
323
324 if ((errno == ERANGE && res == ULONG_MAX)
developer5fbf2ff2023-06-30 10:51:56 +0800325 || (errno != 0 && res == 0) || /*ignore end_ptr!=0 error*/ /**end_ptr != '\0' ||*/src == end_ptr ) {
326 *out = res;
developer86035662023-06-28 19:21:12 +0800327 return -1;
developer5fbf2ff2023-06-30 10:51:56 +0800328 } else
developer86035662023-06-28 19:21:12 +0800329 *out = res;
330
331 return 0;
332}
developer47cc27a2023-05-17 23:09:58 +0800333
developercc5cbfb2023-06-13 18:29:52 +0800334static inline int os_snprintf_error(size_t size, int res)
335{
336 return res < 0 || (unsigned int) res >= size;
337}
338
developer49b17232023-05-19 16:35:19 +0800339/*type define the nl80211 call back func*/
340typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
341
342/**
343*struct mtk_nl80211_param
344* init mtk nl80211 using parameters
345* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
346* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
347* @if_idx: the index should match the interface or wiphy.
348* Note: NA
349**/
350struct mtk_nl80211_param {
351 unsigned int sub_cmd;
352 int if_type;
353 int if_idx;
354};
355
356/**
developer121a8e72023-05-22 09:19:39 +0800357*struct mtk_nl80211_cb_data
358* init mtk nl80211 call back parameters
359* @out_buf: store the mtk vendor output msg for wifi hal buffer.
360* @out_len: the output buffer length.
361* Note: NA
362**/
363struct mtk_nl80211_cb_data {
364 char * out_buf;
365 unsigned int out_len;
366};
367
368/**
developer49b17232023-05-19 16:35:19 +0800369*mtk_nl80211_init
370* init mtk nl80211 netlink and init the vendor msg common part.
371* @nl: netlink, just init it.
372* @msg: netlink message will alloc it.
373* the msg send success/fails is not free by app
374* only the nla_put etc api fails should use nlmsg_free.
375* @msg_data: vendor data msg attr pointer.
376* @param: init using interface and sub_cmd parameter.
377*
378*init the netlink context and mtk netlink vendor msg.
379*
380*return:
381* 0: success
382* other: fail
383**/
384
385int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
386 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
387 /*sanity check here*/
388 if (!nl || !param) {
389 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800390 "[%s][%d]:nl(%p) or param(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800391 __func__, __LINE__, nl, param);
392 return -1;
393 }
394 /*if_type check*/
395 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
396 (void)fprintf(stderr,
397 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
398 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
399 return -1;
400 }
401 /*init the nl*/
402 if (unl_genl_init(nl, "nl80211") < 0) {
403 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
404 __func__, __LINE__);
405 return -1;
406 }
407 /*init the msg*/
408 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
409
410 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
developera3511852023-06-14 14:12:59 +0800411 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
412 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
developer49b17232023-05-19 16:35:19 +0800413 (void)fprintf(stderr,
414 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
415 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
416 goto err;
417 }
418
419 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
420 if (!*msg_data) {
421 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
422 __func__, __LINE__);
423 goto err;
424 }
425
426 return 0;
427err:
developer49b17232023-05-19 16:35:19 +0800428 nlmsg_free(*msg);
429 unl_free(nl);
430 return -1;
431}
432
433/**
434*mtk_nl80211_send
435* set the vendor cmd call back and sent the vendor msg.
436* @nl: netlink.
437* @msg: netlink message.
438* @msg_data: vendor data msg attr pointer.
439* @handler: if the msg have call back shoud add the call back func
440* the event msg will handle by the call back func(exp:get cmd)
441* other set it as NULL(exp:set cmd).
442* @arg:call back func arg parameter.
443*add end of the netlink msg, set the call back and send msg
444*
445*return:
446* 0: success
447* other: fail
448**/
449int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
450 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
451 int ret = 0;
452 /*sanity check*/
453 if (!nl || !msg || !msg_data) {
454 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800455 "[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800456 __func__, __LINE__, nl, msg, msg_data);
457 return -1;
458 }
459 /*end the msg attr of vendor data*/
460 nla_nest_end(msg, msg_data);
461 /*send the msg and set call back */
462 ret = unl_genl_request(nl, msg, handler, arg);
463 if (ret)
464 (void)fprintf(stderr, "send nl80211 cmd fails\n");
465 return ret;
466}
467
468/**
469*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800470* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800471* @nl: netlink.
472*
developer2edaf012023-05-24 14:24:53 +0800473*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800474*
475*return:
476* 0: success
477**/
478
479int mtk_nl80211_deint(struct unl *nl) {
480 unl_free(nl);
481 return 0;
482}
483
developer72fb0bb2023-01-11 09:46:29 +0800484wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
485{
developera3511852023-06-14 14:12:59 +0800486 wifi_secur_list *item;
487 int i;
developer72fb0bb2023-01-11 09:46:29 +0800488
developera3511852023-06-14 14:12:59 +0800489 for (item = list,i = 0;i < list_sz; item++, i++) {
490 if ((int)(item->key) == key) {
491 return item;
492 }
493 }
developer72fb0bb2023-01-11 09:46:29 +0800494
developera3511852023-06-14 14:12:59 +0800495 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800496}
497
498char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
499{
developera3511852023-06-14 14:12:59 +0800500 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
developer72fb0bb2023-01-11 09:46:29 +0800501
developera3511852023-06-14 14:12:59 +0800502 if (!item) {
503 return "";
504 }
developer72fb0bb2023-01-11 09:46:29 +0800505
developera3511852023-06-14 14:12:59 +0800506 return (char *)(item->data);
developer72fb0bb2023-01-11 09:46:29 +0800507}
508
509wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
510{
developera3511852023-06-14 14:12:59 +0800511 wifi_secur_list *item;
512 int i;
developer72fb0bb2023-01-11 09:46:29 +0800513
developera3511852023-06-14 14:12:59 +0800514 for (item = list,i = 0;i < list_sz; item++, i++) {
515 if (strcmp((char *)(item->data), str) == 0) {
516 return item;
517 }
518 }
developer72fb0bb2023-01-11 09:46:29 +0800519
developera3511852023-06-14 14:12:59 +0800520 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800521}
522#endif /* WIFI_HAL_VERSION_3 */
523
developer96b38512023-02-22 11:17:45 +0800524
525static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800526char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
527char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
528#define MAX_SSID_LEN 64
529char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800530int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800531
532static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
533static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
534
developer96b38512023-02-22 11:17:45 +0800535
536static int
537get_value(const char *conf_file, const char *param, char *value, int len)
538{
developera3511852023-06-14 14:12:59 +0800539 FILE *fp;
540 int ret = -1;
541 int param_len = strlen(param);
542 int buf_len;
developer86035662023-06-28 19:21:12 +0800543 char buf[256] = {0};
developer96b38512023-02-22 11:17:45 +0800544
developera3511852023-06-14 14:12:59 +0800545 fp = fopen(conf_file, "r");
546 if (!fp) {
547 return -1;
548 }
developer96b38512023-02-22 11:17:45 +0800549
developera3511852023-06-14 14:12:59 +0800550 while (fgets(buf, sizeof(buf), fp)) {
551 buf_len = strlen(buf);
developer86035662023-06-28 19:21:12 +0800552 if (buf_len == 0) {
553 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +0800554 if (fclose(fp) != 0) {
555 wifi_debug(DEBUG_ERROR, "fclose fail\n");
556 }
developer86035662023-06-28 19:21:12 +0800557 return RETURN_ERR;
558 }
developera3511852023-06-14 14:12:59 +0800559 if (buf[buf_len - 1] == '\n') {
560 buf_len--;
561 buf[buf_len] = '\0';
562 }
563 if ((buf_len > param_len) &&
564 (strncmp(buf, param, param_len) == 0) &&
565 (buf[param_len] == '=')) {
developer96b38512023-02-22 11:17:45 +0800566
developera3511852023-06-14 14:12:59 +0800567 if (buf_len == (param_len + 1)) {
568 value[0] = '\0';
569 ret = 0;
570 } else {
571 ret = snprintf(value, len, "%s", buf + (param_len + 1));
developer75bd10c2023-06-27 11:34:08 +0800572 if (os_snprintf_error(len, ret)) {
573 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
574 }
developera3511852023-06-14 14:12:59 +0800575 }
developerd14dff12023-06-28 22:47:44 +0800576 if (fclose(fp) != 0) {
577 ret = -1;
578 wifi_debug(DEBUG_ERROR, "fclose fail\n");
579 }
developera3511852023-06-14 14:12:59 +0800580 return ret;
581 }
582 }
developer37646972023-06-29 10:58:43 +0800583 if (fclose(fp) == EOF){
584 wifi_debug(DEBUG_ERROR, "fclose fail\n");
585 return RETURN_ERR;
586 }
developera3511852023-06-14 14:12:59 +0800587 return -1;
developer96b38512023-02-22 11:17:45 +0800588}
589
590static int
591get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
592{
developera3511852023-06-14 14:12:59 +0800593 char buf[256];
594 int ret;
595 char *save_ptr = NULL;
596 char *tok = NULL;
developer96b38512023-02-22 11:17:45 +0800597
developera3511852023-06-14 14:12:59 +0800598 ret = get_value(conf_file, param, buf, sizeof(buf));
599 if (ret < 0)
600 return ret;
developer96b38512023-02-22 11:17:45 +0800601
developera3511852023-06-14 14:12:59 +0800602 tok = strtok_r(buf, ";", &save_ptr);
603 do {
604 if (idx == 0 || tok == NULL)
605 break;
606 else
607 idx--;
developer96b38512023-02-22 11:17:45 +0800608
developera3511852023-06-14 14:12:59 +0800609 tok = strtok_r(NULL, ";", &save_ptr);
610 } while (tok != NULL);
developer96b38512023-02-22 11:17:45 +0800611
developera3511852023-06-14 14:12:59 +0800612 if (tok) {
613 ret = snprintf(value, len, "%s", tok);
developer75bd10c2023-06-27 11:34:08 +0800614 if (os_snprintf_error(len, ret)) {
615 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
616 return -1;
617 }
developera3511852023-06-14 14:12:59 +0800618 } else {
619 ret = 0;
620 value[0] = '\0';
621 }
developer96b38512023-02-22 11:17:45 +0800622
developera3511852023-06-14 14:12:59 +0800623 return ret;
developer96b38512023-02-22 11:17:45 +0800624}
625
626
developer72fb0bb2023-01-11 09:46:29 +0800627#ifdef HAL_NETLINK_IMPL
628typedef struct {
developera3511852023-06-14 14:12:59 +0800629 int id;
630 struct nl_sock* socket;
631 struct nl_cb* cb;
developer72fb0bb2023-01-11 09:46:29 +0800632} Netlink;
633
634static int mac_addr_aton(unsigned char *mac_addr, char *arg)
635{
developera3511852023-06-14 14:12:59 +0800636 unsigned char mac_addr_int[6]={};
developer75bd10c2023-06-27 11:34:08 +0800637 unsigned int recv;
638
639 recv = 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);
640
641 if (recv != 6) {
642 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
643 return -1;
644 }
developera3511852023-06-14 14:12:59 +0800645 mac_addr[0] = mac_addr_int[0];
646 mac_addr[1] = mac_addr_int[1];
647 mac_addr[2] = mac_addr_int[2];
648 mac_addr[3] = mac_addr_int[3];
649 mac_addr[4] = mac_addr_int[4];
650 mac_addr[5] = mac_addr_int[5];
651 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800652}
653
654static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
655{
developera3511852023-06-14 14:12:59 +0800656 unsigned int mac_addr_int[6]={};
developere40952c2023-06-15 18:46:43 +0800657 int res;
658
developera3511852023-06-14 14:12:59 +0800659 mac_addr_int[0] = arg[0];
660 mac_addr_int[1] = arg[1];
661 mac_addr_int[2] = arg[2];
662 mac_addr_int[3] = arg[3];
663 mac_addr_int[4] = arg[4];
664 mac_addr_int[5] = arg[5];
developere40952c2023-06-15 18:46:43 +0800665 res = 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]);
666 if (os_snprintf_error(20, res)) {
667 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
668 }
developera3511852023-06-14 14:12:59 +0800669 return;
developer72fb0bb2023-01-11 09:46:29 +0800670}
671
672static int ieee80211_frequency_to_channel(int freq)
673{
developera3511852023-06-14 14:12:59 +0800674 /* see 802.11-2007 17.3.8.3.2 and Annex J */
675 if (freq == 2484)
676 return 14;
677 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
678 else if (freq == 5935)
679 return 2;
680 else if (freq < 2484)
681 return (freq - 2407) / 5;
682 else if (freq >= 4910 && freq <= 4980)
683 return (freq - 4000) / 5;
684 else if (freq < 5950)
685 return (freq - 5000) / 5;
686 else if (freq <= 45000) /* DMG band lower limit */
687 /* see 802.11ax D6.1 27.3.23.2 */
688 return (freq - 5950) / 5;
689 else if (freq >= 58320 && freq <= 70200)
690 return (freq - 56160) / 2160;
691 else
692 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800693}
694
695static int initSock80211(Netlink* nl) {
developera3511852023-06-14 14:12:59 +0800696 nl->socket = nl_socket_alloc();
697 if (!nl->socket) {
developer75bd10c2023-06-27 11:34:08 +0800698 wifi_debug(DEBUG_ERROR, "Failing to allocate the sock\n");
developera3511852023-06-14 14:12:59 +0800699 return -ENOMEM;
700 }
developer72fb0bb2023-01-11 09:46:29 +0800701
developera3511852023-06-14 14:12:59 +0800702 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
developer72fb0bb2023-01-11 09:46:29 +0800703
developera3511852023-06-14 14:12:59 +0800704 if (genl_connect(nl->socket)) {
developer75bd10c2023-06-27 11:34:08 +0800705 wifi_debug(DEBUG_ERROR, "Failed to connect\n");
developera3511852023-06-14 14:12:59 +0800706 nl_close(nl->socket);
707 nl_socket_free(nl->socket);
708 return -ENOLINK;
709 }
developer72fb0bb2023-01-11 09:46:29 +0800710
developera3511852023-06-14 14:12:59 +0800711 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
712 if (nl->id< 0) {
developer75bd10c2023-06-27 11:34:08 +0800713 wifi_debug(DEBUG_ERROR, "interface not found.\n");
developera3511852023-06-14 14:12:59 +0800714 nl_close(nl->socket);
715 nl_socket_free(nl->socket);
716 return -ENOENT;
717 }
developer72fb0bb2023-01-11 09:46:29 +0800718
developera3511852023-06-14 14:12:59 +0800719 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
720 if ((!nl->cb)) {
developer75bd10c2023-06-27 11:34:08 +0800721 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink callback.\n");
developera3511852023-06-14 14:12:59 +0800722 nl_close(nl->socket);
723 nl_socket_free(nl->socket);
724 return ENOMEM;
725 }
developer72fb0bb2023-01-11 09:46:29 +0800726
developera3511852023-06-14 14:12:59 +0800727 return nl->id;
developer72fb0bb2023-01-11 09:46:29 +0800728}
729
730static int nlfree(Netlink *nl)
731{
developera3511852023-06-14 14:12:59 +0800732 nl_cb_put(nl->cb);
733 nl_close(nl->socket);
734 nl_socket_free(nl->socket);
735 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800736}
737
738static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
developera3511852023-06-14 14:12:59 +0800739 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
740 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
741 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
developer72fb0bb2023-01-11 09:46:29 +0800742};
743
744static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
745};
746
747static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
748};
749
750typedef struct _wifi_channelStats_loc {
developera3511852023-06-14 14:12:59 +0800751 INT array_size;
752 INT ch_number;
753 BOOL ch_in_pool;
754 INT ch_noise;
755 BOOL ch_radar_noise;
756 INT ch_max_80211_rssi;
757 INT ch_non_80211_noise;
758 INT ch_utilization;
759 ULLONG ch_utilization_total;
760 ULLONG ch_utilization_busy;
761 ULLONG ch_utilization_busy_tx;
762 ULLONG ch_utilization_busy_rx;
763 ULLONG ch_utilization_busy_self;
764 ULLONG ch_utilization_busy_ext;
developer72fb0bb2023-01-11 09:46:29 +0800765} wifi_channelStats_t_loc;
766
767typedef struct wifi_device_info {
developera3511852023-06-14 14:12:59 +0800768 INT wifi_devIndex;
769 UCHAR wifi_devMacAddress[6];
770 CHAR wifi_devIPAddress[64];
771 BOOL wifi_devAssociatedDeviceAuthentiationState;
772 INT wifi_devSignalStrength;
773 INT wifi_devTxRate;
774 INT wifi_devRxRate;
developer72fb0bb2023-01-11 09:46:29 +0800775} wifi_device_info_t;
776
777#endif
778
779//For 5g Alias Interfaces
developer72fb0bb2023-01-11 09:46:29 +0800780static BOOL Radio_flag = TRUE;
781//wifi_setApBeaconRate(1, beaconRate);
782
783BOOL multiple_set = FALSE;
784
785struct params
786{
developera3511852023-06-14 14:12:59 +0800787 char * name;
788 char * value;
developer72fb0bb2023-01-11 09:46:29 +0800789};
790
791static int _syscmd(char *cmd, char *retBuf, int retBufSize)
792{
developera3511852023-06-14 14:12:59 +0800793 FILE *f;
794 char *ptr = retBuf;
795 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
developer72fb0bb2023-01-11 09:46:29 +0800796
developera3511852023-06-14 14:12:59 +0800797 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
798 if((f = popen(cmd, "r")) == NULL) {
developer75bd10c2023-06-27 11:34:08 +0800799 wifi_debug(DEBUG_ERROR, "\npopen %s error\n", cmd);
developera3511852023-06-14 14:12:59 +0800800 return RETURN_ERR;
801 }
developer72fb0bb2023-01-11 09:46:29 +0800802
developera3511852023-06-14 14:12:59 +0800803 while(!feof(f))
804 {
805 *ptr = 0;
806 if(bufSize>=128) {
807 bufbytes=128;
808 } else {
809 bufbytes=bufSize-1;
810 }
developer72fb0bb2023-01-11 09:46:29 +0800811
developerd14dff12023-06-28 22:47:44 +0800812 if (fgets(ptr,bufbytes,f) == NULL)
813 break;
developera3511852023-06-14 14:12:59 +0800814 readbytes=strlen(ptr);
developer72fb0bb2023-01-11 09:46:29 +0800815
developera3511852023-06-14 14:12:59 +0800816 if(!readbytes)
817 break;
developer72fb0bb2023-01-11 09:46:29 +0800818
developera3511852023-06-14 14:12:59 +0800819 bufSize-=readbytes;
820 ptr += readbytes;
821 }
822 cmd_ret = pclose(f);
823 retBuf[retBufSize-1]=0;
824 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800825
developera3511852023-06-14 14:12:59 +0800826 return cmd_ret >> 8;
developer72fb0bb2023-01-11 09:46:29 +0800827}
828
829INT radio_index_to_phy(int radioIndex)
830{
developera3511852023-06-14 14:12:59 +0800831 /* TODO */
832 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800833}
834
835INT wifi_getMaxRadioNumber(INT *max_radio_num)
836{
developera3511852023-06-14 14:12:59 +0800837 char cmd[64] = {0};
838 char buf[4] = {0};
developere40952c2023-06-15 18:46:43 +0800839 int res;
developerc14d83a2023-06-29 20:09:42 +0800840 unsigned long tmp;
developera3511852023-06-14 14:12:59 +0800841 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800842
developer5fbf2ff2023-06-30 10:51:56 +0800843 res = snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l | tr -d '\\n'");
developere40952c2023-06-15 18:46:43 +0800844 if (os_snprintf_error(sizeof(cmd), res)) {
845 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
846 return RETURN_ERR;
847 }
developera3511852023-06-14 14:12:59 +0800848 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +0800849
850 if (hal_strtoul(buf, 10, &tmp) < 0) {
851 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +0800852 }
developerc14d83a2023-06-29 20:09:42 +0800853 res = tmp;
developerd14dff12023-06-28 22:47:44 +0800854
855 *max_radio_num = res > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:res;
developer72fb0bb2023-01-11 09:46:29 +0800856
developera3511852023-06-14 14:12:59 +0800857 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800858
developera3511852023-06-14 14:12:59 +0800859 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +0800860}
861
developer17038e62023-03-02 14:43:43 +0800862wifi_band radio_index_to_band(int radioIndex)
863{
developera3511852023-06-14 14:12:59 +0800864 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800865}
866
developer72fb0bb2023-01-11 09:46:29 +0800867wifi_band wifi_index_to_band(int apIndex)
868{
developera3511852023-06-14 14:12:59 +0800869 char cmd[128] = {0};
870 char buf[64] = {0};
developerc14d83a2023-06-29 20:09:42 +0800871 long int nl80211_band = 0;
developera3511852023-06-14 14:12:59 +0800872 int i = 0;
873 int phyIndex = 0;
874 int radioIndex = 0;
875 int max_radio_num = 0;
876 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +0800877 int res;
developer72fb0bb2023-01-11 09:46:29 +0800878
developera3511852023-06-14 14:12:59 +0800879 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800880
developera3511852023-06-14 14:12:59 +0800881 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +0800882 if(max_radio_num == 0){
883 return RETURN_ERR;
884 }
developera3511852023-06-14 14:12:59 +0800885 radioIndex = apIndex % max_radio_num;
886 phyIndex = radio_index_to_phy(radioIndex);
887 while(i < 10){
developere40952c2023-06-15 18:46:43 +0800888 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
889 if (os_snprintf_error(sizeof(cmd), res)) {
890 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
891 }
developera3511852023-06-14 14:12:59 +0800892 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +0800893 if (hal_strtol(buf, 16, &nl80211_band) < 0) {
894 wifi_debug(DEBUG_ERROR, "strtol fail\n");
895 }
developera3511852023-06-14 14:12:59 +0800896 if (nl80211_band == 1)
897 band = band_2_4;
898 else if (nl80211_band == 2)
899 band = band_5;
900 else if (nl80211_band == 4) // band == 3 is 60GHz
901 band = band_6;
developer72fb0bb2023-01-11 09:46:29 +0800902
developera3511852023-06-14 14:12:59 +0800903 if(band != band_invalid)
904 break;
developer69b61b02023-03-07 17:17:44 +0800905
developera3511852023-06-14 14:12:59 +0800906 i++;
907 sleep(1);
908 }
developer72fb0bb2023-01-11 09:46:29 +0800909
developera3511852023-06-14 14:12:59 +0800910 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
911 return band;
developer72fb0bb2023-01-11 09:46:29 +0800912}
913
914static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
915{
developer7e4a2a62023-04-06 19:56:03 +0800916 char cmd[MAX_CMD_SIZE] = {0};
917 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800918 int res = 0;
developer72fb0bb2023-01-11 09:46:29 +0800919
developere40952c2023-06-15 18:46:43 +0800920 res = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developer7e4a2a62023-04-06 19:56:03 +0800921 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800922
developere40952c2023-06-15 18:46:43 +0800923 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
924 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
925 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +0800926 }
developerb758dfd2023-06-21 17:32:07 +0800927
developere40952c2023-06-15 18:46:43 +0800928 res = _syscmd(cmd, buf, sizeof(buf));
929 if ((res != 0) && (strlen(buf) == 0)) {
developer7e4a2a62023-04-06 19:56:03 +0800930 printf("%s: _syscmd error!", __func__);
931 return -1;
932 }
933
developere40952c2023-06-15 18:46:43 +0800934 res = snprintf(output, output_size, "%s", buf);
935 if (os_snprintf_error(output_size, res)) {
936 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
937 return RETURN_ERR;
938 }
developer7e4a2a62023-04-06 19:56:03 +0800939
940 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800941}
942
943static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
944{
developera3511852023-06-14 14:12:59 +0800945 char cmd[MAX_CMD_SIZE] = {0};
946 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800947 int res;
developer72fb0bb2023-01-11 09:46:29 +0800948
developera3511852023-06-14 14:12:59 +0800949 for (int i = 0; i < item_count; i++) {
950 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
951 if (strlen(buf) == 0) /*no such item, insert it*/
developere40952c2023-06-15 18:46:43 +0800952 res = snprintf(cmd, sizeof(cmd), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file);
developera3511852023-06-14 14:12:59 +0800953 else /*find the item, update it*/
developere40952c2023-06-15 18:46:43 +0800954 res = 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 +0800955
developere40952c2023-06-15 18:46:43 +0800956 if (os_snprintf_error(sizeof(cmd), res)) {
957 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
958 return RETURN_ERR;
959 }
developera3511852023-06-14 14:12:59 +0800960 if(_syscmd(cmd, buf, sizeof(buf)))
961 return -1;
962 }
developer72fb0bb2023-01-11 09:46:29 +0800963
developera3511852023-06-14 14:12:59 +0800964 return 0;
developera1255e42023-05-13 17:45:02 +0800965}
developerfde01262023-05-22 15:15:24 +0800966
developera1255e42023-05-13 17:45:02 +0800967static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
968{
developera3511852023-06-14 14:12:59 +0800969 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800970 int res = 0;
developera3511852023-06-14 14:12:59 +0800971 int len;
developerfde01262023-05-22 15:15:24 +0800972
developere40952c2023-06-15 18:46:43 +0800973 res = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
974 if (os_snprintf_error(sizeof(cmd), res)) {
975 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
976 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800977 }
developerfde01262023-05-22 15:15:24 +0800978
developere40952c2023-06-15 18:46:43 +0800979
980 res = _syscmd(cmd, output, output_size);
981 if ((res != 0) && (strlen(output) == 0)) {
developera3511852023-06-14 14:12:59 +0800982 printf("%s: _syscmd error!", __func__);
983 return -1;
984 }
developera1255e42023-05-13 17:45:02 +0800985
developera3511852023-06-14 14:12:59 +0800986 len = strlen(output);
987 if ((len > 0) && (output[len - 1] == '\n')) {
988 output[len - 1] = '\0';
989 }
developerfde01262023-05-22 15:15:24 +0800990
developera3511852023-06-14 14:12:59 +0800991 return 0;
developerfde01262023-05-22 15:15:24 +0800992}
developera1255e42023-05-13 17:45:02 +0800993
developera1255e42023-05-13 17:45:02 +0800994static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
995{
developere40952c2023-06-15 18:46:43 +0800996 int res;
developera3511852023-06-14 14:12:59 +0800997 char cmd[MAX_CMD_SIZE] = {0};
998 char buf[MAX_BUF_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800999
developera3511852023-06-14 14:12:59 +08001000 for (int i = 0; i < item_count; i++) {
developere40952c2023-06-15 18:46:43 +08001001 res = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
1002 if (os_snprintf_error(sizeof(cmd), res)) {
1003 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1004 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08001005 }
developera1255e42023-05-13 17:45:02 +08001006
developera3511852023-06-14 14:12:59 +08001007 if(_syscmd(cmd, buf, sizeof(buf)))
1008 return -1;
1009 }
developera1255e42023-05-13 17:45:02 +08001010
developera3511852023-06-14 14:12:59 +08001011 return 0;
developera1255e42023-05-13 17:45:02 +08001012}
1013
developerfde01262023-05-22 15:15:24 +08001014static int wifi_l1ProfileRead(char *param, char *output, int output_size)
1015{
developera3511852023-06-14 14:12:59 +08001016 int ret;
developerfde01262023-05-22 15:15:24 +08001017
developera3511852023-06-14 14:12:59 +08001018 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1019 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001020 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001021 return RETURN_ERR;
1022 }
developerfde01262023-05-22 15:15:24 +08001023
developera3511852023-06-14 14:12:59 +08001024 ret = wifi_datfileRead(l1profile, param, output, output_size);
1025 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001026 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, l1profile, ret);
developera3511852023-06-14 14:12:59 +08001027 return RETURN_ERR;
1028 }
developerfde01262023-05-22 15:15:24 +08001029
developera3511852023-06-14 14:12:59 +08001030 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1031 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001032}
1033
1034static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
1035{
developera3511852023-06-14 14:12:59 +08001036 char option[64];
1037 char card_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001038 int res;
developerfde01262023-05-22 15:15:24 +08001039
developera3511852023-06-14 14:12:59 +08001040 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerfde01262023-05-22 15:15:24 +08001041
developera3511852023-06-14 14:12:59 +08001042 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001043 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001044 return RETURN_ERR;
1045 }
developerfde01262023-05-22 15:15:24 +08001046
developere40952c2023-06-15 18:46:43 +08001047 res = snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
1048 if (os_snprintf_error(sizeof(option), res)) {
1049 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +08001050 return RETURN_ERR;
1051 }
developere40952c2023-06-15 18:46:43 +08001052 res = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
1053 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001054 wifi_debug(DEBUG_ERROR, "wifi_l1ProfileRead %s failed, ret:%d", option, res);
developere40952c2023-06-15 18:46:43 +08001055 return RETURN_ERR;
1056 }
developerfde01262023-05-22 15:15:24 +08001057
developere40952c2023-06-15 18:46:43 +08001058 res = wifi_datfileRead(card_profile_path, param, output, output_size);
1059 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001060 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, card_profile_path, res);
developera3511852023-06-14 14:12:59 +08001061 return RETURN_ERR;
1062 }
developerfde01262023-05-22 15:15:24 +08001063
developera3511852023-06-14 14:12:59 +08001064 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1065 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001066}
1067
1068static int wifi_BandProfileRead(int card_idx,
developera3511852023-06-14 14:12:59 +08001069 int radio_idx,
1070 char *param,
1071 char *output,
1072 int output_size,
1073 char *default_value)
developerfde01262023-05-22 15:15:24 +08001074{
developera3511852023-06-14 14:12:59 +08001075 char option[64];
1076 char band_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001077 int ret, res;
developerfde01262023-05-22 15:15:24 +08001078
developera3511852023-06-14 14:12:59 +08001079 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1080 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001081 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001082 return RETURN_ERR;
1083 }
developerfde01262023-05-22 15:15:24 +08001084
developere40952c2023-06-15 18:46:43 +08001085 res = snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1086 if (os_snprintf_error(sizeof(option), res)) {
1087 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1088 return RETURN_ERR;
1089 }
developera3511852023-06-14 14:12:59 +08001090 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1091 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001092 wifi_debug(DEBUG_ERROR, "wifi_CardProfileRead %s failed, ret:%d", option, ret);
developera3511852023-06-14 14:12:59 +08001093 return RETURN_ERR;
1094 }
developerfde01262023-05-22 15:15:24 +08001095
developera3511852023-06-14 14:12:59 +08001096 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1097 if (ret != 0) {
1098 if (default_value) {
developere40952c2023-06-15 18:46:43 +08001099 res = snprintf(output, output_size, "%s", default_value);
1100 if (os_snprintf_error(output_size, res)) {
1101 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1102 return RETURN_ERR;
1103 }
developera3511852023-06-14 14:12:59 +08001104 } else {
1105 output[0] = '\0';
1106 }
1107 }
developerfde01262023-05-22 15:15:24 +08001108
developera3511852023-06-14 14:12:59 +08001109 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1110 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001111}
1112
developer72fb0bb2023-01-11 09:46:29 +08001113//For Getting Current Interface Name from corresponding hostapd configuration
1114static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1115{
developera3511852023-06-14 14:12:59 +08001116 char config_file[128] = {0};
developere40952c2023-06-15 18:46:43 +08001117 int res;
developer72fb0bb2023-01-11 09:46:29 +08001118
developera3511852023-06-14 14:12:59 +08001119 if (interface_name == NULL)
1120 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001121
developera3511852023-06-14 14:12:59 +08001122 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001123
developere40952c2023-06-15 18:46:43 +08001124 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1125 if (os_snprintf_error(sizeof(config_file), res)) {
1126 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1127 return RETURN_ERR;
1128 }
developera3511852023-06-14 14:12:59 +08001129 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1130 if (strlen(interface_name) == 0)
1131 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001132
developera3511852023-06-14 14:12:59 +08001133 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1134 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001135}
1136
developera1255e42023-05-13 17:45:02 +08001137static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1138{
developera3511852023-06-14 14:12:59 +08001139 char interface_name[IF_NAME_SIZE] = {0};
1140 char cmd[MAX_BUF_SIZE]={'\0'};
1141 char buf[MAX_CMD_SIZE]={'\0'};
1142 UCHAR channel = 0;
developere40952c2023-06-15 18:46:43 +08001143 int res;
developera1255e42023-05-13 17:45:02 +08001144
developera3511852023-06-14 14:12:59 +08001145 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1146 return RETURN_ERR;
1147 /*interface name to channel number*/
developere40952c2023-06-15 18:46:43 +08001148 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1149 if (os_snprintf_error(sizeof(cmd), res)) {
1150 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1151 return RETURN_ERR;
1152 }
1153
developera3511852023-06-14 14:12:59 +08001154 _syscmd(cmd, buf, sizeof(buf));
1155 channel = atoi(buf);
1156 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
developera1255e42023-05-13 17:45:02 +08001157 /*count dev number with the same channel*/
developere40952c2023-06-15 18:46:43 +08001158 res = snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1159 if (os_snprintf_error(sizeof(cmd), res)) {
1160 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1161 return RETURN_ERR;
1162 }
1163
developera3511852023-06-14 14:12:59 +08001164 _syscmd(cmd, buf, sizeof(buf));
1165 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1166 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1167 return RETURN_OK;
developera1255e42023-05-13 17:45:02 +08001168}
developer72fb0bb2023-01-11 09:46:29 +08001169
1170static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1171{
developera3511852023-06-14 14:12:59 +08001172 char interface_name[16] = {0};
1173 if (multiple_set == TRUE)
1174 return RETURN_OK;
1175 char cmd[MAX_CMD_SIZE]="", output[32]="";
1176 FILE *fp;
developere40952c2023-06-15 18:46:43 +08001177 int i, res;
developera3511852023-06-14 14:12:59 +08001178 //NOTE RELOAD should be done in ApplySSIDSettings
1179 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1180 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001181
1182 for (i=0; i<item_count; i++, list++) {
1183 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
1184 if (os_snprintf_error(sizeof(cmd), res)) {
1185 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1186 return RETURN_ERR;
1187 }
1188 if ((fp = popen(cmd, "r"))==NULL) {
developera3511852023-06-14 14:12:59 +08001189 perror("popen failed");
1190 return -1;
1191 }
developere40952c2023-06-15 18:46:43 +08001192 if (!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) {
1193 pclose(fp);
developera3511852023-06-14 14:12:59 +08001194 perror("fgets failed");
1195 return -1;
1196 }
developere40952c2023-06-15 18:46:43 +08001197 pclose(fp);
developera3511852023-06-14 14:12:59 +08001198 }
1199 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001200}
1201
developer7e4a2a62023-04-06 19:56:03 +08001202static int wifi_quick_reload_ap(int apIndex)
1203{
1204 char interface_name[IF_NAME_SIZE] = {0};
1205 char cmd[MAX_CMD_SIZE] = {0};
1206 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001207 int res;
developer7e4a2a62023-04-06 19:56:03 +08001208
1209 if (multiple_set == TRUE)
1210 return RETURN_OK;
1211
1212 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1213 return RETURN_ERR;
1214
developere40952c2023-06-15 18:46:43 +08001215 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1216 if (os_snprintf_error(sizeof(cmd), res)) {
1217 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1218 return RETURN_ERR;
1219 }
developer7e4a2a62023-04-06 19:56:03 +08001220 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1221 return RETURN_ERR;
1222
1223 return RETURN_OK;
1224}
1225
developer72fb0bb2023-01-11 09:46:29 +08001226static int wifi_reloadAp(int apIndex)
1227{
developera3511852023-06-14 14:12:59 +08001228 char interface_name[16] = {0};
developer22e0c672023-06-07 15:25:37 +08001229 int res;
1230
developera3511852023-06-14 14:12:59 +08001231 if (multiple_set == TRUE)
1232 return RETURN_OK;
1233 char cmd[MAX_CMD_SIZE]="";
1234 char buf[MAX_BUF_SIZE]="";
developer72fb0bb2023-01-11 09:46:29 +08001235
developera3511852023-06-14 14:12:59 +08001236 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1237 return RETURN_ERR;
1238 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
developer22e0c672023-06-07 15:25:37 +08001239 if (os_snprintf_error(sizeof(cmd), res)) {
1240 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1241 return RETURN_ERR;
1242 }
developera3511852023-06-14 14:12:59 +08001243 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1244 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001245
developera3511852023-06-14 14:12:59 +08001246 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001247 if (os_snprintf_error(sizeof(cmd), res)) {
1248 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1249 return RETURN_ERR;
1250 }
developera3511852023-06-14 14:12:59 +08001251 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1252 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001253
developera3511852023-06-14 14:12:59 +08001254 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001255 if (os_snprintf_error(sizeof(cmd), res)) {
1256 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1257 return RETURN_ERR;
1258 }
developera3511852023-06-14 14:12:59 +08001259 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1260 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001261
developera3511852023-06-14 14:12:59 +08001262 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001263}
1264
1265INT File_Reading(CHAR *file, char *Value)
1266{
developera3511852023-06-14 14:12:59 +08001267 FILE *fp = NULL;
1268 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1269 int count = 0;
developer72fb0bb2023-01-11 09:46:29 +08001270
developera3511852023-06-14 14:12:59 +08001271 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1272 fp = popen(file,"r");
1273 if(fp == NULL)
1274 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001275
developera3511852023-06-14 14:12:59 +08001276 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1277 {
1278 for(count=0;buf[count]!='\n';count++)
1279 copy_buf[count]=buf[count];
1280 copy_buf[count]='\0';
1281 }
developerc14d83a2023-06-29 20:09:42 +08001282 strncpy(Value, copy_buf, strlen(copy_buf));
1283 Value[strlen(Value)] = '\0';
developera3511852023-06-14 14:12:59 +08001284 pclose(fp);
1285 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001286
developera3511852023-06-14 14:12:59 +08001287 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001288}
1289
1290void wifi_RestartHostapd_2G()
1291{
developera3511852023-06-14 14:12:59 +08001292 int Public2GApIndex = 4;
developer72fb0bb2023-01-11 09:46:29 +08001293
developera3511852023-06-14 14:12:59 +08001294 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1295 wifi_setApEnable(Public2GApIndex, FALSE);
1296 wifi_setApEnable(Public2GApIndex, TRUE);
1297 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001298}
1299
1300void wifi_RestartHostapd_5G()
1301{
developera3511852023-06-14 14:12:59 +08001302 int Public5GApIndex = 5;
developer72fb0bb2023-01-11 09:46:29 +08001303
developera3511852023-06-14 14:12:59 +08001304 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1305 wifi_setApEnable(Public5GApIndex, FALSE);
1306 wifi_setApEnable(Public5GApIndex, TRUE);
1307 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001308}
1309
1310void wifi_RestartPrivateWifi_2G()
1311{
developera3511852023-06-14 14:12:59 +08001312 int PrivateApIndex = 0;
developer72fb0bb2023-01-11 09:46:29 +08001313
developera3511852023-06-14 14:12:59 +08001314 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1315 wifi_setApEnable(PrivateApIndex, FALSE);
1316 wifi_setApEnable(PrivateApIndex, TRUE);
1317 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001318}
1319
1320void wifi_RestartPrivateWifi_5G()
1321{
developera3511852023-06-14 14:12:59 +08001322 int Private5GApIndex = 1;
developer72fb0bb2023-01-11 09:46:29 +08001323
developera3511852023-06-14 14:12:59 +08001324 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1325 wifi_setApEnable(Private5GApIndex, FALSE);
1326 wifi_setApEnable(Private5GApIndex, TRUE);
1327 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001328}
1329
1330static int writeBandWidth(int radioIndex,char *bw_value)
1331{
developera3511852023-06-14 14:12:59 +08001332 char buf[MAX_BUF_SIZE];
1333 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08001334 int res;
developer72fb0bb2023-01-11 09:46:29 +08001335
developere40952c2023-06-15 18:46:43 +08001336 res = snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1337 if (os_snprintf_error(sizeof(cmd), res)) {
1338 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1339 return RETURN_ERR;
1340 }
1341
1342 if (_syscmd(cmd, buf, sizeof(buf))) {
1343 res = snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1344 if (os_snprintf_error(sizeof(cmd), res)) {
1345 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1346 return RETURN_ERR;
1347 }
developera3511852023-06-14 14:12:59 +08001348 _syscmd(cmd, buf, sizeof(buf));
1349 return RETURN_OK;
1350 }
developer72fb0bb2023-01-11 09:46:29 +08001351
developer75bd10c2023-06-27 11:34:08 +08001352 res = snprintf(cmd, sizeof(cmd), "sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1353 if (os_snprintf_error(sizeof(cmd), res)) {
1354 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1355 return RETURN_ERR;
1356 }
developera3511852023-06-14 14:12:59 +08001357 _syscmd(cmd,buf,sizeof(buf));
1358 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001359}
1360
1361// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1362INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1363{
developera3511852023-06-14 14:12:59 +08001364 struct params params={'\0'};
1365 char config_file[MAX_BUF_SIZE] = {0};
1366 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08001367 int res;
developer72fb0bb2023-01-11 09:46:29 +08001368
developera3511852023-06-14 14:12:59 +08001369 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1370 // Copy the numeric value
1371 if (strlen (beaconRate) >= 5) {
1372 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1373 buf[strlen(beaconRate) - 4] = '\0';
developer9ce44382023-06-28 11:09:37 +08001374 } else if (strlen(beaconRate) > 0){
1375 strncpy(buf, beaconRate,sizeof(buf) - 1);
1376 buf[sizeof(buf) - 1] = '\0';
1377 } else
developera3511852023-06-14 14:12:59 +08001378 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001379
developera3511852023-06-14 14:12:59 +08001380 params.name = "beacon_rate";
1381 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1382 if (strncmp(buf, "5.5", 3) == 0) {
developere40952c2023-06-15 18:46:43 +08001383 res = snprintf(buf, sizeof(buf), "55");
1384 if (os_snprintf_error(sizeof(buf), res)) {
1385 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1386 return RETURN_ERR;
1387 }
developera3511852023-06-14 14:12:59 +08001388 params.value = buf;
1389 } else {
developer32f2a182023-06-27 19:50:41 +08001390 if (strlen(buf) >= (MAX_BUF_SIZE - 1)) {
1391 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
1392 return RETURN_ERR;
1393 }
1394 strncat(buf, "0", sizeof(buf) - strlen(buf) - 1);
developera3511852023-06-14 14:12:59 +08001395 params.value = buf;
1396 }
developer72fb0bb2023-01-11 09:46:29 +08001397
developer32f2a182023-06-27 19:50:41 +08001398 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
1399 if (os_snprintf_error(sizeof(config_file), res)) {
1400 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1401 return RETURN_ERR;
1402 }
1403
developera3511852023-06-14 14:12:59 +08001404 wifi_hostapdWrite(config_file, &params, 1);
1405 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1406 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001407
developera3511852023-06-14 14:12:59 +08001408 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001409}
1410
1411INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1412{
developera3511852023-06-14 14:12:59 +08001413 char config_file[128] = {'\0'};
1414 char temp_output[MAX_BUF_SIZE] = {'\0'};
1415 char buf[128] = {'\0'};
1416 char cmd[128] = {'\0'};
developerc14d83a2023-06-29 20:09:42 +08001417 long int rate = 0;
developere40952c2023-06-15 18:46:43 +08001418 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08001419
developera3511852023-06-14 14:12:59 +08001420 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1421 if (NULL == beaconRate)
1422 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001423
developer75bd10c2023-06-27 11:34:08 +08001424 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
1425 if (os_snprintf_error(sizeof(config_file), res)) {
1426 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1427 return RETURN_ERR;
1428 }
developera3511852023-06-14 14:12:59 +08001429 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1430 phyId = radio_index_to_phy(radioIndex);
1431 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1432 if(strlen(buf) > 0) {
1433 if (strncmp(buf, "55", 2) == 0)
developere40952c2023-06-15 18:46:43 +08001434 res = snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
developera3511852023-06-14 14:12:59 +08001435 else {
developerc14d83a2023-06-29 20:09:42 +08001436 if (hal_strtol(buf, 10, &rate) < 0) {
1437 wifi_debug(DEBUG_ERROR, "strtol fail\n");
1438 }
1439 res = snprintf(temp_output, sizeof(temp_output), "%ldMbps", rate);
developera3511852023-06-14 14:12:59 +08001440 }
developer75bd10c2023-06-27 11:34:08 +08001441 if (os_snprintf_error(sizeof(temp_output), res)) {
1442 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1443 return RETURN_ERR;
1444 }
developera3511852023-06-14 14:12:59 +08001445 } else {
1446 // config not set, so we would use lowest rate as default
developer75bd10c2023-06-27 11:34:08 +08001447 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1448 if (os_snprintf_error(sizeof(cmd), res)) {
1449 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1450 return RETURN_ERR;
1451 }
developera3511852023-06-14 14:12:59 +08001452 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08001453 res = snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
developer75bd10c2023-06-27 11:34:08 +08001454 if (os_snprintf_error(sizeof(temp_output), res)) {
1455 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1456 return RETURN_ERR;
1457 }
developera3511852023-06-14 14:12:59 +08001458 }
developer75bd10c2023-06-27 11:34:08 +08001459
developera3511852023-06-14 14:12:59 +08001460 strncpy(beaconRate, temp_output, strlen(temp_output));
1461 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001462
developera3511852023-06-14 14:12:59 +08001463 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001464}
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{
developere40952c2023-06-15 18:46:43 +08001484 int res;
1485
developera3511852023-06-14 14:12:59 +08001486 if(!output_string)
1487 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001488 res = snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1489 if (os_snprintf_error(64, res)) {
1490 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1491 return RETURN_ERR;
1492 }
developer72fb0bb2023-01-11 09:46:29 +08001493
developera3511852023-06-14 14:12:59 +08001494 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001495}
1496
1497
1498/* wifi_factoryReset() function */
1499/**
developer69b61b02023-03-07 17:17:44 +08001500* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001501* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1502*
1503* @param None
1504*
1505* @return The status of the operation.
1506* @retval RETURN_OK if successful.
1507* @retval RETURN_ERR if any error is detected
1508*
1509* @execution Synchronous
1510* @sideeffect None
1511*
1512* @note This function must not suspend and must not invoke any blocking system
1513* calls. It should probably just send a message to a driver event handler task.
1514*
1515*/
1516INT wifi_factoryReset()
1517{
developer47cc27a2023-05-17 23:09:58 +08001518 char cmd[MAX_CMD_SIZE] = {0};
1519 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001520 int res;
developer72fb0bb2023-01-11 09:46:29 +08001521
developer47cc27a2023-05-17 23:09:58 +08001522 /*delete running hostapd conf files*/
1523 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
developere40952c2023-06-15 18:46:43 +08001524 res = snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1525 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1526 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1527 return RETURN_ERR;
1528 }
1529
developer47cc27a2023-05-17 23:09:58 +08001530 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001531
developerd14dff12023-06-28 22:47:44 +08001532 wifi_PrepareDefaultHostapdConfigs(TRUE);
developer47cc27a2023-05-17 23:09:58 +08001533 wifi_psk_file_reset();
1534
1535 memset(cmd, 0, MAX_CMD_SIZE);
1536 memset(buf, 0, MAX_BUF_SIZE);
1537
developere40952c2023-06-15 18:46:43 +08001538 res = snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1539 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1540 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1541 return RETURN_ERR;
1542 }
1543
developer47cc27a2023-05-17 23:09:58 +08001544 _syscmd(cmd, buf, sizeof(buf));
1545
1546 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001547}
1548
1549/* wifi_factoryResetRadios() function */
1550/**
1551* @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.
1552*
1553* @param None
1554* @return The status of the operation
1555* @retval RETURN_OK if successful
1556* @retval RETURN_ERR if any error is detected
1557*
1558* @execution Synchronous
1559*
1560* @sideeffect None
1561*
1562* @note This function must not suspend and must not invoke any blocking system
1563* calls. It should probably just send a message to a driver event handler task.
1564*
1565*/
1566INT wifi_factoryResetRadios()
1567{
developera3511852023-06-14 14:12:59 +08001568 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1569 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001570
developera3511852023-06-14 14:12:59 +08001571 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001572}
1573
developerfead3972023-05-25 20:15:02 +08001574ULONG get_radio_reset_cnt(int radioIndex)
1575{
1576 char cmd[MAX_CMD_SIZE] = {0};
1577 char buf[MAX_BUF_SIZE] = {0};
1578 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001579 int res;
developerfead3972023-05-25 20:15:02 +08001580
developere40952c2023-06-15 18:46:43 +08001581 res = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developerfead3972023-05-25 20:15:02 +08001582 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001583 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1584 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1585 return RETURN_ERR;
1586 }
1587
developerfead3972023-05-25 20:15:02 +08001588 _syscmd(cmd, buf, sizeof(buf));
1589
1590 if (strlen(buf) == 0)
1591 return 0;
1592 else {
1593 reset_count = atol(buf);
1594 return reset_count;
1595 }
1596}
1597void update_radio_reset_cnt(int radioIndex)
1598{
1599 char cmd[MAX_CMD_SIZE] = {0};
1600 char buf[MAX_BUF_SIZE] = {0};
1601 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001602 int res;
developerfead3972023-05-25 20:15:02 +08001603
developere40952c2023-06-15 18:46:43 +08001604 res = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developerfead3972023-05-25 20:15:02 +08001605 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001606 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1607 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1608 return;
1609 }
1610
developerfead3972023-05-25 20:15:02 +08001611 _syscmd(cmd, buf, sizeof(buf));
1612
1613 if (strlen(buf) == 0)
developere40952c2023-06-15 18:46:43 +08001614 res = snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
developerfead3972023-05-25 20:15:02 +08001615 else {
1616 reset_count = atol(buf);
1617 reset_count++;
developere40952c2023-06-15 18:46:43 +08001618 res = snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
1619 }
1620 if (os_snprintf_error(sizeof(cmd), res)) {
1621 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1622 return;
developerfead3972023-05-25 20:15:02 +08001623 }
1624 _syscmd(cmd, buf, sizeof(buf));
1625}
developer72fb0bb2023-01-11 09:46:29 +08001626
1627/* wifi_factoryResetRadio() function */
1628/**
1629* @description Restore selected radio parameters without touching access point parameters
1630*
1631* @param radioIndex - Index of Wi-Fi Radio channel
1632*
1633* @return The status of the operation.
1634* @retval RETURN_OK if successful.
1635* @retval RETURN_ERR if any error is detected
1636*
1637* @execution Synchronous.
1638* @sideeffect None.
1639*
1640* @note This function must not suspend and must not invoke any blocking system
1641* calls. It should probably just send a message to a driver event handler task.
1642*
1643*/
1644INT wifi_factoryResetRadio(int radioIndex) //RDKB
1645{
developer47cc27a2023-05-17 23:09:58 +08001646 char cmd[MAX_CMD_SIZE] = {0};
1647 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001648 int res;
developer72fb0bb2023-01-11 09:46:29 +08001649
developer47cc27a2023-05-17 23:09:58 +08001650 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001651
developerb2977562023-05-24 17:54:12 +08001652 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001653
developerb2977562023-05-24 17:54:12 +08001654 /*reset gi setting*/
developere40952c2023-06-15 18:46:43 +08001655 res = snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
1656 if (os_snprintf_error(sizeof(cmd), res)) {
1657 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1658 return RETURN_ERR;
1659 }
1660
developer47cc27a2023-05-17 23:09:58 +08001661 _syscmd(cmd, buf, sizeof(buf));
1662
developerb2977562023-05-24 17:54:12 +08001663 /*TBD: check mbss issue*/
1664 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08001665 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08001666
developer47cc27a2023-05-17 23:09:58 +08001667 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1668 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001669}
1670
1671/* wifi_initRadio() function */
1672/**
1673* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001674* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001675* different hardware implementations may have different initilization requirements.
1676* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1677*
1678* @return The status of the operation.
1679* @retval RETURN_OK if successful.
1680* @retval RETURN_ERR if any error is detected
1681*
1682* @execution Synchronous.
1683* @sideeffect None.
1684*
1685* @note This function must not suspend and must not invoke any blocking system
1686* calls. It should probably just send a message to a driver event handler task.
1687*
1688*/
1689INT wifi_initRadio(INT radioIndex)
1690{
developera3511852023-06-14 14:12:59 +08001691 //TODO: Initializes the wifi subsystem (for specified radio)
1692 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001693}
1694
developer17038e62023-03-02 14:43:43 +08001695static void
1696wifi_ParseProfile(void)
1697{
developere40952c2023-06-15 18:46:43 +08001698 int i, res;
developera3511852023-06-14 14:12:59 +08001699 int max_radio_num = 0;
1700 int card_idx;
1701 int band_idx;
1702 int phy_idx = 0;
1703 int wireless_mode = 0;
1704 char buf[MAX_BUF_SIZE] = {0};
1705 char chip_name[12];
1706 char card_profile[MAX_BUF_SIZE] = {0};
1707 char band_profile[MAX_BUF_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001708
developera3511852023-06-14 14:12:59 +08001709 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001710
developera3511852023-06-14 14:12:59 +08001711 memset(main_prefix, 0, sizeof(main_prefix));
1712 memset(ext_prefix, 0, sizeof(ext_prefix));
1713 memset(default_ssid, 0, sizeof(default_ssid));
1714 for (i = 0; i < MAX_NUM_RADIOS; i++)
1715 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001716
developera3511852023-06-14 14:12:59 +08001717 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1718 /* LOG */
developer17038e62023-03-02 14:43:43 +08001719 return;
developera3511852023-06-14 14:12:59 +08001720 }
developer17038e62023-03-02 14:43:43 +08001721
developera3511852023-06-14 14:12:59 +08001722 for (card_idx = 0; card_idx < 3; card_idx++) {
developere40952c2023-06-15 18:46:43 +08001723 res = snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1724 if (os_snprintf_error(sizeof(buf), res)) {
1725 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1726 return;
1727 }
developera3511852023-06-14 14:12:59 +08001728 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1729 break;
1730 }
developere40952c2023-06-15 18:46:43 +08001731 res = snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1732 if (os_snprintf_error(sizeof(buf), res)) {
1733 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1734 return;
1735 }
developera3511852023-06-14 14:12:59 +08001736 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1737 break;
1738 }
1739 for (band_idx = 0; band_idx < 3; band_idx++) {
developere40952c2023-06-15 18:46:43 +08001740 res = snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1741 if (os_snprintf_error(sizeof(buf), res)) {
1742 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1743 return;
1744 }
developera3511852023-06-14 14:12:59 +08001745 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1746 /* LOG */
1747 break;
1748 }
developer17038e62023-03-02 14:43:43 +08001749
developere40952c2023-06-15 18:46:43 +08001750 res = snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1751 if (os_snprintf_error(sizeof(buf), res)) {
1752 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1753 return;
1754 }
developera3511852023-06-14 14:12:59 +08001755 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1756 /* LOG */
1757 }
developer17038e62023-03-02 14:43:43 +08001758
developere40952c2023-06-15 18:46:43 +08001759 res = snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1760 if (os_snprintf_error(sizeof(buf), res)) {
1761 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1762 return;
1763 }
developera3511852023-06-14 14:12:59 +08001764 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1765 /* LOG */
1766 }
developer17038e62023-03-02 14:43:43 +08001767
developera3511852023-06-14 14:12:59 +08001768 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1769 /* LOG */
1770 }
1771 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1772 /* LOG */
1773 }
developer745f0bd2023-03-06 14:32:53 +08001774
developera3511852023-06-14 14:12:59 +08001775 wireless_mode = atoi(buf);
1776 switch (wireless_mode) {
1777 case 22:
1778 case 16:
1779 case 6:
1780 case 4:
1781 case 1:
1782 radio_band[phy_idx] = band_2_4;
1783 break;
1784 case 23:
1785 case 17:
1786 case 14:
1787 case 11:
1788 case 2:
1789 radio_band[phy_idx] = band_5;
1790 break;
1791 case 24:
1792 case 18:
1793 radio_band[phy_idx] = band_6;
1794 break;
1795 }
1796 phy_idx++;
1797 }
1798 }
developer17038e62023-03-02 14:43:43 +08001799
developera3511852023-06-14 14:12:59 +08001800 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001801}
1802
1803static void
developerd14dff12023-06-28 22:47:44 +08001804wifi_PrepareDefaultHostapdConfigs(bool reset)
developer17038e62023-03-02 14:43:43 +08001805{
developere40952c2023-06-15 18:46:43 +08001806 int radio_idx, res;
developer0132ed92023-03-21 13:48:53 +08001807 int bss_idx;
1808 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001809 char buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001810 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer0132ed92023-03-21 13:48:53 +08001811 char ssid[MAX_BUF_SIZE] = {0};
1812 char interface[32] = {0};
1813 char ret_buf[MAX_BUF_SIZE] = {0};
1814 char psk_file[64] = {0};
1815 struct params params[3];
developer17038e62023-03-02 14:43:43 +08001816
developer0132ed92023-03-21 13:48:53 +08001817 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1818 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001819
developer0132ed92023-03-21 13:48:53 +08001820 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001821 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001822
developere40952c2023-06-15 18:46:43 +08001823 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1824 if (os_snprintf_error(sizeof(config_file), res)) {
1825 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1826 return;
1827 }
developerd14dff12023-06-28 22:47:44 +08001828 if (access(config_file, F_OK) == 0 && reset == FALSE)
1829 continue;
developere40952c2023-06-15 18:46:43 +08001830 res = snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
1831 if (os_snprintf_error(sizeof(buf), res)) {
1832 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1833 return;
1834 }
developer47cc27a2023-05-17 23:09:58 +08001835 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001836
developer47cc27a2023-05-17 23:09:58 +08001837 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08001838 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1839 if (os_snprintf_error(sizeof(ssid), res)) {
1840 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1841 return;
1842 }
1843 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1844 if (os_snprintf_error(sizeof(interface), res)) {
1845 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1846 return;
1847 }
developer47cc27a2023-05-17 23:09:58 +08001848 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08001849 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1850 if (os_snprintf_error(sizeof(ssid), res)) {
1851 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1852 return;
1853 }
1854 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1855 if (os_snprintf_error(sizeof(interface), res)) {
1856 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1857 return;
1858 }
developer47cc27a2023-05-17 23:09:58 +08001859 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08001860 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1861 if (os_snprintf_error(sizeof(ssid), res)) {
1862 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1863 return;
1864 }
1865 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1866 if (os_snprintf_error(sizeof(interface), res)) {
1867 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1868 return;
1869 }
developer47cc27a2023-05-17 23:09:58 +08001870 }
developer17038e62023-03-02 14:43:43 +08001871
developer47cc27a2023-05-17 23:09:58 +08001872 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08001873 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
1874 if (os_snprintf_error(sizeof(psk_file), res)) {
1875 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1876 return;
1877 }
developer17038e62023-03-02 14:43:43 +08001878
developer47cc27a2023-05-17 23:09:58 +08001879 params[0].name = "ssid";
1880 params[0].value = ssid;
1881 params[1].name = "interface";
1882 params[1].value = interface;
1883 params[2].name = "wpa_psk_file";
1884 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001885
developer47cc27a2023-05-17 23:09:58 +08001886 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001887 }
1888 }
1889 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001890}
1891
1892static void
developer17038e62023-03-02 14:43:43 +08001893wifi_BringDownInterfacesForRadio(int radio_idx)
1894{
developera3511852023-06-14 14:12:59 +08001895 char cmd[MAX_BUF_SIZE] = {0};
1896 char ret_buf[MAX_BUF_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08001897 int res;
developerb758dfd2023-06-21 17:32:07 +08001898
developera3511852023-06-14 14:12:59 +08001899 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001900
developere40952c2023-06-15 18:46:43 +08001901 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1902 if (os_snprintf_error(sizeof(cmd), res)) {
1903 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1904 return;
1905 }
developer8a3bbbf2023-03-15 17:47:23 +08001906 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1907
developera3511852023-06-14 14:12:59 +08001908 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001909}
1910
1911
1912static void
1913wifi_BringDownInterfaces(void)
1914{
developera3511852023-06-14 14:12:59 +08001915 int radio_idx;
1916 int band_idx;
developer17038e62023-03-02 14:43:43 +08001917
developera3511852023-06-14 14:12:59 +08001918 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1919 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1920 band_idx = radio_index_to_band(radio_idx);
1921 if (band_idx < 0) {
1922 break;
1923 }
1924 wifi_BringDownInterfacesForRadio(radio_idx);
1925 }
1926 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001927}
1928
developerb2977562023-05-24 17:54:12 +08001929static void wifi_dat_file_reset_by_radio(char radio_idx)
1930{
developerb149d9d2023-06-06 16:14:22 +08001931 char cmd[MAX_CMD_SIZE * 2] = {0};
developerb2977562023-05-24 17:54:12 +08001932 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001933 char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
1934 char dat_file[MAX_SUB_CMD_SIZE]= {0};
developere40952c2023-06-15 18:46:43 +08001935 int res;
developerb2977562023-05-24 17:54:12 +08001936
developere40952c2023-06-15 18:46:43 +08001937 res = snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1938 if (os_snprintf_error(sizeof(rom_dat_file), res)) {
1939 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1940 return;
1941 }
1942 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
1943 if (os_snprintf_error(sizeof(dat_file), res)) {
1944 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1945 return;
1946 }
1947 res = snprintf(cmd, (MAX_CMD_SIZE * 2), "cp -rf %s %s", rom_dat_file, dat_file);
1948 if (os_snprintf_error((MAX_CMD_SIZE * 2), res)) {
1949 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1950 return;
1951 }
developerb2977562023-05-24 17:54:12 +08001952 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1953
1954}
1955
developer47cc27a2023-05-17 23:09:58 +08001956static void wifi_psk_file_reset()
1957{
1958 char cmd[MAX_CMD_SIZE] = {0};
1959 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001960 char psk_file[MAX_SUB_CMD_SIZE]= {0};
developer47cc27a2023-05-17 23:09:58 +08001961 char vap_idx = 0;
developere40952c2023-06-15 18:46:43 +08001962 int res;
developer47cc27a2023-05-17 23:09:58 +08001963
1964 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
developere40952c2023-06-15 18:46:43 +08001965 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1966 if (os_snprintf_error(sizeof(psk_file), res)) {
1967 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1968 return;
1969 }
developer47cc27a2023-05-17 23:09:58 +08001970
1971 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001972 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1973 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1974 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1975 return;
1976 }
developer47cc27a2023-05-17 23:09:58 +08001977 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1978 } else {
developere40952c2023-06-15 18:46:43 +08001979 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1980 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1981 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1982 return;
1983 }
1984
developer47cc27a2023-05-17 23:09:58 +08001985 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1986 }
1987 }
developerb2977562023-05-24 17:54:12 +08001988}
1989
developer8a3bbbf2023-03-15 17:47:23 +08001990static void wifi_vap_status_reset()
1991{
developera3511852023-06-14 14:12:59 +08001992 char cmd[MAX_CMD_SIZE] = {0};
1993 char ret_buf[MAX_BUF_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08001994 int radio_idx = 0;
developer8a3bbbf2023-03-15 17:47:23 +08001995 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08001996 int res;
developer8666b312023-03-24 14:05:31 +08001997
developer8a3bbbf2023-03-15 17:47:23 +08001998 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001999 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
2000 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2001 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2002 return;
2003 }
developer8a3bbbf2023-03-15 17:47:23 +08002004 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2005 } else {
developere40952c2023-06-15 18:46:43 +08002006 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
2007 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2008 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2009 return;
2010 }
developer8a3bbbf2023-03-15 17:47:23 +08002011 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2012 }
2013
2014 memset(cmd, 0, MAX_CMD_SIZE);
2015 memset(ret_buf, 0, MAX_BUF_SIZE);
2016
2017 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
developera3511852023-06-14 14:12:59 +08002018 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developere40952c2023-06-15 18:46:43 +08002019 res = snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
2020 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2021 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2022 return;
2023 }
developer8a3bbbf2023-03-15 17:47:23 +08002024 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2025 }
2026
developerfead3972023-05-25 20:15:02 +08002027}
2028
2029static void wifi_radio_reset_count_reset()
2030{
developera3511852023-06-14 14:12:59 +08002031 char cmd[MAX_CMD_SIZE] = {0};
2032 char ret_buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002033 int res;
developerfead3972023-05-25 20:15:02 +08002034
2035 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08002036 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE);
2037 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2038 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2039 return;
2040 }
developerfead3972023-05-25 20:15:02 +08002041 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2042 } else {
developere40952c2023-06-15 18:46:43 +08002043 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE);
2044 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2045 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2046 return;
2047 }
developerfead3972023-05-25 20:15:02 +08002048 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2049 }
developer8a3bbbf2023-03-15 17:47:23 +08002050}
developer17038e62023-03-02 14:43:43 +08002051
developer72fb0bb2023-01-11 09:46:29 +08002052// Initializes the wifi subsystem (all radios)
developera3511852023-06-14 14:12:59 +08002053INT wifi_init() //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002054{
developera3511852023-06-14 14:12:59 +08002055 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercc9a4f32023-05-30 17:40:02 +08002056 static int CallOnce = 1;
developera3511852023-06-14 14:12:59 +08002057 //Not intitializing macfilter for Turris-Omnia Platform for now
2058 //macfilter_init();
2059 if (CallOnce) {
developercc9a4f32023-05-30 17:40:02 +08002060 wifi_ParseProfile();
developerd14dff12023-06-28 22:47:44 +08002061 wifi_PrepareDefaultHostapdConfigs(FALSE);
developercc9a4f32023-05-30 17:40:02 +08002062 wifi_psk_file_reset();
2063 //system("/usr/sbin/iw reg set US");
2064 system("systemctl start hostapd.service");
2065 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002066
developercc9a4f32023-05-30 17:40:02 +08002067 wifi_vap_status_reset();
2068 wifi_radio_reset_count_reset();
2069 CallOnce = 0;
developera3511852023-06-14 14:12:59 +08002070 }
developer96b38512023-02-22 11:17:45 +08002071
developera3511852023-06-14 14:12:59 +08002072 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002073
developera3511852023-06-14 14:12:59 +08002074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002075}
2076
2077/* wifi_reset() function */
2078/**
2079* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08002080* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08002081* different hardware implementations may have different requirements.
2082* Parameters : None
2083*
2084* @return The status of the operation.
2085* @retval RETURN_OK if successful.
2086* @retval RETURN_ERR if any error is detected
2087*
2088* @execution Synchronous.
2089* @sideeffect None.
2090*
2091* @note This function must not suspend and must not invoke any blocking system
2092* calls. It should probably just send a message to a driver event handler task.
2093*
2094*/
2095INT wifi_reset()
2096{
developer17038e62023-03-02 14:43:43 +08002097
developera3511852023-06-14 14:12:59 +08002098 wifi_BringDownInterfaces();
2099 sleep(2);
developer17038e62023-03-02 14:43:43 +08002100
developera3511852023-06-14 14:12:59 +08002101 //TODO: resets the wifi subsystem, deletes all APs
2102 system("systemctl stop hostapd.service");
2103 sleep(2);
developer17038e62023-03-02 14:43:43 +08002104
developera3511852023-06-14 14:12:59 +08002105 system("systemctl start hostapd.service");
2106 sleep(5);
developer17038e62023-03-02 14:43:43 +08002107
developerd14dff12023-06-28 22:47:44 +08002108 wifi_PrepareDefaultHostapdConfigs(TRUE);
developer47cc27a2023-05-17 23:09:58 +08002109 wifi_psk_file_reset();
developera3511852023-06-14 14:12:59 +08002110 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002111
2112 wifi_vap_status_reset();
2113
developera3511852023-06-14 14:12:59 +08002114 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002115}
2116
2117/* wifi_down() function */
2118/**
2119* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08002120* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08002121* different hardware implementations may have different requirements.
2122*
2123* @param None
2124*
2125* @return The status of the operation
2126* @retval RETURN_OK if successful
2127* @retval RETURN_ERR if any error is detected
2128*
2129* @execution Synchronous
2130* @sideeffect None
2131*
2132* @note This function must not suspend and must not invoke any blocking system
2133* calls. It should probably just send a message to a driver event handler task.
2134*
2135*/
2136INT wifi_down()
2137{
developera3511852023-06-14 14:12:59 +08002138 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
2139 int max_num_radios = 0;
developerb2977562023-05-24 17:54:12 +08002140 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08002141
developerb2977562023-05-24 17:54:12 +08002142 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
2143 wifi_setRadioEnable(radioIndex, FALSE);
2144
developera3511852023-06-14 14:12:59 +08002145 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002146}
2147
2148
2149/* wifi_createInitialConfigFiles() function */
2150/**
2151* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08002152* and content of these files are implementation dependent. This function call is
2153* used to trigger this task if necessary. Some implementations may not need this
2154* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08002155* do nothing and return RETURN_OK.
2156*
2157* @param None
2158*
2159* @return The status of the operation
2160* @retval RETURN_OK if successful
2161* @retval RETURN_ERR if any error is detected
2162*
2163* @execution Synchronous
2164* @sideeffect None
2165*
2166* @note This function must not suspend and must not invoke any blocking system
2167* calls. It should probably just send a message to a driver event handler task.
2168*
2169*/
2170INT wifi_createInitialConfigFiles()
2171{
developera3511852023-06-14 14:12:59 +08002172 //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)
2173 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002174}
2175
developer7e4a2a62023-04-06 19:56:03 +08002176/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08002177INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
2178{
developera3511852023-06-14 14:12:59 +08002179 int ret;
developer72fb0bb2023-01-11 09:46:29 +08002180
developera3511852023-06-14 14:12:59 +08002181 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002182
developera3511852023-06-14 14:12:59 +08002183 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
2184 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08002185 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead CountryCode failed\n");
developera3511852023-06-14 14:12:59 +08002186 return RETURN_ERR;
2187 }
developer7e4a2a62023-04-06 19:56:03 +08002188
developera3511852023-06-14 14:12:59 +08002189 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002190
developera3511852023-06-14 14:12:59 +08002191 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002192}
2193
2194INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
2195{
developer7e4a2a62023-04-06 19:56:03 +08002196 /*Set wifi config. Wait for wifi reset to apply*/
developer7e4a2a62023-04-06 19:56:03 +08002197 struct params params;
2198 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002199 int ret = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002200
developer7e4a2a62023-04-06 19:56:03 +08002201 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002202
developer7e4a2a62023-04-06 19:56:03 +08002203 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
2204 printf("%s: input para error!!!\n", __func__);
2205 return RETURN_ERR;
2206 }
developer72fb0bb2023-01-11 09:46:29 +08002207
developerc79e9172023-06-06 19:48:03 +08002208 if (!strlen(CountryCode)) {
2209 memcpy(CountryCode, "US", strlen("US")); /*default set the code to US*/
2210 CountryCode[2] = '\0';
2211 }
developer72fb0bb2023-01-11 09:46:29 +08002212
developer7e4a2a62023-04-06 19:56:03 +08002213 params.name = "country_code";
2214 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08002215
developere40952c2023-06-15 18:46:43 +08002216 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2217 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
2218 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2219 return RETURN_ERR;
2220 }
developer7e4a2a62023-04-06 19:56:03 +08002221 ret = wifi_hostapdWrite(config_file, &params, 1);
2222
2223 if (ret) {
2224 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
2225 __func__, ret);
2226 }
2227
2228 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2229
2230 if (ret) {
2231 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
2232 __func__, ret);
2233 }
2234
2235 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2236
2237 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002238}
2239
2240INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
2241{
developera3511852023-06-14 14:12:59 +08002242 char interface_name[16] = {0};
2243 char channel_util_file[64] = {0};
2244 char cmd[128] = {0};
2245 char buf[128] = {0};
2246 char *line = NULL;
2247 char *param = NULL, *value = NULL;
developere40952c2023-06-15 18:46:43 +08002248 int read = 0, res;
developera3511852023-06-14 14:12:59 +08002249 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
developer86035662023-06-28 19:21:12 +08002250 unsigned long preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
developerc14d83a2023-06-29 20:09:42 +08002251 long int rssi;
2252 long int tmp_l;
2253 unsigned long tmp_ul;
developera3511852023-06-14 14:12:59 +08002254 size_t len = 0;
2255 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08002256
developera3511852023-06-14 14:12:59 +08002257 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002258
developera3511852023-06-14 14:12:59 +08002259 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2260 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002261 res = snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
2262 if (os_snprintf_error(sizeof(cmd), res)) {
2263 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2264 return RETURN_ERR;
2265 }
2266
developera3511852023-06-14 14:12:59 +08002267 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +08002268 if (hal_strtol(buf, 10, &rssi) < 0) {
2269 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2270 }
2271 outputChannelStats2->ch_Max80211Rssi = rssi;
developer72fb0bb2023-01-11 09:46:29 +08002272
developera3511852023-06-14 14:12:59 +08002273 memset(cmd, 0, sizeof(cmd));
2274 memset(buf, 0, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08002275 res = snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
2276 if (os_snprintf_error(sizeof(cmd), res)) {
2277 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2278 return RETURN_ERR;
2279 }
developera3511852023-06-14 14:12:59 +08002280 if ((f = popen(cmd, "r")) == NULL) {
2281 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
2282 return RETURN_ERR;
2283 }
developer72fb0bb2023-01-11 09:46:29 +08002284
developera3511852023-06-14 14:12:59 +08002285 read = getline(&line, &len, f);
2286 while (read != -1) {
2287 param = strtok(line, ":\t");
developerc14d83a2023-06-29 20:09:42 +08002288 if (!param) {
2289 read = getline(&line, &len, f);
2290 continue;
2291 }
developera3511852023-06-14 14:12:59 +08002292 value = strtok(NULL, " ");
developerc14d83a2023-06-29 20:09:42 +08002293 if (!value) {
developer37646972023-06-29 10:58:43 +08002294 read = getline(&line, &len, f);
2295 continue;
2296 }
developera3511852023-06-14 14:12:59 +08002297 if(strstr(param, "frequency") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08002298 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
2299 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2300 }
2301 outputChannelStats2->ch_Frequency = tmp_ul;
developera3511852023-06-14 14:12:59 +08002302 }
2303 if(strstr(param, "noise") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08002304 if (hal_strtol(value, 10, &tmp_l) < 0) {
2305 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2306 }
2307 outputChannelStats2->ch_NoiseFloor = tmp_l;
developer37646972023-06-29 10:58:43 +08002308
developerc14d83a2023-06-29 20:09:42 +08002309 if (hal_strtol(value, 10, &tmp_l) < 0) {
2310 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2311 }
2312 outputChannelStats2->ch_Non80211Noise = tmp_l;
developera3511852023-06-14 14:12:59 +08002313 }
2314 if(strstr(param, "channel active time") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08002315 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
2316 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2317 }
2318 ActiveTime = tmp_ul;
developera3511852023-06-14 14:12:59 +08002319 }
developerc14d83a2023-06-29 20:09:42 +08002320 if(strstr(param, "channel busy time") != NULL) {
2321 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
2322 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2323 }
2324 BusyTime = tmp_ul;
developera3511852023-06-14 14:12:59 +08002325 }
2326 if(strstr(param, "channel transmit time") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08002327 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
2328 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2329 }
2330 TransmitTime = tmp_ul;
developera3511852023-06-14 14:12:59 +08002331 }
2332 read = getline(&line, &len, f);
2333 }
2334 pclose(f);
developer72fb0bb2023-01-11 09:46:29 +08002335
developera3511852023-06-14 14:12:59 +08002336 // The file should store the last active, busy and transmit time
developere40952c2023-06-15 18:46:43 +08002337 res = snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2338 if (os_snprintf_error(sizeof(channel_util_file), res)) {
2339 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2340 return RETURN_ERR;
2341 }
2342
developera3511852023-06-14 14:12:59 +08002343 f = fopen(channel_util_file, "r");
2344 if (f != NULL) {
2345 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002346 if (hal_strtoul(line, 10, &preActiveTime) < 0) {
2347 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerc14d83a2023-06-29 20:09:42 +08002348 if (fclose(f) != 0) {
2349 wifi_debug(DEBUG_ERROR, "fclose fail\n");
2350 }
developer86035662023-06-28 19:21:12 +08002351 return RETURN_ERR;
2352 }
developera3511852023-06-14 14:12:59 +08002353 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002354 if (hal_strtoul(line, 10, &preBusyTime) < 0) {
2355 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerc14d83a2023-06-29 20:09:42 +08002356 if (fclose(f) != 0) {
2357 wifi_debug(DEBUG_ERROR, "fclose fail\n");
2358 }
developer86035662023-06-28 19:21:12 +08002359 return RETURN_ERR;
2360 }
developera3511852023-06-14 14:12:59 +08002361 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002362 if (hal_strtoul(line, 10, &preTransmitTime) < 0) {
2363 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerc14d83a2023-06-29 20:09:42 +08002364 if (fclose(f) != 0) {
2365 wifi_debug(DEBUG_ERROR, "fclose fail\n");
2366 }
developer86035662023-06-28 19:21:12 +08002367 return RETURN_ERR;
2368 }
developerc14d83a2023-06-29 20:09:42 +08002369
2370 if (fclose(f) == EOF)
2371 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
2372
2373 }
2374
2375 if (ActiveTime == preActiveTime) {
2376 wifi_debug(DEBUG_ERROR, "error:ActiveTime == preActiveTime\n");
2377 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08002378 }
developer72fb0bb2023-01-11 09:46:29 +08002379
developera3511852023-06-14 14:12:59 +08002380 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2381 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
developer72fb0bb2023-01-11 09:46:29 +08002382
developera3511852023-06-14 14:12:59 +08002383 f = fopen(channel_util_file, "w");
2384 if (f != NULL) {
developer86035662023-06-28 19:21:12 +08002385 if (fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime) < 0) {
2386 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
2387 }
2388 if (fclose(f) != 0) {
2389 wifi_debug(DEBUG_ERROR, "fclose fail\n");
2390 }
developera3511852023-06-14 14:12:59 +08002391 }
2392 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2393 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002394}
2395
2396/**********************************************************************************
2397 *
2398 * Wifi radio level function prototypes
2399 *
2400**********************************************************************************/
2401
2402//Get the total number of radios in this wifi subsystem
2403INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2404{
developera3511852023-06-14 14:12:59 +08002405 if (NULL == output)
2406 return RETURN_ERR;
2407 *output = MAX_NUM_RADIOS;
developer72fb0bb2023-01-11 09:46:29 +08002408
developera3511852023-06-14 14:12:59 +08002409 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002410}
2411
developer69b61b02023-03-07 17:17:44 +08002412//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002413INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2414{
developera3511852023-06-14 14:12:59 +08002415 if (NULL == output)
2416 return RETURN_ERR;
2417 *output = MAX_APS;
developer72fb0bb2023-01-11 09:46:29 +08002418
developera3511852023-06-14 14:12:59 +08002419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002420}
2421
2422//Get the Radio enable config parameter
developera3511852023-06-14 14:12:59 +08002423INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002424{
developer56fbedb2023-05-30 16:47:05 +08002425 char interface_name[16] = {0};
2426 char buf[128] = {0}, cmd[128] = {0};
2427 int apIndex;
2428 int max_radio_num = 0;
developer75bd10c2023-06-27 11:34:08 +08002429 int res;
developer3a85ab82023-05-25 11:59:38 +08002430
developer56fbedb2023-05-30 16:47:05 +08002431 if (NULL == output_bool)
2432 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002433
developer56fbedb2023-05-30 16:47:05 +08002434 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08002435
developer56fbedb2023-05-30 16:47:05 +08002436 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002437
developer56fbedb2023-05-30 16:47:05 +08002438 if (radioIndex >= max_radio_num)
2439 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002440
developer56fbedb2023-05-30 16:47:05 +08002441 /* loop all interface in radio, if any is enable, reture true, else return false */
2442 for(apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num)
2443 {
2444 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2445 continue;
2446 memset(cmd, 0, sizeof(cmd));
developer75bd10c2023-06-27 11:34:08 +08002447 res = snprintf(cmd, sizeof(cmd), "ifconfig %s 2> /dev/null | grep UP", interface_name);
2448 if (os_snprintf_error(sizeof(cmd), res)) {
2449 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2450 return RETURN_ERR;
2451 }
developer56fbedb2023-05-30 16:47:05 +08002452 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? FALSE : TRUE;
2453 if (*output_bool == TRUE)
2454 break;
2455 }
2456
2457 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002458}
2459
developere82c0ca2023-05-10 16:25:35 +08002460typedef long time_t;
2461static time_t radio_up_time[MAX_NUM_RADIOS];
2462
developer72fb0bb2023-01-11 09:46:29 +08002463INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2464{
developera3511852023-06-14 14:12:59 +08002465 char interface_name[16] = {0};
2466 char cmd[MAX_CMD_SIZE] = {0};
2467 char buf[MAX_BUF_SIZE] = {0};
2468 int apIndex;
2469 int max_radio_num = 0;
developere40952c2023-06-15 18:46:43 +08002470 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002471
developera3511852023-06-14 14:12:59 +08002472 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002473
developera3511852023-06-14 14:12:59 +08002474 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002475
developera3511852023-06-14 14:12:59 +08002476 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002477
developera3511852023-06-14 14:12:59 +08002478 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002479
2480 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2481 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002482
2483 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
2484 if (os_snprintf_error(sizeof(cmd), res)) {
2485 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2486 return RETURN_ERR;
2487 }
developer47cc27a2023-05-17 23:09:58 +08002488
developer8a3bbbf2023-03-15 17:47:23 +08002489 _syscmd(cmd, buf, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +08002490 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08002491 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
2492 if (os_snprintf_error(sizeof(cmd), res)) {
2493 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2494 return RETURN_ERR;
2495 }
developer56fbedb2023-05-30 16:47:05 +08002496 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002497 if(strncmp(buf, "OK", 2))
developer75bd10c2023-06-27 11:34:08 +08002498 wifi_debug(DEBUG_ERROR, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002499 } else {
developere82c0ca2023-05-10 16:25:35 +08002500 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developera3511852023-06-14 14:12:59 +08002501 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2502 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002503
developer8a3bbbf2023-03-15 17:47:23 +08002504 memset(cmd, 0, MAX_CMD_SIZE);
2505 memset(buf, 0, MAX_BUF_SIZE);
2506
developere40952c2023-06-15 18:46:43 +08002507 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2508 if (os_snprintf_error(sizeof(cmd), res)) {
2509 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2510 return RETURN_ERR;
2511 }
developera3511852023-06-14 14:12:59 +08002512 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002513
developera3511852023-06-14 14:12:59 +08002514 if(*buf == '1') {
developere40952c2023-06-15 18:46:43 +08002515 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
2516 if (os_snprintf_error(sizeof(cmd), res)) {
2517 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2518 return RETURN_ERR;
2519 }
developer56fbedb2023-05-30 16:47:05 +08002520 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002521
2522 memset(cmd, 0, MAX_CMD_SIZE);
2523 memset(buf, 0, MAX_BUF_SIZE);
2524
developere40952c2023-06-15 18:46:43 +08002525 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
developera3511852023-06-14 14:12:59 +08002526 phyId, apIndex);
developere40952c2023-06-15 18:46:43 +08002527 if (os_snprintf_error(sizeof(cmd), res)) {
2528 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2529 return RETURN_ERR;
2530 }
developera3511852023-06-14 14:12:59 +08002531 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002532
developera3511852023-06-14 14:12:59 +08002533 }
2534 }
developere75ba632023-06-29 16:03:33 +08002535 if (time(&radio_up_time[radioIndex]) < 0) {
2536 wifi_debug(DEBUG_ERROR, "GET time fail\n");
2537 return RETURN_ERR;
2538 }
developera3511852023-06-14 14:12:59 +08002539 }
developer72fb0bb2023-01-11 09:46:29 +08002540
developera3511852023-06-14 14:12:59 +08002541 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2542 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002543}
2544
2545//Get the Radio enable status
2546INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2547{
developera3511852023-06-14 14:12:59 +08002548 if (NULL == output_bool)
2549 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002550
developera3511852023-06-14 14:12:59 +08002551 return wifi_getRadioEnable(radioIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08002552}
2553
2554//Get the Radio Interface name from platform, eg "wlan0"
2555INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2556{
developera3511852023-06-14 14:12:59 +08002557 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2558 return RETURN_ERR;
2559 return wifi_GetInterfaceName(radioIndex, output_string);
developer72fb0bb2023-01-11 09:46:29 +08002560}
2561
developer6e578302023-06-21 10:11:16 +08002562int mtk_get_vow_info_callback(struct nl_msg *msg, void *data)
2563{
2564 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2565 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX + 1];
2566 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2567 int err = 0;
2568 struct vow_info *vow_info = NULL;
2569 struct mtk_nl80211_cb_data *cb_data = data;
2570
2571 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2572 genlmsg_attrlen(gnlh, 0), NULL);
2573 if (err < 0) {
2574 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
2575 return err;
2576 }
2577
2578 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2579 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX,
2580 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2581 if (err < 0){
2582 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX fails\n");
2583 return err;
2584 }
2585
2586 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]) {
2587 vow_info = (struct vow_info *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]);
2588 memmove(cb_data->out_buf, vow_info, sizeof(struct vow_info));
2589 }
2590 }
2591
2592 return 0;
2593}
2594
2595INT mtk_wifi_set_air_time_management(
2596 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
2597 char* data, INT len, void *output)
2598{
2599 char inf_name[IF_NAME_SIZE] = {0};
2600 unsigned int if_idx = 0;
2601 int ret = -1;
2602 struct unl unl_ins;
2603 struct nl_msg *msg = NULL;
2604 struct nlattr * msg_data = NULL;
2605 struct mtk_nl80211_param param;
2606
2607 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
2608 return RETURN_ERR;
2609 if_idx = if_nametoindex(inf_name);
2610 if (!if_idx) {
2611 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
2612 return RETURN_ERR;
2613 }
2614 /*init mtk nl80211 vendor cmd*/
2615 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_VOW;
2616 param.if_type = NL80211_ATTR_IFINDEX;
2617 param.if_idx = if_idx;
2618
2619 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
2620 if (ret) {
2621 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
2622 return RETURN_ERR;
2623 }
2624 /*add mtk vendor cmd data*/
2625 if (nla_put(msg, vendor_data_attr, len, data)) {
2626 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
2627 nlmsg_free(msg);
2628 goto err;
2629 }
2630
2631 /*send mtk nl80211 vendor msg*/
2632 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
2633 if (ret) {
2634 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
2635 goto err;
2636 }
2637 /*deinit mtk nl80211 vendor msg*/
2638 mtk_nl80211_deint(&unl_ins);
2639 wifi_debug(DEBUG_INFO, "send cmd success.\n");
2640
2641 return RETURN_OK;
2642err:
2643 mtk_nl80211_deint(&unl_ins);
2644 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
2645 return RETURN_ERR;
2646}
2647
2648//Get the ATM(Air Time Management) Capable.
2649INT wifi_getATMCapable(BOOL *output_bool)
2650{
2651 if (NULL == output_bool)
2652 return RETURN_ERR;
2653 *output_bool = TRUE;
2654
2655 return RETURN_OK;
2656}
2657
2658INT wifi_setATMEnable(BOOL enable)
2659{
2660 int max_radio_num = 0;
2661 int radio_idx = 0;
2662 char dat_file[MAX_BUF_SIZE] = {0};
2663 int res;
2664 struct params params[2];
2665
2666 wifi_getMaxRadioNumber(&max_radio_num);
2667 for (radio_idx = 0; radio_idx < max_radio_num; radio_idx++) {
2668 if (mtk_wifi_set_air_time_management
2669 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO,
2670 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
2671 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
2672 return RETURN_ERR;
2673 }
2674
2675 if (mtk_wifi_set_air_time_management
2676 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_BW_EN_INFO,
2677 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
2678 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
2679 return RETURN_ERR;
2680 }
2681
2682 params[0].name = "VOW_Airtime_Fairness_En";
2683 params[0].value = enable ? "1" : "0";
2684 params[1].name = "VOW_BW_Ctrl";
2685 params[1].value = enable ? "1" : "0";
2686
2687 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
2688 if (os_snprintf_error(sizeof(dat_file), res)) {
2689 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2690 return RETURN_ERR;
2691 }
2692 wifi_datfileWrite(dat_file, params, 2);
2693 }
2694
2695 return RETURN_OK;
2696}
2697
2698INT wifi_getATMEnable(BOOL *output_enable)
2699{
2700 int max_radio_num = 0;
2701 int radio_idx = 0;
2702 struct vow_info vow_info;
2703 struct vow_info get_vow_info;
2704 struct mtk_nl80211_cb_data cb_data;
2705
2706 if (output_enable == NULL)
2707 return RETURN_ERR;
2708
2709 wifi_getMaxRadioNumber(&max_radio_num);
2710
2711 *output_enable = FALSE;
2712
2713 memset(&vow_info, 0, sizeof(struct vow_info));
2714
2715 cb_data.out_buf = (char *)&vow_info;
2716 cb_data.out_len = sizeof(struct vow_info);
2717
2718 for (radio_idx = 0; radio_idx < max_radio_num; radio_idx++) {
2719 if (mtk_wifi_set_air_time_management
2720 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2721 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2722 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2723 return RETURN_ERR;
2724 }
2725
2726 if (vow_info.atf_en == TRUE || vow_info.bw_en == TRUE) {
2727 *output_enable = TRUE;
2728 break;
2729 }
2730 }
2731
2732 return RETURN_OK;
2733}
2734
2735UINT apidx_to_group(INT apIndex)
2736{
2737 int max_radio_num = 0;
2738 unsigned int group = 0;
2739
2740 wifi_getMaxRadioNumber(&max_radio_num);
developerc14d83a2023-06-29 20:09:42 +08002741 if (max_radio_num == 0) {
2742 wifi_debug(DEBUG_ERROR, "invalid max radio num\n");
2743 return 0;
2744 }
developer6e578302023-06-21 10:11:16 +08002745 group = apIndex / max_radio_num + 5 * (apIndex % max_radio_num);
2746
2747 return group;
2748}
2749
2750INT wifi_setApATMAirTimePercent(INT apIndex, UINT ap_AirTimePercent)
2751{
2752 struct vow_group_en_param atc_en_param;
2753 struct vow_ratio_param radio_param;
2754 unsigned int group = 0;
2755 //BOOL ATM_enable = FALSE;
2756
2757 if (ap_AirTimePercent < 5 || ap_AirTimePercent > 100) {
2758 wifi_debug(DEBUG_ERROR, "invalid ait time percent!\n");
2759 return RETURN_ERR;
2760 }
2761
2762 /* mt7990 support 15 group now*/
2763 group = apidx_to_group(apIndex);
2764
2765 if (group > 15) {
2766 wifi_debug(DEBUG_ERROR, "invalid group!\n");
2767 return RETURN_ERR;
2768 }
2769
2770 atc_en_param.group = group;
2771 atc_en_param.en = 1;
2772 if (mtk_wifi_set_air_time_management
2773 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO,
2774 NULL, (char *)&atc_en_param, sizeof(struct vow_group_en_param), NULL)!= RETURN_OK) {
2775 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO cmd fails\n");
2776 return RETURN_ERR;
2777 }
2778
2779 radio_param.group = group;
2780 radio_param.ratio = ap_AirTimePercent;
2781 if (mtk_wifi_set_air_time_management
2782 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO,
2783 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
2784 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO cmd fails\n");
2785 return RETURN_ERR;
2786 }
2787
2788 if (mtk_wifi_set_air_time_management
2789 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO,
2790 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
2791 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO cmd fails\n");
2792 return RETURN_ERR;
2793 }
2794
2795 return RETURN_OK;
2796}
2797
2798INT wifi_getApATMAirTimePercent(INT apIndex, UINT *output_ap_AirTimePercent)
2799{
2800 unsigned int group = 0;
2801 struct vow_info get_vow_info, vow_info;
2802 struct mtk_nl80211_cb_data cb_data;
2803
2804 if (output_ap_AirTimePercent == NULL)
2805 return RETURN_ERR;
2806
2807 group = apidx_to_group(apIndex);
2808 if (group > 15) {
2809 wifi_debug(DEBUG_ERROR, "invalid group!\n");
2810 return RETURN_ERR;
2811 }
2812
2813 memset(&vow_info, 0, sizeof(struct vow_info));
2814 memset(&get_vow_info, 0, sizeof(struct vow_info));
2815
2816 cb_data.out_buf = (char *)&vow_info;
2817 cb_data.out_len = sizeof(struct vow_info);
2818
2819 get_vow_info.group = group;
2820
2821 if (mtk_wifi_set_air_time_management
2822 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2823 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2824 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2825 return RETURN_ERR;
2826 }
2827
2828 *output_ap_AirTimePercent = vow_info.ratio;
2829
2830 return RETURN_ERR;
2831}
2832
developerd14dff12023-06-28 22:47:44 +08002833INT wifi_getApATMSta(INT apIndex, UCHAR *output_sta_MAC_ATM_array, UINT buf_size)
2834{
2835 ULONG dev_num = 0;
2836 struct vow_info vow_info;
2837 struct vow_info get_vow_info;
2838 struct mtk_nl80211_cb_data cb_data;
2839 unsigned int percent;
2840 char assocArray[MAX_BUF_SIZE] = {0};
2841 char *mac = NULL;
2842 unsigned char output_len = 0;
2843 int res;
2844 char buf[MAX_BUF_SIZE] = {0};
2845
2846 memset(&vow_info, 0, sizeof(struct vow_info));
2847 memset(&get_vow_info, 0, sizeof(struct vow_info));
2848
2849 cb_data.out_buf = (char *)&vow_info;
2850 cb_data.out_len = sizeof(struct vow_info);
2851
2852 if (mtk_wifi_set_air_time_management
2853 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2854 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2855 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2856 return RETURN_ERR;
2857 }
2858
2859 if (vow_info.atf_en == FALSE) {
2860 wifi_debug(DEBUG_ERROR, "ATF disable!\n");
2861 return RETURN_ERR;
2862 }
2863
2864 if (wifi_getApNumDevicesAssociated(apIndex, &dev_num) != RETURN_OK) {
2865 wifi_debug(DEBUG_ERROR, "get sta num fail!\n");
2866 return RETURN_ERR;;
2867 }
2868
2869 percent = 100 / dev_num;
2870
2871 if (wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray)) != RETURN_OK){
2872 wifi_debug(DEBUG_ERROR, "get sta mac fail!\n");
2873 return RETURN_ERR;;
2874 }
2875
2876 memset(output_sta_MAC_ATM_array, 0, MAX_BUF_SIZE);
2877
2878 mac = strtok(assocArray, "\n");
2879 while (mac != NULL) {
2880 if (strlen(mac) >= 17) {
2881 res = snprintf(buf, sizeof(buf), "%s %d|", mac, percent);
2882
2883 if (os_snprintf_error(sizeof(buf), res)) {
2884 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2885 return RETURN_ERR;
2886 }
2887
2888 if (output_len + strlen(buf) > buf_size)
2889 break;
2890
2891 strncat((char *)output_sta_MAC_ATM_array, buf, strlen(buf));
2892
2893 output_len += strlen(buf);
2894 }
2895
2896 mac = strtok(NULL, "\n");
2897 }
2898
2899 /* Remove the last | */
2900 if (strlen((char *)output_sta_MAC_ATM_array) != 0)
2901 output_sta_MAC_ATM_array[strlen((char *)output_sta_MAC_ATM_array)-1] = '\0';
2902
2903 return RETURN_OK;
2904}
2905
2906INT wifi_setApATMSta(INT apIndex, UCHAR *sta_MAC_ATM_array, UINT ap_AirTimePercent)
2907{
2908 return RETURN_ERR;
2909}
developer9ce44382023-06-28 11:09:37 +08002910
developer72fb0bb2023-01-11 09:46:29 +08002911//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2912//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.
2913INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2914{
developera3511852023-06-14 14:12:59 +08002915 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2916 // For max bit rate, we should always choose the best MCS
2917 char mode[64] = {0};
2918 char channel_bandwidth_str[64] = {0};
2919 UINT mode_map = 0;
2920 UINT num_subcarrier = 0;
2921 UINT code_bits = 0;
2922 float code_rate = 0; // use max code rate
2923 int NSS = 0;
2924 UINT Symbol_duration = 0;
2925 UINT GI_duration = 0;
2926 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2927 BOOL enable = FALSE;
2928 float bit_rate = 0;
developere40952c2023-06-15 18:46:43 +08002929 int ant_bitmap = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002930
developera3511852023-06-14 14:12:59 +08002931 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2932 if (NULL == output_string)
2933 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002934
developera3511852023-06-14 14:12:59 +08002935 wifi_getRadioEnable(radioIndex, &enable);
2936 if (enable == FALSE) {
developere40952c2023-06-15 18:46:43 +08002937 res = snprintf(output_string, 64, "0 Mb/s");
2938 if (os_snprintf_error(64, res)) {
2939 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2940 return RETURN_ERR;
2941 }
developera3511852023-06-14 14:12:59 +08002942 return RETURN_OK;
2943 }
developer72fb0bb2023-01-11 09:46:29 +08002944
developera3511852023-06-14 14:12:59 +08002945 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08002946 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +08002947 return RETURN_ERR;
2948 }
developer72fb0bb2023-01-11 09:46:29 +08002949
developera3511852023-06-14 14:12:59 +08002950 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08002951 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +08002952 return RETURN_ERR;
2953 }
developer72fb0bb2023-01-11 09:46:29 +08002954
developera3511852023-06-14 14:12:59 +08002955 if (gi == wifi_guard_interval_3200)
2956 GI_duration = 32;
2957 else if (gi == wifi_guard_interval_1600)
2958 GI_duration = 16;
2959 else if (gi == wifi_guard_interval_800)
2960 GI_duration = 8;
2961 else // auto, 400
2962 GI_duration = 4;
developer72fb0bb2023-01-11 09:46:29 +08002963
developera3511852023-06-14 14:12:59 +08002964 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08002965 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error\n");
developera3511852023-06-14 14:12:59 +08002966 return RETURN_ERR;
2967 }
developer72fb0bb2023-01-11 09:46:29 +08002968
developera3511852023-06-14 14:12:59 +08002969 if (strstr(channel_bandwidth_str, "80+80") != NULL)
developer32f2a182023-06-27 19:50:41 +08002970 memcpy(channel_bandwidth_str, "160", strlen("160"));
developer72fb0bb2023-01-11 09:46:29 +08002971
developera3511852023-06-14 14:12:59 +08002972 if (mode_map & WIFI_MODE_AX) {
2973 if (strstr(channel_bandwidth_str, "160") != NULL)
2974 num_subcarrier = 1960;
2975 else if (strstr(channel_bandwidth_str, "80") != NULL)
2976 num_subcarrier = 980;
2977 else if (strstr(channel_bandwidth_str, "40") != NULL)
2978 num_subcarrier = 468;
2979 else if (strstr(channel_bandwidth_str, "20") != NULL)
2980 num_subcarrier = 234;
2981 code_bits = 10;
2982 code_rate = (float)5/6;
2983 Symbol_duration = 128;
2984 GI_duration = 8;/*HE no GI 400ns*/
2985 } else if (mode_map & WIFI_MODE_AC) {
2986 if (strstr(channel_bandwidth_str, "160") != NULL)
2987 num_subcarrier = 468;
2988 else if (strstr(channel_bandwidth_str, "80") != NULL)
2989 num_subcarrier = 234;
2990 else if (strstr(channel_bandwidth_str, "40") != NULL)
2991 num_subcarrier = 108;
2992 else if (strstr(channel_bandwidth_str, "20") != NULL)
2993 num_subcarrier = 52;
2994 code_bits = 8;
2995 code_rate = (float)5/6;
2996 Symbol_duration = 32;
2997 } else if (mode_map & WIFI_MODE_N) {
2998 if (strstr(channel_bandwidth_str, "160") != NULL)
2999 num_subcarrier = 468;
3000 else if (strstr(channel_bandwidth_str, "80") != NULL)
3001 num_subcarrier = 234;
3002 else if (strstr(channel_bandwidth_str, "40") != NULL)
3003 num_subcarrier = 108;
3004 else if (strstr(channel_bandwidth_str, "20") != NULL)
3005 num_subcarrier = 52;
3006 code_bits = 6;
3007 code_rate = (float)3/4;
3008 Symbol_duration = 32;
3009 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
3010 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
developere40952c2023-06-15 18:46:43 +08003011 res = snprintf(output_string, 64, "65 Mb/s");
3012 if (os_snprintf_error(64, res)) {
3013 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3014 return RETURN_ERR;
3015 }
developera3511852023-06-14 14:12:59 +08003016 return RETURN_OK;
3017 } else {
developere40952c2023-06-15 18:46:43 +08003018 res = snprintf(output_string, 64, "0 Mb/s");
3019 if (os_snprintf_error(64, res)) {
3020 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3021 return RETURN_ERR;
3022 }
developera3511852023-06-14 14:12:59 +08003023 return RETURN_OK;
3024 }
developer72fb0bb2023-01-11 09:46:29 +08003025
developera3511852023-06-14 14:12:59 +08003026 // Spatial streams
3027 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08003028 wifi_debug(DEBUG_ERROR, "wifi_getRadioTxChainMask return error\n");
developera3511852023-06-14 14:12:59 +08003029 return RETURN_ERR;
3030 }
3031 for (; ant_bitmap > 0; ant_bitmap >>= 1)
3032 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08003033
developera3511852023-06-14 14:12:59 +08003034 // multiple 10 is to align duration unit (0.1 us)
3035 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
developere40952c2023-06-15 18:46:43 +08003036 res = snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
3037 if (os_snprintf_error(64, res)) {
3038 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3039 return RETURN_ERR;
3040 }
developera3511852023-06-14 14:12:59 +08003041 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
3042 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
3043 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003044
developera3511852023-06-14 14:12:59 +08003045 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003046}
developer72fb0bb2023-01-11 09:46:29 +08003047
3048//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
3049//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.
3050INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
3051{
developera3511852023-06-14 14:12:59 +08003052 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003053
developera3511852023-06-14 14:12:59 +08003054 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3055 if (NULL == output_string)
3056 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003057
developera3511852023-06-14 14:12:59 +08003058 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003059
developera3511852023-06-14 14:12:59 +08003060 memset(output_string, 0, 10);
3061 if (band == band_2_4)
developer32f2a182023-06-27 19:50:41 +08003062 memcpy(output_string, "2.4GHz", strlen("2.4GHz"));
developera3511852023-06-14 14:12:59 +08003063 else if (band == band_5)
developer32f2a182023-06-27 19:50:41 +08003064 memcpy(output_string, "5GHz", strlen("5GHz"));
developera3511852023-06-14 14:12:59 +08003065 else if (band == band_6)
developer32f2a182023-06-27 19:50:41 +08003066 memcpy(output_string, "6GHz", strlen("6GHz"));
developera3511852023-06-14 14:12:59 +08003067 else
3068 return RETURN_ERR;
3069 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003070
developera3511852023-06-14 14:12:59 +08003071 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003072}
3073
3074//Get the frequency band at which the radio is operating, eg: "2.4GHz"
3075//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.
3076INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
3077{
developera3511852023-06-14 14:12:59 +08003078 wifi_band band = band_invalid;
developer9ce44382023-06-28 11:09:37 +08003079 int res = -1;
developere40952c2023-06-15 18:46:43 +08003080
developera3511852023-06-14 14:12:59 +08003081 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3082 if (NULL == output_string)
3083 return RETURN_ERR;
3084 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003085
developera3511852023-06-14 14:12:59 +08003086 if (band == band_2_4)
developere40952c2023-06-15 18:46:43 +08003087 res = snprintf(output_string, 64, "2.4GHz");
developera3511852023-06-14 14:12:59 +08003088 else if (band == band_5)
developere40952c2023-06-15 18:46:43 +08003089 res = snprintf(output_string, 64, "5GHz");
developera3511852023-06-14 14:12:59 +08003090 else if (band == band_6)
developere40952c2023-06-15 18:46:43 +08003091 res = snprintf(output_string, 64, "6GHz");
developer72fb0bb2023-01-11 09:46:29 +08003092
developere40952c2023-06-15 18:46:43 +08003093 if (os_snprintf_error(64, res)) {
3094 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3095 return RETURN_ERR;
3096 }
developera3511852023-06-14 14:12:59 +08003097 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003098
developera3511852023-06-14 14:12:59 +08003099 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003100}
3101
3102//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
3103//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.
3104INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
3105{
developera3511852023-06-14 14:12:59 +08003106 char cmd[128]={0};
3107 char buf[128]={0};
3108 char temp_output[128] = {0};
3109 wifi_band band;
developere40952c2023-06-15 18:46:43 +08003110 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08003111
developera3511852023-06-14 14:12:59 +08003112 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3113 if (NULL == output_string)
3114 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003115
developera3511852023-06-14 14:12:59 +08003116 band = wifi_index_to_band(radioIndex);
3117 if (band == band_2_4) {
developer32f2a182023-06-27 19:50:41 +08003118 strncat(temp_output, "b,g,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003119 } else if (band == band_5) {
developer32f2a182023-06-27 19:50:41 +08003120 strncat(temp_output, "a,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003121 }
3122 phyId = radio_index_to_phy(radioIndex);
3123 // ht capabilities
developere40952c2023-06-15 18:46:43 +08003124 res = 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);
3125 if (os_snprintf_error(sizeof(cmd), res)) {
3126 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3127 return RETURN_ERR;
3128 }
developera3511852023-06-14 14:12:59 +08003129 _syscmd(cmd, buf, sizeof(buf));
3130 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
developer32f2a182023-06-27 19:50:41 +08003131 if (strlen(temp_output) >= sizeof(temp_output) - 2)
3132 return RETURN_ERR;
3133 strncat(temp_output, "n,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003134 }
developer72fb0bb2023-01-11 09:46:29 +08003135
developera3511852023-06-14 14:12:59 +08003136 // vht capabilities
3137 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08003138 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
3139 if (os_snprintf_error(sizeof(cmd), res)) {
3140 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3141 return RETURN_ERR;
3142 }
3143 _syscmd(cmd, buf, sizeof(buf));
3144 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
developer32f2a182023-06-27 19:50:41 +08003145 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3146 return RETURN_ERR;
developerc14d83a2023-06-29 20:09:42 +08003147 strncat(temp_output, "ac,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003148 }
3149 }
developer72fb0bb2023-01-11 09:46:29 +08003150
developera3511852023-06-14 14:12:59 +08003151 // he capabilities
developere40952c2023-06-15 18:46:43 +08003152 res = 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);
3153 if (os_snprintf_error(sizeof(cmd), res)) {
3154 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3155 return RETURN_ERR;
3156 }
developera3511852023-06-14 14:12:59 +08003157 _syscmd(cmd, buf, sizeof(buf));
3158 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08003159 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3160 return RETURN_ERR;
3161 strncat(temp_output, "ax,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003162 }
developer72fb0bb2023-01-11 09:46:29 +08003163
developere82c0ca2023-05-10 16:25:35 +08003164 // eht capabilities
developere40952c2023-06-15 18:46:43 +08003165 res = 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);
3166 if (os_snprintf_error(sizeof(cmd), res)) {
3167 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3168 return RETURN_ERR;
3169 }
developera3511852023-06-14 14:12:59 +08003170 _syscmd(cmd, buf, sizeof(buf));
3171 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08003172 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3173 return RETURN_ERR;
3174 strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003175 }
developere82c0ca2023-05-10 16:25:35 +08003176
developera3511852023-06-14 14:12:59 +08003177 // Remove the last comma
3178 if (strlen(temp_output) != 0)
3179 temp_output[strlen(temp_output)-1] = '\0';
3180 strncpy(output_string, temp_output, strlen(temp_output));
3181 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3182 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003183}
3184
3185//Get the radio operating mode, and pure mode flag. eg: "ac"
3186//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.
3187INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
3188{
developere40952c2023-06-15 18:46:43 +08003189 int res;
3190
developera3511852023-06-14 14:12:59 +08003191 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3192 if (NULL == output_string)
3193 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003194
developera3511852023-06-14 14:12:59 +08003195 if (radioIndex == 0) {
developere40952c2023-06-15 18:46:43 +08003196 res = snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
3197 if (os_snprintf_error(64, res)) {
3198 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3199 return RETURN_ERR;
3200 }
developera3511852023-06-14 14:12:59 +08003201 *gOnly = FALSE;
3202 *nOnly = TRUE;
3203 *acOnly = FALSE;
3204 } else {
developere40952c2023-06-15 18:46:43 +08003205 res = snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
3206 if (os_snprintf_error(64, res)) {
3207 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3208 return RETURN_ERR;
3209 }
developera3511852023-06-14 14:12:59 +08003210 *gOnly = FALSE;
3211 *nOnly = FALSE;
3212 *acOnly = FALSE;
3213 }
3214 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003215
developera3511852023-06-14 14:12:59 +08003216 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003217}
3218
developer0f10c772023-05-16 21:43:39 +08003219enum WIFI_MODE {
3220 WMODE_INVALID = 0,
3221 WMODE_A = 1 << 0,
3222 WMODE_B = 1 << 1,
3223 WMODE_G = 1 << 2,
3224 WMODE_GN = 1 << 3,
3225 WMODE_AN = 1 << 4,
3226 WMODE_AC = 1 << 5,
3227 WMODE_AX_24G = 1 << 6,
3228 WMODE_AX_5G = 1 << 7,
3229 WMODE_AX_6G = 1 << 8,
3230 WMODE_BE_24G = 1 << 9,
3231 WMODE_BE_5G = 1 << 10,
3232 WMODE_BE_6G = 1 << 11,
3233 /*
3234 * total types of supported wireless mode,
3235 * add this value once yow add new type
3236 */
3237 WMODE_COMP = 12,
3238};
3239
3240#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08003241
3242int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08003243{
developerfead3972023-05-25 20:15:02 +08003244 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3245 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
developerc14d83a2023-06-29 20:09:42 +08003246 struct genlmsghdr *gnlh;
developerfead3972023-05-25 20:15:02 +08003247 unsigned int *phymode;
3248 int err = 0;
3249 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08003250
developerfead3972023-05-25 20:15:02 +08003251 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08003252 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developerfead3972023-05-25 20:15:02 +08003253 return NL_SKIP;
3254 }
developerc14d83a2023-06-29 20:09:42 +08003255 gnlh = nlmsg_data(nlmsg_hdr(msg));
developer72fb0bb2023-01-11 09:46:29 +08003256
developerfead3972023-05-25 20:15:02 +08003257 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3258 genlmsg_attrlen(gnlh, 0), NULL);
3259 if (err < 0) {
3260 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
3261 return NL_SKIP;
3262 }
developer0f10c772023-05-16 21:43:39 +08003263
developerfead3972023-05-25 20:15:02 +08003264 if (tb[NL80211_ATTR_VENDOR_DATA]) {
3265 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
3266 tb[NL80211_ATTR_VENDOR_DATA], NULL);
3267 if (err < 0)
3268 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08003269
developerfead3972023-05-25 20:15:02 +08003270 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
3271 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
3272
3273 memset(cb_data->out_buf, 0, cb_data->out_len);
3274 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
3275 }
3276 } else
3277 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
3278
3279 return NL_OK;
3280}
developer0f10c772023-05-16 21:43:39 +08003281
developerfead3972023-05-25 20:15:02 +08003282void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
3283{
3284 wifi_band band;
3285 unsigned char radio_mode_tem_len;
developere40952c2023-06-15 18:46:43 +08003286 int res;
developerfead3972023-05-25 20:15:02 +08003287
3288 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08003289 // puremode is a bit map
developera3511852023-06-14 14:12:59 +08003290 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08003291 memset(output_string, 0, RADIO_MODE_LEN);
3292
3293 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3294
3295 switch (band) {
3296 case band_2_4:
3297 if (phymode & WMODE_B) {
developere40952c2023-06-15 18:46:43 +08003298 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
3299 if (os_snprintf_error(radio_mode_tem_len, res)) {
3300 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3301 return;
3302 }
developer0f10c772023-05-16 21:43:39 +08003303 *pureMode |= WIFI_MODE_B;
3304 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3305 }
3306 if (phymode & WMODE_G) {
developere40952c2023-06-15 18:46:43 +08003307 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
3308 if (os_snprintf_error(radio_mode_tem_len, res)) {
3309 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3310 return;
3311 }
developer0f10c772023-05-16 21:43:39 +08003312 *pureMode |= WIFI_MODE_G;
3313 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3314 }
3315 if (phymode & WMODE_GN) {
developere40952c2023-06-15 18:46:43 +08003316 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3317 if (os_snprintf_error(radio_mode_tem_len, res)) {
3318 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3319 return;
3320 }
developer0f10c772023-05-16 21:43:39 +08003321 *pureMode |= WIFI_MODE_N;
3322 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3323 }
3324 if (phymode & WMODE_AX_24G) {
developere40952c2023-06-15 18:46:43 +08003325 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3326 if (os_snprintf_error(radio_mode_tem_len, res)) {
3327 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3328 return;
3329 }
developer0f10c772023-05-16 21:43:39 +08003330 *pureMode |= WIFI_MODE_AX;
3331 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3332 }
3333 if (phymode & WMODE_BE_24G) {
developere40952c2023-06-15 18:46:43 +08003334 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3335 if (os_snprintf_error(radio_mode_tem_len, res)) {
3336 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3337 return;
3338 }
developer0f10c772023-05-16 21:43:39 +08003339 *pureMode |= WIFI_MODE_BE;
3340 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3341 }
3342 break;
3343 case band_5:
3344 if (phymode & WMODE_A) {
developere40952c2023-06-15 18:46:43 +08003345 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
3346 if (os_snprintf_error(radio_mode_tem_len, res)) {
3347 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3348 return;
3349 }
developer0f10c772023-05-16 21:43:39 +08003350 *pureMode |= WIFI_MODE_A;
3351 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3352 }
3353 if (phymode & WMODE_AN) {
developere40952c2023-06-15 18:46:43 +08003354 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3355 if (os_snprintf_error(radio_mode_tem_len, res)) {
3356 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3357 return;
3358 }
developer0f10c772023-05-16 21:43:39 +08003359 *pureMode |= WIFI_MODE_N;
3360 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3361 }
3362 if (phymode & WMODE_AC) {
developere40952c2023-06-15 18:46:43 +08003363 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
3364 if (os_snprintf_error(radio_mode_tem_len, res)) {
3365 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3366 return;
3367 }
developer0f10c772023-05-16 21:43:39 +08003368 *pureMode |= WIFI_MODE_AC;
3369 }
3370 if (phymode & WMODE_AX_5G) {
developere40952c2023-06-15 18:46:43 +08003371 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3372 if (os_snprintf_error(radio_mode_tem_len, res)) {
3373 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3374 return;
3375 }
developer0f10c772023-05-16 21:43:39 +08003376 *pureMode |= WIFI_MODE_AX;
3377 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3378 }
3379 if (phymode & WMODE_BE_5G) {
developere40952c2023-06-15 18:46:43 +08003380 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3381 if (os_snprintf_error(radio_mode_tem_len, res)) {
3382 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3383 return;
3384 }
developer0f10c772023-05-16 21:43:39 +08003385 *pureMode |= WIFI_MODE_BE;
3386 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3387 }
3388 break;
3389 case band_6:
3390 if (phymode & WMODE_AX_6G) {
developere40952c2023-06-15 18:46:43 +08003391 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3392 if (os_snprintf_error(radio_mode_tem_len, res)) {
3393 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3394 return;
3395 }
developer0f10c772023-05-16 21:43:39 +08003396 *pureMode |= WIFI_MODE_AX;
3397 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3398 }
3399 if (phymode & WMODE_BE_6G) {
developere40952c2023-06-15 18:46:43 +08003400 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3401 if (os_snprintf_error(radio_mode_tem_len, res)) {
3402 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3403 return;
3404 }
developer0f10c772023-05-16 21:43:39 +08003405 *pureMode |= WIFI_MODE_BE;
3406 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3407 }
3408 break;
3409 default:
developer86035662023-06-28 19:21:12 +08003410 wifi_debug(DEBUG_ERROR, "%s band_idx invalid\n", __func__);
developer0f10c772023-05-16 21:43:39 +08003411 break;
3412 }
3413
3414 /* Remove the last comma */
3415 if (strlen(output_string) != 0)
developera3511852023-06-14 14:12:59 +08003416 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08003417
developerfead3972023-05-25 20:15:02 +08003418}
3419
3420INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
3421{
3422 unsigned int phymode;
3423 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003424 int ret = -1;
3425 unsigned int if_idx = 0;
3426 struct unl unl_ins;
3427 struct nl_msg *msg = NULL;
3428 struct nlattr * msg_data = NULL;
3429 struct mtk_nl80211_param param;
3430 struct mtk_nl80211_cb_data cb_data;
3431
developera3511852023-06-14 14:12:59 +08003432 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3433 if (NULL == output_string || NULL == pureMode)
developerdaf24792023-06-06 11:40:04 +08003434 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003435
3436 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3437 return RETURN_ERR;
3438
3439 if_idx = if_nametoindex(interface_name);
3440 if (!if_idx) {
3441 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
3442 return RETURN_ERR;
3443 }
3444 /*init mtk nl80211 vendor cmd*/
3445 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
3446 param.if_type = NL80211_ATTR_IFINDEX;
3447 param.if_idx = if_idx;
3448
3449 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3450 if (ret) {
3451 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3452 return RETURN_ERR;
3453 }
3454
3455 /*add mtk vendor cmd data*/
3456 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
3457 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
3458 nlmsg_free(msg);
3459 goto err;
3460 }
3461
3462 /*send mtk nl80211 vendor msg*/
3463 cb_data.out_buf = (char *)&phymode;
3464 cb_data.out_len = sizeof(unsigned int);
3465
3466 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
3467
3468 if (ret) {
3469 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3470 goto err;
3471 }
3472 /*deinit mtk nl80211 vendor msg*/
3473 mtk_nl80211_deint(&unl_ins);
3474
3475 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
developer6e578302023-06-21 10:11:16 +08003476 wifi_debug(DEBUG_INFO,"send cmd success\n");
developerfead3972023-05-25 20:15:02 +08003477
developera3511852023-06-14 14:12:59 +08003478 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3479 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003480err:
3481 mtk_nl80211_deint(&unl_ins);
3482 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
3483 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003484}
3485
3486// Set the radio operating mode, and pure mode flag.
3487INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
3488{
developera3511852023-06-14 14:12:59 +08003489 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
3490 if (strcmp (channelMode,"11A") == 0)
3491 {
3492 writeBandWidth(radioIndex,"20MHz");
3493 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3494 printf("\nChannel Mode is 802.11a (5GHz)\n");
3495 }
3496 else if (strcmp (channelMode,"11NAHT20") == 0)
3497 {
3498 writeBandWidth(radioIndex,"20MHz");
3499 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3500 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
3501 }
3502 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
3503 {
3504 writeBandWidth(radioIndex,"40MHz");
3505 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3506 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3507 }
3508 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
3509 {
3510 writeBandWidth(radioIndex,"40MHz");
3511 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3512 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3513 }
3514 else if (strcmp (channelMode,"11ACVHT20") == 0)
3515 {
3516 writeBandWidth(radioIndex,"20MHz");
3517 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3518 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
3519 }
3520 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
3521 {
3522 writeBandWidth(radioIndex,"40MHz");
3523 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3524 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3525 }
3526 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
3527 {
3528 writeBandWidth(radioIndex,"40MHz");
3529 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3530 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3531 }
3532 else if (strcmp (channelMode,"11ACVHT80") == 0)
3533 {
3534 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
3535 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
3536 }
3537 else if (strcmp (channelMode,"11ACVHT160") == 0)
3538 {
3539 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
3540 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
3541 }
3542 else if (strcmp (channelMode,"11B") == 0)
3543 {
3544 writeBandWidth(radioIndex,"20MHz");
3545 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3546 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
3547 }
3548 else if (strcmp (channelMode,"11G") == 0)
3549 {
3550 writeBandWidth(radioIndex,"20MHz");
3551 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3552 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
3553 }
3554 else if (strcmp (channelMode,"11NGHT20") == 0)
3555 {
3556 writeBandWidth(radioIndex,"20MHz");
3557 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3558 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3559 }
3560 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3561 {
3562 writeBandWidth(radioIndex,"40MHz");
3563 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3564 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3565 }
3566 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3567 {
3568 writeBandWidth(radioIndex,"40MHz");
3569 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3570 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3571 }
3572 else
3573 {
3574 return RETURN_ERR;
3575 }
3576 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003577
developera3511852023-06-14 14:12:59 +08003578 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003579}
3580
developer0f10c772023-05-16 21:43:39 +08003581typedef enum _RT_802_11_PHY_MODE {
3582 PHY_11BG_MIXED = 0,
3583 PHY_11B = 1,
3584 PHY_11A = 2,
3585 PHY_11ABG_MIXED = 3,
3586 PHY_11G = 4,
3587 PHY_11ABGN_MIXED = 5, /* both band 5 */
developera3511852023-06-14 14:12:59 +08003588 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3589 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3590 PHY_11AN_MIXED = 8, /* 5G band 8 */
3591 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3592 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3593 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
developer0f10c772023-05-16 21:43:39 +08003594 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3595 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3596 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3597 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3598 PHY_11AX_24G = 16,
3599 PHY_11AX_5G = 17,
3600 PHY_11AX_6G = 18,
3601 PHY_11AX_24G_6G = 19,
3602 PHY_11AX_5G_6G = 20,
3603 PHY_11AX_24G_5G_6G = 21,
3604 PHY_11BE_24G = 22,
3605 PHY_11BE_5G = 23,
3606 PHY_11BE_6G = 24,
3607 PHY_11BE_24G_6G = 25,
3608 PHY_11BE_5G_6G = 26,
3609 PHY_11BE_24G_5G_6G = 27,
3610 PHY_MODE_MAX,
3611} RT_802_11_PHY_MODE;
3612
3613unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3614{
3615 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003616 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003617
3618 band_idx = radio_index_to_band(radioIndex);
3619
3620 switch (band_idx) {
3621 case band_2_4:
3622 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3623 wireless_mode = PHY_11GN_MIXED;
3624 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3625 wireless_mode = PHY_11BGN_MIXED;
3626 if (pureMode & WIFI_MODE_AX)
3627 wireless_mode = PHY_11AX_24G;
3628 if (pureMode & WIFI_MODE_BE)
3629 wireless_mode = PHY_11BE_24G;
3630 break;
3631 case band_5:
3632 if (pureMode == WIFI_MODE_N)
3633 wireless_mode = PHY_11N_5G;
3634 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3635 wireless_mode = PHY_11VHT_N_MIXED;
3636 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3637 wireless_mode = PHY_11VHT_N_A_MIXED;
3638 if (pureMode & WIFI_MODE_AX)
3639 wireless_mode = PHY_11AX_5G;
3640 if (pureMode & WIFI_MODE_BE)
3641 wireless_mode = PHY_11BE_5G;
3642 break;
3643 case band_6:
3644 if (pureMode & WIFI_MODE_AX)
3645 wireless_mode = PHY_11AX_6G;
3646 if (pureMode & WIFI_MODE_BE)
3647 wireless_mode = PHY_11BE_6G;
3648 break;
3649 default:
developer37646972023-06-29 10:58:43 +08003650 if (fprintf(stderr, "%s band_idx invalid\n", __func__) < 0)
3651 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developer0f10c772023-05-16 21:43:39 +08003652 break;
3653 }
3654
3655 return wireless_mode;
3656}
3657
developer72fb0bb2023-01-11 09:46:29 +08003658// Set the radio operating mode, and pure mode flag.
3659INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3660{
developerfead3972023-05-25 20:15:02 +08003661 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003662
developer0f10c772023-05-16 21:43:39 +08003663 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003664 int ret = -1;
3665 unsigned int if_idx = 0;
3666 struct unl unl_ins;
3667 struct nl_msg *msg = NULL;
3668 struct nlattr * msg_data = NULL;
3669 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003670
developer0f10c772023-05-16 21:43:39 +08003671 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003672
developer0f10c772023-05-16 21:43:39 +08003673 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003674
developera3511852023-06-14 14:12:59 +08003675 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08003676 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08003677 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003678 }
developer72fb0bb2023-01-11 09:46:29 +08003679
developer0f10c772023-05-16 21:43:39 +08003680 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08003681 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003682
3683 if_idx = if_nametoindex(interface_name);
3684 if (!if_idx) {
3685 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3686 return RETURN_ERR;
3687 }
3688 /*init mtk nl80211 vendor cmd*/
3689 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3690 param.if_type = NL80211_ATTR_IFINDEX;
3691 param.if_idx = if_idx;
3692
3693 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3694 if (ret) {
3695 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3696 return RETURN_ERR;
3697 }
3698
3699 /*add mtk vendor cmd data*/
3700 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3701 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3702 nlmsg_free(msg);
3703 goto err;
3704 }
3705 /*send mtk nl80211 vendor msg*/
3706 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3707 if (ret) {
3708 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3709 goto err;
3710 }
3711 /*deinit mtk nl80211 vendor msg*/
3712 mtk_nl80211_deint(&unl_ins);
3713 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003714
developera3511852023-06-14 14:12:59 +08003715 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer0f10c772023-05-16 21:43:39 +08003716
developera3511852023-06-14 14:12:59 +08003717 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003718err:
3719 mtk_nl80211_deint(&unl_ins);
3720 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3721 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003722}
3723
3724INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3725{
developerfead3972023-05-25 20:15:02 +08003726 unsigned char wireless_mode = PHY_MODE_MAX;
developera3511852023-06-14 14:12:59 +08003727 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003728 char dat_file[MAX_BUF_SIZE] = {0};
3729 struct params params={0};
developere40952c2023-06-15 18:46:43 +08003730 int res;
developer0f10c772023-05-16 21:43:39 +08003731
3732 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3733
3734 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3735
developera3511852023-06-14 14:12:59 +08003736 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08003737 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08003738 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003739 }
developer0f10c772023-05-16 21:43:39 +08003740
3741 params.name = "WirelessMode";
developere40952c2023-06-15 18:46:43 +08003742 res = snprintf(buf, sizeof(buf), "%d", wireless_mode);
3743 if (os_snprintf_error(sizeof(buf), res)) {
3744 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3745 return RETURN_ERR;
3746 }
3747
developera3511852023-06-14 14:12:59 +08003748 params.value = buf;
developer0f10c772023-05-16 21:43:39 +08003749
developere40952c2023-06-15 18:46:43 +08003750 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3751 if (os_snprintf_error(sizeof(dat_file), res)) {
3752 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3753 return RETURN_ERR;
3754 }
developera3511852023-06-14 14:12:59 +08003755 wifi_datfileWrite(dat_file, &params, 1);
developer0f10c772023-05-16 21:43:39 +08003756
developera3511852023-06-14 14:12:59 +08003757 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003758
developera3511852023-06-14 14:12:59 +08003759 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003760}
3761
3762INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3763
developera3511852023-06-14 14:12:59 +08003764 char config_file[64] = {0};
3765 char buf[64] = {0};
3766 struct params params = {0};
3767 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003768 int res;
developer72fb0bb2023-01-11 09:46:29 +08003769
developera3511852023-06-14 14:12:59 +08003770 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003771
developera3511852023-06-14 14:12:59 +08003772 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003773
developera3511852023-06-14 14:12:59 +08003774 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3775 return RETURN_ERR;
3776 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3777 return RETURN_ERR;
3778 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3779 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003780
developer75bd10c2023-06-27 11:34:08 +08003781 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3782 if (os_snprintf_error(sizeof(config_file), res)) {
3783 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3784 return RETURN_ERR;
3785 }
developera3511852023-06-14 14:12:59 +08003786 params.name = "hw_mode";
3787 params.value = hw_mode;
3788 wifi_hostapdWrite(config_file, &params, 1);
3789 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003790
developera3511852023-06-14 14:12:59 +08003791 if (band == band_2_4) {
3792 if (strncmp(hw_mode, "b", 1) == 0) {
3793 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
developere40952c2023-06-15 18:46:43 +08003794 res = snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3795 if (os_snprintf_error(sizeof(buf), res)) {
3796 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3797 return RETURN_ERR;
3798 }
developera3511852023-06-14 14:12:59 +08003799 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003800 res = snprintf(buf, sizeof(buf), "%s", "1,2");
3801 if (os_snprintf_error(sizeof(buf), res)) {
3802 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3803 return RETURN_ERR;
3804 }
developera3511852023-06-14 14:12:59 +08003805 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3806 } else {
3807 // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
developer72fb0bb2023-01-11 09:46:29 +08003808
developere40952c2023-06-15 18:46:43 +08003809 res = snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3810 if (os_snprintf_error(sizeof(buf), res)) {
3811 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3812 return RETURN_ERR;
3813 }
developera3511852023-06-14 14:12:59 +08003814 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003815 res = snprintf(buf, sizeof(buf), "%s", "6,12,24");
3816 if (os_snprintf_error(sizeof(buf), res)) {
3817 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3818 return RETURN_ERR;
3819 }
developera3511852023-06-14 14:12:59 +08003820 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3821 }
3822 }
developer72fb0bb2023-01-11 09:46:29 +08003823
developera3511852023-06-14 14:12:59 +08003824 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3825 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003826}
3827
3828INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3829{
developera3511852023-06-14 14:12:59 +08003830 char config_file[64] = {0};
3831 struct params params = {0};
3832 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08003833 int res;
developer72fb0bb2023-01-11 09:46:29 +08003834
developera3511852023-06-14 14:12:59 +08003835 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003836
developera3511852023-06-14 14:12:59 +08003837 band = wifi_index_to_band(radioIndex);
3838 if (band != band_2_4)
3839 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003840
developer75bd10c2023-06-27 11:34:08 +08003841 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3842 if (os_snprintf_error(sizeof(config_file), res)) {
3843 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3844 return RETURN_ERR;
3845 }
developera3511852023-06-14 14:12:59 +08003846 params.name = "noscan";
3847 params.value = noscan;
3848 wifi_hostapdWrite(config_file, &params, 1);
3849 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003850
developera3511852023-06-14 14:12:59 +08003851 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3852 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003853}
3854
3855//Get the list of supported channel. eg: "1-11"
3856//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.
3857INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3858{
developera3511852023-06-14 14:12:59 +08003859 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3860 if (NULL == output_string)
3861 return RETURN_ERR;
3862 char cmd[256] = {0};
3863 char buf[128] = {0};
3864 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +08003865 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08003866
developera3511852023-06-14 14:12:59 +08003867 // Parse possible channel number and separate them with commas.
3868 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3869 phyId = radio_index_to_phy(radioIndex);
3870 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3871 if (dfs_enable)
developere40952c2023-06-15 18:46:43 +08003872 res = 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);
developera3511852023-06-14 14:12:59 +08003873 else
developere40952c2023-06-15 18:46:43 +08003874 res = 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);
developer72fb0bb2023-01-11 09:46:29 +08003875
developere40952c2023-06-15 18:46:43 +08003876 if (os_snprintf_error(sizeof(cmd), res)) {
3877 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3878 return RETURN_ERR;
3879 }
developera3511852023-06-14 14:12:59 +08003880 _syscmd(cmd,buf,sizeof(buf));
3881 strncpy(output_string, buf, strlen(buf) < sizeof(buf) ? strlen(buf) : sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003882
developera3511852023-06-14 14:12:59 +08003883 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3884 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003885}
developerd1824452023-05-18 12:30:04 +08003886//Getting current radio extension channel
3887INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3888{
developera3511852023-06-14 14:12:59 +08003889 CHAR buf[150] = {0};
developer32f2a182023-06-27 19:50:41 +08003890 int len;
developerd1824452023-05-18 12:30:04 +08003891
developera3511852023-06-14 14:12:59 +08003892 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08003893 if (strncmp(buf, "Below", 5) == 0) {
3894 len = strlen("BelowControlChannel");
3895 memcpy(Value, "BelowControlChannel", len);
developerc14d83a2023-06-29 20:09:42 +08003896 Value[len] = '\0';
developer32f2a182023-06-27 19:50:41 +08003897 }
3898 else if(strncmp(buf, "Above", 5) == 0) {
3899 len = strlen("AboveControlChannel");
3900 memcpy(Value, "AboveControlChannel", len);
developerc14d83a2023-06-29 20:09:42 +08003901 Value[len] = '\0';
developer32f2a182023-06-27 19:50:41 +08003902 }
developerc14d83a2023-06-29 20:09:42 +08003903
developera3511852023-06-14 14:12:59 +08003904 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08003905}
developerf6a87542023-05-16 15:47:28 +08003906
developer72fb0bb2023-01-11 09:46:29 +08003907//Get the list for used channel. eg: "1,6,9,11"
3908//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.
3909INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3910{
developera3511852023-06-14 14:12:59 +08003911 char interface_name[16] = {0};
3912 char cmd[128] = {0};
3913 char buf[128] = {0};
3914 char config_file[64] = {0};
3915 int channel = 0;
3916 int freq = 0;
3917 int bandwidth = 0;
3918 int center_freq = 0;
3919 int center_channel = 0;
3920 int channel_delta = 0;
3921 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003922 int res;
developer72fb0bb2023-01-11 09:46:29 +08003923
developera3511852023-06-14 14:12:59 +08003924 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003925
developera3511852023-06-14 14:12:59 +08003926 if (NULL == output_string)
3927 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003928
developera3511852023-06-14 14:12:59 +08003929 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3930 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08003931
3932 res = snprintf(cmd, sizeof(cmd), "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3933 if (os_snprintf_error(sizeof(cmd), res)) {
3934 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3935 return RETURN_ERR;
3936 }
developera3511852023-06-14 14:12:59 +08003937 _syscmd(cmd, buf, sizeof(buf));
3938 if (strlen(buf) == 0) {
developer75bd10c2023-06-27 11:34:08 +08003939 wifi_debug(DEBUG_ERROR, "failed to get channel information from iw.\n");
developera3511852023-06-14 14:12:59 +08003940 return RETURN_ERR;
3941 }
developerd14dff12023-06-28 22:47:44 +08003942 if (sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq) != 4) {
3943 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
3944 return RETURN_ERR;
3945 }
developer72fb0bb2023-01-11 09:46:29 +08003946
developera3511852023-06-14 14:12:59 +08003947 if (bandwidth == 20) {
developere40952c2023-06-15 18:46:43 +08003948 res = snprintf(output_string, 256, "%d", channel);
3949 if (os_snprintf_error(256, res)) {
3950 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3951 return RETURN_ERR;
3952 }
developera3511852023-06-14 14:12:59 +08003953 return RETURN_OK;
3954 }
developer72fb0bb2023-01-11 09:46:29 +08003955
developera3511852023-06-14 14:12:59 +08003956 center_channel = ieee80211_frequency_to_channel(center_freq);
developer72fb0bb2023-01-11 09:46:29 +08003957
developera3511852023-06-14 14:12:59 +08003958 band = wifi_index_to_band(radioIndex);
3959 if (band == band_2_4 && bandwidth == 40) {
developer32f2a182023-06-27 19:50:41 +08003960 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3961 if (os_snprintf_error(sizeof(config_file), res)) {
3962 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3963 return RETURN_ERR;
3964 }
developera3511852023-06-14 14:12:59 +08003965 memset(buf, 0, sizeof(buf));
3966 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
developer72fb0bb2023-01-11 09:46:29 +08003967
developera3511852023-06-14 14:12:59 +08003968 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
developere40952c2023-06-15 18:46:43 +08003969 res = snprintf(output_string, 256, "%d,%d", channel, channel+4);
developera3511852023-06-14 14:12:59 +08003970 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
developere40952c2023-06-15 18:46:43 +08003971 res = snprintf(output_string, 256, "%d,%d", channel-4, channel);
developera3511852023-06-14 14:12:59 +08003972 } else {
developer37646972023-06-29 10:58:43 +08003973 if (fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf) < 0)
3974 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08003975 return RETURN_ERR;
3976 }
developerb758dfd2023-06-21 17:32:07 +08003977
developere40952c2023-06-15 18:46:43 +08003978 if (os_snprintf_error(256, res)) {
3979 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3980 return RETURN_ERR;
3981 }
developera3511852023-06-14 14:12:59 +08003982 } else if (band == band_5 || band == band_6){
3983 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
3984 // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6.
3985 channel_delta = (bandwidth-20)/10;
3986 memset(output_string, 0, 256);
3987 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3988 // If i is not the last channel, we add a comma.
developere40952c2023-06-15 18:46:43 +08003989 res = snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
developer32f2a182023-06-27 19:50:41 +08003990
developere40952c2023-06-15 18:46:43 +08003991 if (os_snprintf_error(sizeof(buf), res)) {
3992 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3993 return RETURN_ERR;
3994 }
developer32f2a182023-06-27 19:50:41 +08003995 strncat(output_string, buf, sizeof(output_string) - strlen(output_string) - 1);
developera3511852023-06-14 14:12:59 +08003996 }
3997 } else
3998 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003999
developera3511852023-06-14 14:12:59 +08004000 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4001 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004002}
4003
developer69b61b02023-03-07 17:17:44 +08004004//Get the running channel number
developerd1824452023-05-18 12:30:04 +08004005INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08004006{
developera3511852023-06-14 14:12:59 +08004007 char channel_str[16] = {0};
4008 char config_file[128] = {0};
4009 char buf[MAX_BUF_SIZE] = {0};
4010 char cmd[MAX_CMD_SIZE] = {0};
4011 char interface_name[IF_NAME_SIZE] = {0};
4012 wifi_band band = band_invalid;
4013 ULONG iwChannel = 0;
developere40952c2023-06-15 18:46:43 +08004014 int res;
developer47a56bf2023-05-30 13:38:57 +08004015
developera3511852023-06-14 14:12:59 +08004016 if (output_ulong == NULL)
4017 return RETURN_ERR;
4018 band = wifi_index_to_band(radioIndex);
developerb758dfd2023-06-21 17:32:07 +08004019 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08004020 if (os_snprintf_error(sizeof(config_file), res)) {
4021 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4022 return RETURN_ERR;
4023 }
4024
developera3511852023-06-14 14:12:59 +08004025 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
developerc14d83a2023-06-29 20:09:42 +08004026 if (hal_strtoul(buf, 10, output_ulong) < 0) {
4027 wifi_debug(DEBUG_ERROR, "strtol fail\n");
4028 }
developera3511852023-06-14 14:12:59 +08004029 if (*output_ulong == 0) {
4030 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4031 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004032 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
4033 if (os_snprintf_error(sizeof(cmd), res)) {
4034 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4035 return RETURN_ERR;
4036 }
4037
developera3511852023-06-14 14:12:59 +08004038 _syscmd(cmd,buf,sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08004039 if (sscanf(buf, "%lu", &iwChannel) != 1) {
4040 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
4041 return RETURN_ERR;
4042 }
developera3511852023-06-14 14:12:59 +08004043 *output_ulong = iwChannel;
4044 }
developer72fb0bb2023-01-11 09:46:29 +08004045
developera3511852023-06-14 14:12:59 +08004046 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004047}
4048
developer72fb0bb2023-01-11 09:46:29 +08004049INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
4050{
developera3511852023-06-14 14:12:59 +08004051 char cmd[1024] = {0}, buf[5] = {0};
4052 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08004053 int res;
developer72fb0bb2023-01-11 09:46:29 +08004054
developera3511852023-06-14 14:12:59 +08004055 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4056 if (NULL == output_ulong)
4057 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004058
developera3511852023-06-14 14:12:59 +08004059 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
4060 return RETURN_ERR;
developer47a56bf2023-05-30 13:38:57 +08004061
developere40952c2023-06-15 18:46:43 +08004062 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
4063 if (os_snprintf_error(sizeof(cmd), res)) {
4064 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4065 return RETURN_ERR;
4066 }
developera3511852023-06-14 14:12:59 +08004067 _syscmd(cmd,buf,sizeof(buf));
4068 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
4069 if (*output_ulong == 0) {
4070 return RETURN_ERR;
4071 }
developer72fb0bb2023-01-11 09:46:29 +08004072
developera3511852023-06-14 14:12:59 +08004073 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004075}
developer72fb0bb2023-01-11 09:46:29 +08004076//Storing the previous channel value
4077INT wifi_storeprevchanval(INT radioIndex)
4078{
developera3511852023-06-14 14:12:59 +08004079 char buf[256] = {0};
4080 char output[4]={'\0'};
4081 char config_file[MAX_BUF_SIZE] = {0};
4082 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004083 int res;
developerd1824452023-05-18 12:30:04 +08004084
developera3511852023-06-14 14:12:59 +08004085 band = wifi_index_to_band(radioIndex);
4086 if (band == band_invalid) {
4087 return RETURN_ERR;
4088 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
4089 }
developere40952c2023-06-15 18:46:43 +08004090 res = snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
4091 if (os_snprintf_error(sizeof(config_file), res)) {
4092 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4093 return RETURN_ERR;
4094 }
4095
developera3511852023-06-14 14:12:59 +08004096 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
developerd1824452023-05-18 12:30:04 +08004097
developera3511852023-06-14 14:12:59 +08004098 if(band == band_2_4)
developer75bd10c2023-06-27 11:34:08 +08004099 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developera3511852023-06-14 14:12:59 +08004100 else if(band == band_5)
developer75bd10c2023-06-27 11:34:08 +08004101 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developera3511852023-06-14 14:12:59 +08004102 else
developer75bd10c2023-06-27 11:34:08 +08004103 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
4104
4105 if (os_snprintf_error(sizeof(buf), res)) {
4106 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4107 return RETURN_ERR;
4108 }
developera3511852023-06-14 14:12:59 +08004109 system(buf);
4110 Radio_flag = FALSE;
4111 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004112}
4113
4114//Set the running channel number
4115INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
4116{
developera3511852023-06-14 14:12:59 +08004117 // We only write hostapd config here
4118 char str_channel[8]={0};
4119 char *list_channel;
4120 char possible_channels[256] = {0};
4121 char config_file_dat[128] = {0};
4122 struct params dat = {0};
4123 struct params acs = {0};
4124 wifi_band band = band_invalid;
4125 bool acs_channel = false;
developere40952c2023-06-15 18:46:43 +08004126 int res;
developer72fb0bb2023-01-11 09:46:29 +08004127
developera3511852023-06-14 14:12:59 +08004128 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004129
developera3511852023-06-14 14:12:59 +08004130 if (channel == 0)
4131 acs_channel = true;
4132 // Check valid
developer75bd10c2023-06-27 11:34:08 +08004133 res = snprintf(str_channel, sizeof(str_channel), "%lu", channel);
4134 if (os_snprintf_error(sizeof(str_channel), res)) {
4135 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4136 return RETURN_ERR;
4137 }
developer47a56bf2023-05-30 13:38:57 +08004138
developera3511852023-06-14 14:12:59 +08004139 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
4140 list_channel = strtok(possible_channels, ",");
4141 while(true)
4142 {
4143 if(list_channel == NULL) { // input not in the list
developer75bd10c2023-06-27 11:34:08 +08004144 wifi_debug(DEBUG_ERROR, "Channel %s is not in possible list\n", str_channel);
developera3511852023-06-14 14:12:59 +08004145 return RETURN_ERR;
4146 }
4147 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
4148 break;
4149 list_channel = strtok(NULL, ",");
4150 }
4151 /*
4152 list.name = "channel";
4153 list.value = str_channel;
4154 wifi_getMaxRadioNumber(&max_radio_num);
4155 for(int i=0; i<=MAX_APS/max_radio_num;i++)
4156 {
4157 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
4158 wifi_hostapdWrite(config_file, &list, 1);
4159 }
4160 */
4161 dat.name = "Channel";
4162 dat.value = str_channel;
4163 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004164 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4165 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4166 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4167 return RETURN_ERR;
4168 }
4169
developera3511852023-06-14 14:12:59 +08004170 wifi_datfileWrite(config_file_dat, &dat, 1);
4171 if (acs_channel == true) {
4172 acs.name = "AutoChannelSelect";
4173 acs.value = "3";
4174 } else {
4175 acs.name = "AutoChannelSelect";
4176 acs.value = "0";
4177 }
4178 wifi_datfileWrite(config_file_dat, &acs, 1);
4179 wifi_reloadAp(radioIndex);
4180 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4181 return RETURN_OK;
4182}
4183
4184INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
4185{
4186 struct params list[2];
4187 char str_idx[16];
4188 char config_file[64];
developere40952c2023-06-15 18:46:43 +08004189 int max_num_radios = 0, res;
developera3511852023-06-14 14:12:59 +08004190 wifi_band band = band_invalid;
4191
4192 band = wifi_index_to_band(radioIndex);
4193 if (band == band_2_4)
4194 return RETURN_OK;
4195
developere40952c2023-06-15 18:46:43 +08004196 res = snprintf(str_idx, sizeof(str_idx), "%lu", channel);
4197 if (os_snprintf_error(sizeof(str_idx), res)) {
4198 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4199 return RETURN_ERR;
4200 }
4201
developera3511852023-06-14 14:12:59 +08004202 list[0].name = "vht_oper_centr_freq_seg0_idx";
4203 list[0].value = str_idx;
4204 list[1].name = "he_oper_centr_freq_seg0_idx";
4205 list[1].value = str_idx;
4206
4207 wifi_getMaxRadioNumber(&max_num_radios);
developer9ce44382023-06-28 11:09:37 +08004208 if(max_num_radios== 0){
4209 return RETURN_ERR;
4210 }
developera3511852023-06-14 14:12:59 +08004211 for(int i=0; i<=MAX_APS/max_num_radios; i++)
4212 {
developere40952c2023-06-15 18:46:43 +08004213 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
4214 if (os_snprintf_error(sizeof(config_file), res)) {
4215 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4216 return RETURN_ERR;
4217 }
developera3511852023-06-14 14:12:59 +08004218 if (band == band_6)
4219 wifi_hostapdWrite(config_file, &list[1], 1);
4220 else
4221 wifi_hostapdWrite(config_file, list, 2);
4222 }
4223
4224 return RETURN_OK;
4225}
4226
4227//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
4228//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
4229INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
4230{
4231 //Set to wifi config only. Wait for wifi reset to apply.
4232 ULONG Value = 0;
4233 char config_file_dat[128] = {0};
4234 struct params acs = {0};
4235 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004236 int res;
developera3511852023-06-14 14:12:59 +08004237
4238 if(enable == TRUE) {
4239 wifi_setRadioChannel(radioIndex,Value);
4240 } else {
4241 acs.name = "AutoChannelSelect";
4242 acs.value = "0";
4243 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004244 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4245 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4246 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4247 return RETURN_ERR;
4248 }
developera3511852023-06-14 14:12:59 +08004249 wifi_datfileWrite(config_file_dat, &acs, 1);
4250 }
4251 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004252}
4253
4254INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
4255{
developera3511852023-06-14 14:12:59 +08004256 if (output_bool == NULL)
4257 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004258
developera3511852023-06-14 14:12:59 +08004259 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004260
developera3511852023-06-14 14:12:59 +08004261 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004262}
4263
4264INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
4265{
developera3511852023-06-14 14:12:59 +08004266 if (NULL == output_bool)
4267 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004268 *output_bool=TRUE;
developera3511852023-06-14 14:12:59 +08004269 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004270}
4271
4272INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
4273{
developer326d4232023-06-15 16:45:30 +08004274 unsigned long period = 0;
4275
developera3511852023-06-14 14:12:59 +08004276 if (NULL == output_bool)
4277 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004278
4279 if (wifi_getRadioAutoChannelRefreshPeriod(radioIndex, &period) != RETURN_OK)
developerb758dfd2023-06-21 17:32:07 +08004280 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08004281
4282 *output_bool = (period > 0) ? TRUE : FALSE;
4283
developera3511852023-06-14 14:12:59 +08004284 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004285}
4286
developer326d4232023-06-15 16:45:30 +08004287INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08004288{
developer326d4232023-06-15 16:45:30 +08004289 ULONG period = 1800;
4290
4291 if (enable == TRUE) {
4292 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, period) != RETURN_OK)
4293 return RETURN_ERR;
4294 }
4295 else {
4296 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, 0) != RETURN_OK)
4297 return RETURN_ERR;
4298 }
developera3511852023-06-14 14:12:59 +08004299 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004300}
4301
4302INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
4303{
developera3511852023-06-14 14:12:59 +08004304 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004305}
4306
4307INT wifi_factoryResetAP(int apIndex)
4308{
developerb149d9d2023-06-06 16:14:22 +08004309 char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08004310 char cmd[MAX_CMD_SIZE] = {0};
4311 char ret_buf[MAX_BUF_SIZE] = {0};
4312 int radio_idx = 0;
4313 int bss_idx = 0;
4314 char ssid[32] = {0};
4315 char interface[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08004316 char psk_file[MAX_SUB_CMD_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08004317 struct params params[3] = {0};
developere40952c2023-06-15 18:46:43 +08004318 int res;
developer72fb0bb2023-01-11 09:46:29 +08004319
developera3511852023-06-14 14:12:59 +08004320 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004321
developer47cc27a2023-05-17 23:09:58 +08004322 /*del old config file*/
developer9ce44382023-06-28 11:09:37 +08004323 res = snprintf(ap_config_file, sizeof(ap_config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd14dff12023-06-28 22:47:44 +08004324 if (os_snprintf_error(sizeof(ap_config_file), res)) {
developere40952c2023-06-15 18:46:43 +08004325 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4326 return RETURN_ERR;
4327 }
4328
4329 res = snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
4330 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4331 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4332 return RETURN_ERR;
4333 }
4334
developer47cc27a2023-05-17 23:09:58 +08004335 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08004336
developer47cc27a2023-05-17 23:09:58 +08004337 memset(cmd, 0, sizeof(cmd));
4338 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08004339
developer47cc27a2023-05-17 23:09:58 +08004340 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
4341
4342 /*prepare new config file*/
developere40952c2023-06-15 18:46:43 +08004343 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
4344 if (os_snprintf_error(sizeof(cmd), res)) {
4345 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4346 return RETURN_ERR;
4347 }
4348
developer47cc27a2023-05-17 23:09:58 +08004349 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4350
4351 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08004352 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
4353 if (os_snprintf_error(sizeof(ssid), res)) {
4354 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4355 return RETURN_ERR;
4356 }
4357
4358 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
4359 if (os_snprintf_error(sizeof(interface), res)) {
4360 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4361 return RETURN_ERR;
4362 }
developer47cc27a2023-05-17 23:09:58 +08004363 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08004364 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
4365 if (os_snprintf_error(sizeof(ssid), res)) {
4366 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4367 return RETURN_ERR;
4368 }
4369
4370 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
4371 if (os_snprintf_error(sizeof(interface), res)) {
4372 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4373 return RETURN_ERR;
4374 }
developer47cc27a2023-05-17 23:09:58 +08004375 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08004376 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
4377 if (os_snprintf_error(sizeof(ssid), res)) {
4378 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4379 return RETURN_ERR;
4380 }
4381
4382 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
4383 if (os_snprintf_error(sizeof(interface), res)) {
4384 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4385 return RETURN_ERR;
4386 }
developer47cc27a2023-05-17 23:09:58 +08004387 }
4388
4389 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08004390 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
4391 if (os_snprintf_error(sizeof(psk_file), res)) {
4392 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4393 return RETURN_ERR;
4394 }
developer47cc27a2023-05-17 23:09:58 +08004395
4396 params[0].name = "ssid";
4397 params[0].value = ssid;
4398 params[1].name = "interface";
4399 params[1].value = interface;
4400 params[2].name = "wpa_psk_file";
4401 params[2].value = psk_file;
4402
4403 wifi_hostapdWrite(ap_config_file, params, 3);
4404
4405 /*clear psk file*/
4406 memset(cmd, 0, sizeof(cmd));
4407 memset(ret_buf, 0, sizeof(ret_buf));
4408
developere40952c2023-06-15 18:46:43 +08004409 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
4410 if (os_snprintf_error(sizeof(psk_file), res)) {
4411 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4412 return RETURN_ERR;
4413 }
developer47cc27a2023-05-17 23:09:58 +08004414
4415 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08004416 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
4417 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4418 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4419 return RETURN_ERR;
4420 }
4421
developer47cc27a2023-05-17 23:09:58 +08004422 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4423 } else {
developere40952c2023-06-15 18:46:43 +08004424 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
4425 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4426 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4427 return RETURN_ERR;
4428 }
4429
developer47cc27a2023-05-17 23:09:58 +08004430 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4431 }
4432
developer429ba832023-05-31 11:03:35 +08004433 wifi_setApEnable(apIndex, FALSE);
4434 wifi_setApEnable(apIndex, TRUE);
developer47cc27a2023-05-17 23:09:58 +08004435 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4436
4437 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004438}
4439
developer72fb0bb2023-01-11 09:46:29 +08004440INT wifi_setBandSteeringApGroup(char *ApGroup)
4441{
developera3511852023-06-14 14:12:59 +08004442 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004443}
4444
4445INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
4446{
developera3511852023-06-14 14:12:59 +08004447 char config_file[128] = {'\0'};
4448 char buf[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004449 int res;
developerc14d83a2023-06-29 20:09:42 +08004450 long int tmp;
4451
developera3511852023-06-14 14:12:59 +08004452 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4453 if (dtimInterval == NULL)
4454 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004455
4456 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
4457 if (os_snprintf_error(sizeof(config_file), res)) {
4458 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4459 return RETURN_ERR;
4460 }
developer72fb0bb2023-01-11 09:46:29 +08004461
developera3511852023-06-14 14:12:59 +08004462 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004463
developera3511852023-06-14 14:12:59 +08004464 if (strlen(buf) == 0) {
4465 *dtimInterval = 2;
4466 } else {
developerc14d83a2023-06-29 20:09:42 +08004467 if (hal_strtol(buf, 10, &tmp) < 0) {
4468 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08004469 }
developerc14d83a2023-06-29 20:09:42 +08004470 *dtimInterval = tmp;
developera3511852023-06-14 14:12:59 +08004471 }
developer72fb0bb2023-01-11 09:46:29 +08004472
developera3511852023-06-14 14:12:59 +08004473 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4474 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004475}
4476
4477INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
4478{
developera3511852023-06-14 14:12:59 +08004479 struct params params={0};
4480 char config_file[MAX_BUF_SIZE] = {'\0'};
4481 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004482 int res;
developer72fb0bb2023-01-11 09:46:29 +08004483
developera3511852023-06-14 14:12:59 +08004484 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4485 if (dtimInterval < 1 || dtimInterval > 255) {
4486 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
4487 return RETURN_ERR;
4488 }
developer69b61b02023-03-07 17:17:44 +08004489
developera3511852023-06-14 14:12:59 +08004490 params.name = "dtim_period";
developere40952c2023-06-15 18:46:43 +08004491 res = snprintf(buf, sizeof(buf), "%d", dtimInterval);
4492 if (os_snprintf_error(sizeof(buf), res)) {
4493 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4494 return RETURN_ERR;
4495 }
developera3511852023-06-14 14:12:59 +08004496 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08004497
developer75bd10c2023-06-27 11:34:08 +08004498 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
4499 if (os_snprintf_error(sizeof(config_file), res)) {
4500 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4501 return RETURN_ERR;
4502 }
developera3511852023-06-14 14:12:59 +08004503 wifi_hostapdWrite(config_file, &params, 1);
4504 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08004505
developera3511852023-06-14 14:12:59 +08004506 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4507 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004508}
4509
4510//Check if the driver support the Dfs
4511INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
4512{
developera3511852023-06-14 14:12:59 +08004513 wifi_band band = band_invalid;
4514 if (NULL == output_bool)
4515 return RETURN_ERR;
4516 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +08004517
developera3511852023-06-14 14:12:59 +08004518 band = wifi_index_to_band(radioIndex);
4519 if (band == band_5)
4520 *output_bool = TRUE;
4521 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004522}
4523
4524//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.
4525//The value of this parameter is a comma seperated list of channel number
4526INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
4527{
developer326d4232023-06-15 16:45:30 +08004528
4529 #define CHANNEL_AVAILABLE 0
4530 #define CHANNEL_INVALID 1
4531 #define CHANNEL_LIST_MAX_LENGTH 256
4532 #define MAX_CHANNEL_NUMBER 255
4533
4534 char config_file[MAX_BUF_SIZE] = {0};
4535 char possible_channels[CHANNEL_LIST_MAX_LENGTH] = {0};
4536 char skip_list[CHANNEL_LIST_MAX_LENGTH] = {0};
4537 int skip_table[MAX_CHANNEL_NUMBER +1] = {0};
4538 wifi_band band = band_invalid;
4539 char *token_channel = NULL, *token_skip = NULL;
developer75bd10c2023-06-27 11:34:08 +08004540 int res;
developere40952c2023-06-15 18:46:43 +08004541
developera3511852023-06-14 14:12:59 +08004542 if (NULL == output_pool)
4543 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004544 // get skiplist, possible_channels list
4545 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
4546 band = wifi_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08004547 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4548 if (os_snprintf_error(sizeof(config_file), res)) {
4549 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4550 return RETURN_ERR;
4551 }
developer326d4232023-06-15 16:45:30 +08004552 wifi_datfileRead(config_file, "AutoChannelSkipList", skip_list, sizeof(skip_list));
4553
4554 if (skip_list[0] != '\0') {
4555 int len = strlen(skip_list);
4556 for (int i = 0; i < len; i++) {
4557 if (skip_list[i] == ';') {
4558 skip_list[i] = ',';
4559 }
4560 }
4561 // skip list
4562 token_skip = strtok(skip_list, ",");
4563 while (token_skip != NULL) {
4564 int channel = atoi(token_skip);
4565 if (channel <= MAX_CHANNEL_NUMBER && strstr(possible_channels, token_skip) != NULL)
4566 skip_table[atoi(token_skip)] = CHANNEL_INVALID;
4567 token_skip = strtok(NULL, ",");
4568 }
developere40952c2023-06-15 18:46:43 +08004569 }
developer72fb0bb2023-01-11 09:46:29 +08004570
developer326d4232023-06-15 16:45:30 +08004571 int count = 0;
4572 token_channel = strtok(possible_channels, ",");
4573 while (token_channel != NULL) {
4574 int channel = atoi(token_channel);
4575 if (channel <= MAX_CHANNEL_NUMBER && skip_table[channel] == CHANNEL_AVAILABLE) {
4576 count += snprintf(&output_pool[count], CHANNEL_LIST_MAX_LENGTH-count, "%d,", channel);
4577 if (count >= CHANNEL_LIST_MAX_LENGTH-1)
4578 break;
4579 }
4580 token_channel = strtok(NULL, ",");
4581 }
4582 //delete the last one ','
4583 if (count >0 && output_pool[count-1] == ',')
4584 output_pool[count-1] = '\0';
developera3511852023-06-14 14:12:59 +08004585 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004586}
4587
4588INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
4589{
developer326d4232023-06-15 16:45:30 +08004590 char config_file_dat[128] = {0};
4591 struct params dat = {0};
4592 wifi_band band = band_invalid;
4593 char new_pool[128] = {0};
developer75bd10c2023-06-27 11:34:08 +08004594 int res;
developer326d4232023-06-15 16:45:30 +08004595
4596 if (NULL == pool)
4597 return RETURN_ERR;
4598
developer9ce44382023-06-28 11:09:37 +08004599 strncpy(new_pool, pool, sizeof(new_pool) - 1);
4600 new_pool[sizeof(new_pool) - 1] = '\0';
developer326d4232023-06-15 16:45:30 +08004601 for (int i = 0; new_pool[i] != '\0'; i++) {
4602 if (new_pool[i] == ',')
4603 new_pool[i] = ';';
4604 }
4605
4606 dat.name = "AutoChannelSkipList";
4607 dat.value = new_pool;
4608 band = wifi_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08004609 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4610 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4612 return RETURN_ERR;
4613 }
developer326d4232023-06-15 16:45:30 +08004614 if (wifi_datfileWrite(config_file_dat, &dat, 1) != 0)
4615 return RETURN_ERR;
4616 wifi_reloadAp(radioIndex);
4617
developera3511852023-06-14 14:12:59 +08004618 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004619}
4620
4621INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
4622{
developera3511852023-06-14 14:12:59 +08004623 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
4624 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004625 //Should refresh period time be filled in here? output_interval_seconds is INT type
4626 //wifi_getRadioAutoChannelRefreshPeriod is Ulong type
4627 *output_interval_seconds = 1800;
4628 *output_dwell_milliseconds = 200;
developer72fb0bb2023-01-11 09:46:29 +08004629
developera3511852023-06-14 14:12:59 +08004630 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004631}
4632
4633INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
4634{
developera3511852023-06-14 14:12:59 +08004635 //Set to wifi config. And apply instantly.
4636 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004637}
4638
4639INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
4640{
developera3511852023-06-14 14:12:59 +08004641 if (output_bool == NULL)
4642 return RETURN_ERR;
4643 *output_bool = true;
4644 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004645}
4646
4647INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
4648{
developera3511852023-06-14 14:12:59 +08004649 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004650}
4651
4652//Get the Dfs enable status
4653INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
4654{
developera3511852023-06-14 14:12:59 +08004655 char buf[16] = {0};
4656 char config_file_dat[128] = {0};
4657 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004658 int res;
developer72fb0bb2023-01-11 09:46:29 +08004659
developera3511852023-06-14 14:12:59 +08004660 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004661
developera3511852023-06-14 14:12:59 +08004662 if (output_bool == NULL)
4663 return RETURN_ERR;
4664 *output_bool = TRUE; // default
4665 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004666 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4667 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4668 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4669 return RETURN_ERR;
4670 }
developerd1824452023-05-18 12:30:04 +08004671
developera3511852023-06-14 14:12:59 +08004672 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08004673
developera3511852023-06-14 14:12:59 +08004674 if (strncmp(buf, "0", 1) == 0)
4675 *output_bool = FALSE;
4676 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4677 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004678}
4679
4680//Set the Dfs enable status
4681INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
4682{
developera3511852023-06-14 14:12:59 +08004683 char config_dat_file[128] = {0};
4684 FILE *f = NULL;
4685 struct params dat = {0};
4686 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08004687 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +08004688
developera3511852023-06-14 14:12:59 +08004689 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004690
developera3511852023-06-14 14:12:59 +08004691 f = fopen(DFS_ENABLE_FILE, "w");
4692 if (f == NULL)
4693 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08004694 ret = fprintf(f, "%d", enable);
4695 if (ret < 0)
4696 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developerd14dff12023-06-28 22:47:44 +08004697 if (fclose(f) != 0) {
4698 wifi_debug(DEBUG_ERROR, "fclose fail\n");
4699 return RETURN_ERR;
4700 }
developer72fb0bb2023-01-11 09:46:29 +08004701
developera3511852023-06-14 14:12:59 +08004702 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08004703
developera3511852023-06-14 14:12:59 +08004704 dat.name = "DfsEnable";
4705 dat.value = enable?"1":"0";
4706 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004707 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4708 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4709 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4710 return RETURN_ERR;
4711 }
4712
developera3511852023-06-14 14:12:59 +08004713 wifi_datfileWrite(config_dat_file, &dat, 1);
4714 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4715 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004716}
4717
4718//Check if the driver support the AutoChannelRefreshPeriod
4719INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
4720{
developera3511852023-06-14 14:12:59 +08004721 if (NULL == output_bool)
4722 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004723 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004724
developera3511852023-06-14 14:12:59 +08004725 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004726}
4727
developer326d4232023-06-15 16:45:30 +08004728
4729int get_ACS_RefreshPeriod_callback(struct nl_msg *msg, void *arg)
4730{
4731 ULONG *data = (ULONG *)arg;
4732 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4733 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
4734 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4735 int err = 0;
4736
4737 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4738 genlmsg_attrlen(gnlh, 0), NULL);
4739 if (err < 0)
4740 return NL_SKIP;
4741
4742 if (tb[NL80211_ATTR_VENDOR_DATA]) {
4743 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
4744 tb[NL80211_ATTR_VENDOR_DATA], NULL);
4745 if (err < 0)
4746 return NL_SKIP;
4747
4748 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]) {
4749 *data = nla_get_u32(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]);
4750 }
4751 }
4752
4753 return NL_OK;
4754}
4755
developer72fb0bb2023-01-11 09:46:29 +08004756//Get the ACS refresh period in seconds
4757INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
4758{
developer326d4232023-06-15 16:45:30 +08004759 char interface_name[IF_NAME_SIZE] = {0};
4760 int ret = -1;
4761 unsigned int if_idx = 0;
4762 struct unl unl_ins;
4763 struct nl_msg *msg = NULL;
4764 struct nlattr * msg_data = NULL;
4765 struct mtk_nl80211_param param;
4766 unsigned long checktime = 0;
4767
4768 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08004769 if (NULL == output_ulong)
4770 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004771
4772 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4773 return RETURN_ERR;
4774
4775 if_idx = if_nametoindex(interface_name);
4776 if (!if_idx) {
4777 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4778 return RETURN_ERR;
4779 }
4780 /*init mtk nl80211 vendor cmd*/
4781 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
4782 param.if_type = NL80211_ATTR_IFINDEX;
4783 param.if_idx = if_idx;
developer72fb0bb2023-01-11 09:46:29 +08004784
developer326d4232023-06-15 16:45:30 +08004785 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4786 if (ret) {
4787 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4788 return RETURN_ERR;
4789 }
4790
4791 /*add mtk vendor cmd data*/
4792 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD, 0)) {
4793 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD attribute error\n");
4794 nlmsg_free(msg);
4795 goto err;
4796 }
4797
4798 /*send mtk nl80211 vendor msg*/
4799 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ACS_RefreshPeriod_callback, &checktime);
4800
4801 if (ret) {
4802 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4803 goto err;
4804 }
4805 /*deinit mtk nl80211 vendor msg*/
4806 mtk_nl80211_deint(&unl_ins);
4807 *output_ulong = checktime;
4808 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
4809
4810 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08004811 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08004812err:
4813 mtk_nl80211_deint(&unl_ins);
4814 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
4815 return RETURN_ERR;
4816
developer72fb0bb2023-01-11 09:46:29 +08004817}
4818
4819//Set the ACS refresh period in seconds
4820INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
4821{
developer326d4232023-06-15 16:45:30 +08004822 char interface_name[IF_NAME_SIZE] = {0};
4823 int ret = -1;
4824 unsigned int if_idx = 0;
4825 struct unl unl_ins;
4826 struct nl_msg *msg = NULL;
4827 struct nlattr * msg_data = NULL;
4828 struct mtk_nl80211_param param;
4829
4830 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4831
4832 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4833 return RETURN_ERR;
4834
4835 if_idx = if_nametoindex(interface_name);
4836 if (!if_idx) {
4837 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4838 return RETURN_ERR;
4839 }
4840 /*init mtk nl80211 vendor cmd*/
4841 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
4842 param.if_type = NL80211_ATTR_IFINDEX;
4843 param.if_idx = if_idx;
4844
4845 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4846 if (ret) {
4847 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4848 return RETURN_ERR;
4849 }
4850
4851 /*add mtk vendor cmd data*/
4852 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
4853 wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME attribute error\n");
4854 nlmsg_free(msg);
4855 goto err;
4856 }
4857
4858 /*send mtk nl80211 vendor msg*/
4859 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4860
4861 if (ret) {
4862 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4863 goto err;
4864 }
4865 /*deinit mtk nl80211 vendor msg*/
4866 mtk_nl80211_deint(&unl_ins);
4867 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
4868
4869 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4870 return RETURN_OK;
4871err:
4872 mtk_nl80211_deint(&unl_ins);
4873 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developera3511852023-06-14 14:12:59 +08004874 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004875}
4876
4877//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
4878//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.
4879INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
4880{
developera3511852023-06-14 14:12:59 +08004881 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
4882 char extchannel[128] = {0};
4883 char interface_name[64] = {0};
developere40952c2023-06-15 18:46:43 +08004884 int ret = 0, len=0, res;
developera3511852023-06-14 14:12:59 +08004885 BOOL radio_enable = FALSE;
4886 wifi_band band;
developer72fb0bb2023-01-11 09:46:29 +08004887
developera3511852023-06-14 14:12:59 +08004888 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004889
developera3511852023-06-14 14:12:59 +08004890 if (NULL == output_string) {
4891 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
4892 return RETURN_ERR;
4893 }
4894 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
4895 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
4896 return RETURN_ERR;
4897 }
4898 if (radio_enable != TRUE) {
4899 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
4900 return RETURN_OK;
4901 }
4902 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4903 return RETURN_ERR;
4904 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08004905
developere40952c2023-06-15 18:46:43 +08004906 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
4907 if (os_snprintf_error(sizeof(cmd), res)) {
4908 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4909 return RETURN_ERR;
4910 }
developera3511852023-06-14 14:12:59 +08004911 ret = _syscmd(cmd, buf, sizeof(buf));
4912 len = strlen(buf);
4913 if((ret != 0) || (len == 0))
4914 {
4915 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4916 return RETURN_ERR;
4917 }
developer8666b312023-03-24 14:05:31 +08004918
developera3511852023-06-14 14:12:59 +08004919 band = wifi_index_to_band(radioIndex);
4920 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
4921 wifi_getRadioExtChannel(radioIndex, extchannel);
developere40952c2023-06-15 18:46:43 +08004922 if (strncmp(extchannel, "Auto", 4) != 0) {
4923 res = snprintf(buf, sizeof(buf), "40");
4924 if (os_snprintf_error(sizeof(buf), res)) {
4925 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4926 return RETURN_ERR;
4927 }
4928 }
4929 }
4930 res = snprintf(output_string, 64, "%sMHz", buf);
4931 if (os_snprintf_error(64, res)) {
4932 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4933 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08004934 }
developera3511852023-06-14 14:12:59 +08004935 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004936
developera3511852023-06-14 14:12:59 +08004937 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004938}
4939
4940enum mwctl_chan_width {
4941 MWCTL_CHAN_WIDTH_20,
4942 MWCTL_CHAN_WIDTH_40,
4943 MWCTL_CHAN_WIDTH_80,
4944 MWCTL_CHAN_WIDTH_160,
4945 MWCTL_CHAN_WIDTH_320,
4946};
4947
4948struct bw_option {
4949 unsigned int bandwith;
4950 enum mwctl_chan_width mode;
4951};
4952
4953struct bw_option bw_opt[] = {
4954 {20, MWCTL_CHAN_WIDTH_20},
4955 {40, MWCTL_CHAN_WIDTH_40},
4956 {80, MWCTL_CHAN_WIDTH_80},
4957 {160, MWCTL_CHAN_WIDTH_160},
4958 {320, MWCTL_CHAN_WIDTH_320},
4959};
4960
4961INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
4962{
4963 int ret = -1;
4964 int i;
4965 struct unl unl_ins;
4966 struct nl_msg *msg = NULL;
4967 struct nlattr * msg_data = NULL;
4968 struct mtk_nl80211_param param;
4969 bool b_match = FALSE;
4970
4971 /*init mtk nl80211 vendor cmd*/
4972 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
4973 param.if_type = NL80211_ATTR_WIPHY;
4974 param.if_idx = radio_index_to_phy(radioIndex);
4975
4976 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4977 if (ret) {
4978 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4979 return RETURN_ERR;
4980 }
4981
4982 /*add mtk vendor cmd data*/
4983 if (channel != NULL)
4984 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
4985 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
4986 nlmsg_free(msg);
4987 goto err;
4988 }
4989
4990 if (bandwidth != NULL) {
4991 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
4992 if (bw_opt[i].bandwith == *bandwidth) {
4993 b_match = true;
4994 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
4995 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
4996 nlmsg_free(msg);
4997 goto err;
4998 }
4999 break;
5000 }
5001 }
5002
5003 if (!b_match) {
5004 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
5005 nlmsg_free(msg);
5006 goto err;
5007 }
5008 }
5009
5010 /*send mtk nl80211 vendor msg*/
5011 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
5012 if (ret) {
5013 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
5014 goto err;
5015 }
5016 /*deinit mtk nl80211 vendor msg*/
5017 mtk_nl80211_deint(&unl_ins);
5018 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developera3511852023-06-14 14:12:59 +08005019 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developerfead3972023-05-25 20:15:02 +08005020
developera3511852023-06-14 14:12:59 +08005021 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08005022err:
5023 mtk_nl80211_deint(&unl_ins);
5024 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
5025 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005026}
developerfead3972023-05-25 20:15:02 +08005027
developer72fb0bb2023-01-11 09:46:29 +08005028//Set the Operating Channel Bandwidth.
5029INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
5030{
developera3511852023-06-14 14:12:59 +08005031 char config_file[128];
5032 char ht_value[16];
5033 char vht_value[16];
5034 char eht_value[16];
5035 struct params dat[3];
5036 wifi_band band = band_invalid;
5037 unsigned int bw = 20;
developere40952c2023-06-15 18:46:43 +08005038 int ret = 0, res1, res2, res3;
developer72fb0bb2023-01-11 09:46:29 +08005039
developera3511852023-06-14 14:12:59 +08005040 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005041
developera3511852023-06-14 14:12:59 +08005042 if(NULL == bandwidth)
5043 return RETURN_ERR;
5044 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08005045
developera3511852023-06-14 14:12:59 +08005046 if(strstr(bandwidth,"320") != NULL) {
developere40952c2023-06-15 18:46:43 +08005047 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5048 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
5049 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developera3511852023-06-14 14:12:59 +08005050 bw = 320;
5051 } else if(strstr(bandwidth,"160") != NULL) {
developere40952c2023-06-15 18:46:43 +08005052 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5053 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
5054 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developera3511852023-06-14 14:12:59 +08005055 bw = 160;
5056 } else if(strstr(bandwidth,"80") != NULL) {
developere40952c2023-06-15 18:46:43 +08005057 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5058 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
5059 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developera3511852023-06-14 14:12:59 +08005060 bw = 80;
5061 } else if(strstr(bandwidth,"40") != NULL) {
developere40952c2023-06-15 18:46:43 +08005062 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5063 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
5064 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developera3511852023-06-14 14:12:59 +08005065 bw = 40;
5066 } else if(strstr(bandwidth,"20") != NULL) {
developere40952c2023-06-15 18:46:43 +08005067 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
5068 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
5069 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developera3511852023-06-14 14:12:59 +08005070 bw = 20;
5071 } else {
developer37646972023-06-29 10:58:43 +08005072 if (fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth) < 0)
5073 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08005074 return RETURN_ERR;
5075 }
developer72fb0bb2023-01-11 09:46:29 +08005076
developer37646972023-06-29 10:58:43 +08005077 if (os_snprintf_error(sizeof(ht_value), res1) ||
5078 os_snprintf_error(sizeof(vht_value), res2) ||
5079 os_snprintf_error(sizeof(eht_value), res3)) {
developere40952c2023-06-15 18:46:43 +08005080 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5081 return RETURN_ERR;
5082 }
5083
5084 res1 = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5085 if (os_snprintf_error(sizeof(config_file), res1)) {
5086 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5087 return RETURN_ERR;
5088 }
developera3511852023-06-14 14:12:59 +08005089 dat[0].name = "HT_BW";
5090 dat[0].value = ht_value;
5091 dat[1].name = "VHT_BW";
5092 dat[1].value = vht_value;
5093 dat[2].name = "EHT_ApBw";
5094 dat[2].value = eht_value;
5095 wifi_datfileWrite(config_file, dat, 3);
5096 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
developerfead3972023-05-25 20:15:02 +08005097 if (ret != RETURN_OK) {
developer37646972023-06-29 10:58:43 +08005098 if (fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__) < 0)
5099 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08005100 return RETURN_ERR;
5101 }
developer72fb0bb2023-01-11 09:46:29 +08005102
developera3511852023-06-14 14:12:59 +08005103 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5104 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005105}
5106
developer72fb0bb2023-01-11 09:46:29 +08005107//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
5108//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.
5109INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
5110{
developera3511852023-06-14 14:12:59 +08005111 char config_file[64] = {0};
5112 char config_dat_file[64] = {0};
5113 char mode_str[16] = {0};
5114 char buf[64] = {0};
5115 char cmd[MAX_CMD_SIZE] = {0};
5116 char interface_name[64] = {0};
5117 int ret = 0, len=0;
5118 wifi_band band;
5119 ULONG channel = 0;
5120 int centr_channel = 0;
5121 UINT mode_map = 0;
developere40952c2023-06-15 18:46:43 +08005122 int freq=0, res;
developer72fb0bb2023-01-11 09:46:29 +08005123
developera3511852023-06-14 14:12:59 +08005124 if (output_string == NULL)
5125 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005126
developer86035662023-06-28 19:21:12 +08005127 if (wifi_getRadioMode(radioIndex, mode_str, &mode_map) != RETURN_OK) {
5128 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode fail\n");
5129 }
developer72fb0bb2023-01-11 09:46:29 +08005130
developera3511852023-06-14 14:12:59 +08005131 band = wifi_index_to_band(radioIndex);
5132 if (band == band_invalid)
5133 return RETURN_ERR;
5134 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5135 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005136
developere40952c2023-06-15 18:46:43 +08005137 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5138 if (os_snprintf_error(sizeof(config_file), res)) {
5139 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5140 return RETURN_ERR;
5141 }
5142
5143 res = snprintf(output_string, 64, "Auto");
5144 if (os_snprintf_error(64, res)) {
5145 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5146 return RETURN_ERR;
5147 }
developer72fb0bb2023-01-11 09:46:29 +08005148
developera3511852023-06-14 14:12:59 +08005149 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
5150 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
developere40952c2023-06-15 18:46:43 +08005151 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5152 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5153 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5154 return RETURN_ERR;
5155 }
developerb758dfd2023-06-21 17:32:07 +08005156
developera3511852023-06-14 14:12:59 +08005157 wifi_halgetRadioExtChannel(config_dat_file, output_string);
developer37646972023-06-29 10:58:43 +08005158 if (!(mode_map&WIFI_MODE_N)) {
developere40952c2023-06-15 18:46:43 +08005159 res = snprintf(output_string, 64, "Auto");
developer37646972023-06-29 10:58:43 +08005160 if (os_snprintf_error(64, res)) {
5161 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5162 return RETURN_ERR;
5163 }
5164 }
developera3511852023-06-14 14:12:59 +08005165 } else {
5166 // 5G and 6G band with ac or ax mode.
5167 wifi_getRadioChannel(radioIndex, &channel);
developere40952c2023-06-15 18:46:43 +08005168 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
5169 if (os_snprintf_error(sizeof(cmd), res)) {
5170 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5171 return RETURN_ERR;
5172 }
developerd1824452023-05-18 12:30:04 +08005173
developera3511852023-06-14 14:12:59 +08005174 ret = _syscmd(cmd, buf, sizeof(buf));
5175 len = strlen(buf);
5176 if((ret != 0) || (len == 0))
5177 {
5178 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
5179 return RETURN_ERR;
5180 }
5181 sscanf(buf, "%d", &freq);
5182 centr_channel = ieee80211_frequency_to_channel(freq);
5183 if (centr_channel > (int)channel)
developere40952c2023-06-15 18:46:43 +08005184 res = snprintf(output_string, 64, "AboveControlChannel");
developera3511852023-06-14 14:12:59 +08005185 else
developere40952c2023-06-15 18:46:43 +08005186 res = snprintf(output_string, 64, "BelowControlChannel");
5187
5188 if (os_snprintf_error(64, res)) {
5189 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5190 return RETURN_ERR;
5191 }
developera3511852023-06-14 14:12:59 +08005192 }
developer72fb0bb2023-01-11 09:46:29 +08005193
developera3511852023-06-14 14:12:59 +08005194 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005195}
5196
5197//Set the extension channel.
5198INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08005199{
developera3511852023-06-14 14:12:59 +08005200 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5201 struct params params={0};
5202 char config_file[64] = {0};
5203 char config_dat_file[64] = {0};
5204 char ext_channel[64] = {0};
5205 char buf[128] = {0};
5206 char cmd[128] = {0};
developerc14d83a2023-06-29 20:09:42 +08005207 int max_radio_num =0, ret = 0;
5208 long int bandwidth = 0;
developera3511852023-06-14 14:12:59 +08005209 unsigned long channel = 0;
5210 bool stbcEnable = FALSE;
5211 params.name = "ht_capab";
5212 wifi_band band;
developere40952c2023-06-15 18:46:43 +08005213 int res;
developer72fb0bb2023-01-11 09:46:29 +08005214
developer75bd10c2023-06-27 11:34:08 +08005215 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5216 if (os_snprintf_error(sizeof(config_file), res)) {
5217 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5218 return RETURN_ERR;
5219 }
5220
developere40952c2023-06-15 18:46:43 +08005221 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
5222 if (os_snprintf_error(sizeof(cmd), res)) {
5223 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5224 return RETURN_ERR;
5225 }
developera3511852023-06-14 14:12:59 +08005226 _syscmd(cmd, buf, sizeof(buf));
5227 if (strlen(buf) != 0)
5228 stbcEnable = TRUE;
5229 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
5230 return RETURN_ERR;
developerc14d83a2023-06-29 20:09:42 +08005231 if (hal_strtol(buf, 10, &bandwidth) < 0) {
5232 wifi_debug(DEBUG_ERROR, "strtol fail\n");
5233 }
developera3511852023-06-14 14:12:59 +08005234 // TDK expected to get error with 20MHz
5235 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
5236 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
5237 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005238
developera3511852023-06-14 14:12:59 +08005239 band = wifi_index_to_band(radioIndex);
5240 if (band == band_invalid)
5241 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005242
developera3511852023-06-14 14:12:59 +08005243 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
5244 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005245
developerc14d83a2023-06-29 20:09:42 +08005246 res = snprintf(buf, sizeof(buf), "HT%ld", bandwidth);
developere40952c2023-06-15 18:46:43 +08005247 if (os_snprintf_error(sizeof(buf), res)) {
5248 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5249 return RETURN_ERR;
5250 }
developera3511852023-06-14 14:12:59 +08005251 ret = util_get_sec_chan_offset(channel, buf);
5252 if (ret == -EINVAL)
5253 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005254
developera3511852023-06-14 14:12:59 +08005255 if(NULL!= strstr(string,"Above")) {
5256 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
5257 return RETURN_OK;
developer32f2a182023-06-27 19:50:41 +08005258 memcpy(ext_channel, "Above", strlen("Above"));
developera3511852023-06-14 14:12:59 +08005259 } else if(NULL!= strstr(string,"Below")) {
5260 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
5261 return RETURN_OK;
developer32f2a182023-06-27 19:50:41 +08005262 memcpy(ext_channel, "Below", strlen("Below"));
developera3511852023-06-14 14:12:59 +08005263 } else {
5264 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08005265 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08005266 }
5267 params.name = "HT_EXTCHA";
5268 params.value = ext_channel;
developer72fb0bb2023-01-11 09:46:29 +08005269
developere75ba632023-06-29 16:03:33 +08005270 res = snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08005271 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5272 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5273 return RETURN_ERR;
5274 }
developera3511852023-06-14 14:12:59 +08005275 wifi_datfileWrite(config_dat_file, &params, 1);
developerd1824452023-05-18 12:30:04 +08005276
developera3511852023-06-14 14:12:59 +08005277 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08005278 if(max_radio_num== 0){
5279 return RETURN_ERR;
5280 }
developera3511852023-06-14 14:12:59 +08005281 for(int i=0; i<=MAX_APS/max_radio_num; i++)
5282 {
developer32f2a182023-06-27 19:50:41 +08005283 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
5284 if (os_snprintf_error(sizeof(config_file), res)) {
5285 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5286 return RETURN_ERR;
5287 }
developera3511852023-06-14 14:12:59 +08005288 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
5289 }
developer72fb0bb2023-01-11 09:46:29 +08005290
developera3511852023-06-14 14:12:59 +08005291 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
5292 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5293 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005294}
5295
5296//Get the guard interval value. eg "400nsec" or "800nsec"
5297//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.
5298INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
5299{
developera3511852023-06-14 14:12:59 +08005300 wifi_guard_interval_t GI;
developer32f2a182023-06-27 19:50:41 +08005301 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08005302
developera3511852023-06-14 14:12:59 +08005303 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005304
developera3511852023-06-14 14:12:59 +08005305 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
5306 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005307
developer32f2a182023-06-27 19:50:41 +08005308 if (GI == wifi_guard_interval_400) {
5309 len = strlen("400nsec");
5310 memcpy(output_string, "400nsec", len);
5311 } else if (GI == wifi_guard_interval_800) {
5312 len = strlen("800nsec");
5313 memcpy(output_string, "800nsec", strlen("800nsec"));
5314 } else if (GI == wifi_guard_interval_1600) {
5315 len = strlen("1600nsec");
5316 memcpy(output_string, "1600nsec", strlen("1600nsec"));
5317 } else if (GI == wifi_guard_interval_3200) {
5318 len = strlen("3200nsec");
5319 memcpy(output_string, "3200nsec", strlen("3200nsec"));
5320 } else {
5321 len = strlen("Auto");
5322 memcpy(output_string, "Auto", strlen("Auto"));
5323 }
5324 output_string[len] = '\0';
developera3511852023-06-14 14:12:59 +08005325 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5326 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005327}
5328
5329//Set the guard interval value.
5330INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
5331{
developera3511852023-06-14 14:12:59 +08005332 wifi_guard_interval_t GI;
5333 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08005334
developera3511852023-06-14 14:12:59 +08005335 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005336
developera3511852023-06-14 14:12:59 +08005337 if (strcmp(string, "400nsec") == 0)
5338 GI = wifi_guard_interval_400;
5339 else if (strcmp(string , "800nsec") == 0)
5340 GI = wifi_guard_interval_800;
5341 else if (strcmp(string , "1600nsec") == 0)
5342 GI = wifi_guard_interval_1600;
5343 else if (strcmp(string , "3200nsec") == 0)
5344 GI = wifi_guard_interval_3200;
5345 else
5346 GI = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +08005347
developera3511852023-06-14 14:12:59 +08005348 ret = wifi_setGuardInterval(radioIndex, GI);
developer72fb0bb2023-01-11 09:46:29 +08005349
developera3511852023-06-14 14:12:59 +08005350 if (ret == RETURN_ERR) {
5351 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
5352 return RETURN_ERR;
5353 }
developer72fb0bb2023-01-11 09:46:29 +08005354
developera3511852023-06-14 14:12:59 +08005355 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5356 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005357}
5358
5359//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
5360INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
5361{
developera3511852023-06-14 14:12:59 +08005362 char buf[32]={0};
5363 char mcs_file[64] = {0};
5364 char cmd[MAX_CMD_SIZE] = {0};
5365 UINT mode_bitmap = 0;
developere40952c2023-06-15 18:46:43 +08005366 int res;
developerc14d83a2023-06-29 20:09:42 +08005367 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08005368
developera3511852023-06-14 14:12:59 +08005369 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5370 if(output_int == NULL)
5371 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005372 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
5373 if (os_snprintf_error(sizeof(mcs_file), res)) {
5374 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5375 return RETURN_ERR;
5376 }
5377
5378 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
5379 if (os_snprintf_error(sizeof(cmd), res)) {
5380 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5381 return RETURN_ERR;
5382 }
developer72fb0bb2023-01-11 09:46:29 +08005383
developera3511852023-06-14 14:12:59 +08005384 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08005385 if (strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +08005386 if (hal_strtol(buf, 10, &tmp) < 0) {
5387 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08005388 }
developerc14d83a2023-06-29 20:09:42 +08005389 *output_int = tmp;
developerd14dff12023-06-28 22:47:44 +08005390 } else {
developera3511852023-06-14 14:12:59 +08005391 // output the max MCS for the current radio mode
5392 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
5393 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
5394 return RETURN_ERR;
5395 }
5396 if (mode_bitmap & WIFI_MODE_AX) {
5397 *output_int = 11;
5398 } else if (mode_bitmap & WIFI_MODE_AC) {
5399 *output_int = 9;
5400 } else if (mode_bitmap & WIFI_MODE_N) {
5401 *output_int = 7;
5402 }
5403 }
5404 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005405
developera3511852023-06-14 14:12:59 +08005406 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005407}
5408
5409//Set the Modulation Coding Scheme index
5410INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
5411{
developera3511852023-06-14 14:12:59 +08005412 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
5413 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
5414 char config_file[64] = {0};
5415 char set_value[16] = {0};
5416 char mcs_file[32] = {0};
5417 struct params set_config = {0};
5418 FILE *f = NULL;
5419 INT nss = 0;
5420 int ant_bitmap = 0;
5421 unsigned short cal_value = 0;
5422 UCHAR tval = 0, i = 0;
developere40952c2023-06-15 18:46:43 +08005423 int res;
developer72fb0bb2023-01-11 09:46:29 +08005424
developera3511852023-06-14 14:12:59 +08005425 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005426
developere40952c2023-06-15 18:46:43 +08005427 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5428 if (os_snprintf_error(sizeof(config_file), res)) {
5429 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5430 return RETURN_ERR;
5431 }
developer72fb0bb2023-01-11 09:46:29 +08005432
developera3511852023-06-14 14:12:59 +08005433 // -1 means auto
5434 if (MCS > 15 || MCS < -1) {
developer75bd10c2023-06-27 11:34:08 +08005435 wifi_debug(DEBUG_ERROR, "invalid MCS %d\n", MCS);
developera3511852023-06-14 14:12:59 +08005436 return RETURN_ERR;
5437 }
5438 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
5439 for(; ant_bitmap > 0; ant_bitmap >>= 1)
5440 nss += 1;
5441 //printf("%s:nss = %d\n", __func__, nss);
5442 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
5443 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
5444 if (MCS > 9 || MCS == -1)
5445 tval = 2;/*one stream value*/
5446 else if (MCS > 7)
5447 tval = 1;
5448 else
5449 tval = 0;
5450 for (i = 0; i < nss; i++)
5451 cal_value |= (tval << (2*i));
developere40952c2023-06-15 18:46:43 +08005452 res = snprintf(set_value, sizeof(set_value), "%x", cal_value);
5453 if (os_snprintf_error(sizeof(set_value), res)) {
5454 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5455 return RETURN_ERR;
5456 }
5457
developera3511852023-06-14 14:12:59 +08005458 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
5459 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
5460 set_config.value = set_value;
developer72fb0bb2023-01-11 09:46:29 +08005461
developera3511852023-06-14 14:12:59 +08005462 wifi_hostapdWrite(config_file, &set_config, 1);
5463 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
developer72fb0bb2023-01-11 09:46:29 +08005464
developera3511852023-06-14 14:12:59 +08005465 // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
developere40952c2023-06-15 18:46:43 +08005466 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
5467 if (os_snprintf_error(sizeof(mcs_file), res)) {
5468 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5469 return RETURN_ERR;
5470 }
5471
developera3511852023-06-14 14:12:59 +08005472 f = fopen(mcs_file, "w");
5473 if (f == NULL) {
developere75ba632023-06-29 16:03:33 +08005474 if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
5475 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08005476 return RETURN_ERR;
5477 }
developere75ba632023-06-29 16:03:33 +08005478 if (fprintf(f, "%d", MCS) < 0)
5479 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
5480 if (fclose(f) == EOF) {
5481 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
5482 return RETURN_ERR;
5483 }
developer72fb0bb2023-01-11 09:46:29 +08005484
developera3511852023-06-14 14:12:59 +08005485 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5486 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005487}
5488
5489//Get supported Transmit Power list, eg : "0,25,50,75,100"
5490//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.
5491INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
5492{
developere40952c2023-06-15 18:46:43 +08005493 int res;
5494 if (NULL == output_list)
5495 return RETURN_ERR;
5496 res = snprintf(output_list, 64,"0,25,50,75,100");
5497 if (os_snprintf_error(64, res)) {
5498 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5499 return RETURN_ERR;
5500 }
5501
5502 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005503}
5504
5505//Get current Transmit Power in dBm units.
5506//The transmite power level is in units of full power for this radio.
5507INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
5508{
developera3511852023-06-14 14:12:59 +08005509 char interface_name[16] = {0};
5510 char cmd[MAX_CMD_SIZE]={0};
5511 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08005512 char pwr_file[128]={0};
developere40952c2023-06-15 18:46:43 +08005513 int res;
developera1255e42023-05-13 17:45:02 +08005514
developera3511852023-06-14 14:12:59 +08005515 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005516
developera3511852023-06-14 14:12:59 +08005517 if(output_ulong == NULL)
5518 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005519
developera3511852023-06-14 14:12:59 +08005520 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5521 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005522 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
5523 if (os_snprintf_error(sizeof(pwr_file), res)) {
5524 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5525 return RETURN_ERR;
5526 }
5527
5528 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
5529 if (os_snprintf_error(sizeof(cmd), res)) {
5530 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5531 return RETURN_ERR;
5532 }
5533
developera1255e42023-05-13 17:45:02 +08005534 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +08005535 if (strlen(buf) > 0) {
5536 if (hal_strtoul(buf, 10, output_ulong) < 0) {
5537 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08005538 }
5539 } else
developera1255e42023-05-13 17:45:02 +08005540 *output_ulong = 100;
developera3511852023-06-14 14:12:59 +08005541 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5542 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005543}
5544
5545//Set Transmit Power
5546//The transmite power level is in units of full power for this radio.
5547INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
5548{
developera3511852023-06-14 14:12:59 +08005549 char interface_name[16] = {0};
5550 char *support;
5551 char buf[128]={0};
5552 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08005553 char pwr_file[128]={0};
developera3511852023-06-14 14:12:59 +08005554 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08005555 int if_idx, ret = 0;
5556 struct nl_msg *msg = NULL;
5557 struct nlattr * msg_data = NULL;
5558 struct mtk_nl80211_param param;
5559 struct unl unl_ins;
developere40952c2023-06-15 18:46:43 +08005560 int res;
developer72fb0bb2023-01-11 09:46:29 +08005561
developera3511852023-06-14 14:12:59 +08005562 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005563
developera3511852023-06-14 14:12:59 +08005564 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5565 return RETURN_ERR;
5566 // Get the Tx power supported list and check that is the input in the list
developere40952c2023-06-15 18:46:43 +08005567 res = snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
5568 if (os_snprintf_error(sizeof(txpower_str), res)) {
5569 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5570 return RETURN_ERR;
5571 }
developera3511852023-06-14 14:12:59 +08005572 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
5573 support = strtok(buf, ",");
5574 while(true)
5575 {
5576 if(support == NULL) { // input not in the list
5577 wifi_dbg_printf("Input value is invalid.\n");
5578 return RETURN_ERR;
5579 }
5580 if (strncmp(txpower_str, support, strlen(support)) == 0) {
5581 break;
5582 }
5583 support = strtok(NULL, ",");
5584 }
developerfead3972023-05-25 20:15:02 +08005585
5586 if_idx = if_nametoindex(interface_name);
5587 /*init mtk nl80211 vendor cmd*/
5588 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
5589 param.if_type = NL80211_ATTR_IFINDEX;
5590 param.if_idx = if_idx;
5591 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
5592 if (ret) {
5593 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
5594 return RETURN_ERR;
5595 }
5596 /*add mtk vendor cmd data*/
5597 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
5598 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
5599 nlmsg_free(msg);
5600 goto err;
5601 }
5602
5603 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
5604 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
5605 nlmsg_free(msg);
5606 goto err;
5607 }
5608
5609 /*send mtk nl80211 vendor msg*/
5610 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
5611 if (ret) {
5612 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
5613 goto err;
5614 }
5615 /*deinit mtk nl80211 vendor msg*/
5616 mtk_nl80211_deint(&unl_ins);
5617 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
5618
developere40952c2023-06-15 18:46:43 +08005619 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
5620 if (os_snprintf_error(sizeof(pwr_file), res)) {
5621 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5622 return RETURN_ERR;
5623 }
5624
developera3511852023-06-14 14:12:59 +08005625 f = fopen(pwr_file, "w");
5626 if (f == NULL) {
developerc14d83a2023-06-29 20:09:42 +08005627 wifi_debug(DEBUG_ERROR, "%s: fopen failed\n", __func__);
developera3511852023-06-14 14:12:59 +08005628 return RETURN_ERR;
5629 }
5630 fprintf(f, "%lu", TransmitPower);
developerc14d83a2023-06-29 20:09:42 +08005631 if (fclose(f) == EOF)
5632 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera1255e42023-05-13 17:45:02 +08005633 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08005634err:
5635 mtk_nl80211_deint(&unl_ins);
5636 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
5637 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005638}
5639
5640//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
5641INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
5642{
developera3511852023-06-14 14:12:59 +08005643 if (NULL == Supported)
5644 return RETURN_ERR;
5645 *Supported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08005646
developera3511852023-06-14 14:12:59 +08005647 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005648}
5649
5650//Get 80211h feature enable
5651INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
5652{
developera3511852023-06-14 14:12:59 +08005653 char buf[64]={'\0'};
5654 char config_file[64] = {'\0'};
developer75bd10c2023-06-27 11:34:08 +08005655 int res;
developer72fb0bb2023-01-11 09:46:29 +08005656
developera3511852023-06-14 14:12:59 +08005657 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5658 if(enable == NULL)
5659 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005660
developer75bd10c2023-06-27 11:34:08 +08005661 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5662 if (os_snprintf_error(sizeof(config_file), res)) {
5663 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5664 return RETURN_ERR;
5665 }
developera3511852023-06-14 14:12:59 +08005666 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
5667 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005668
developera3511852023-06-14 14:12:59 +08005669 if (strncmp(buf, "1", 1) == 0)
5670 *enable = TRUE;
5671 else
5672 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08005673
developera3511852023-06-14 14:12:59 +08005674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5675 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005676}
5677
5678//Set 80211h feature enable
5679INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
5680{
developera3511852023-06-14 14:12:59 +08005681 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5682 struct params params={'\0'};
5683 struct params dat={0};
5684 char config_file[MAX_BUF_SIZE] = {0};
5685 char config_dat_file[MAX_BUF_SIZE] = {0};
5686 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08005687 int res;
developer72fb0bb2023-01-11 09:46:29 +08005688
developera3511852023-06-14 14:12:59 +08005689 params.name = "ieee80211h";
developer72fb0bb2023-01-11 09:46:29 +08005690
developera3511852023-06-14 14:12:59 +08005691 if (enable) {
5692 params.value = "1";
5693 } else {
5694 params.value = "0";
5695 }
developer72fb0bb2023-01-11 09:46:29 +08005696
developera3511852023-06-14 14:12:59 +08005697 dat.name = "IEEE80211H";
5698 dat.value = params.value;
developerd1824452023-05-18 12:30:04 +08005699
developera3511852023-06-14 14:12:59 +08005700 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08005701 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5702 if (os_snprintf_error(sizeof(config_file), res)) {
5703 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5704 return RETURN_ERR;
5705 }
5706
5707 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5708 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5709 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5710 return RETURN_ERR;
5711 }
developer69b61b02023-03-07 17:17:44 +08005712
developera3511852023-06-14 14:12:59 +08005713 wifi_hostapdWrite(config_file, &params, 1);
5714 wifi_datfileWrite(config_dat_file, &dat, 1);
5715 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
5716 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5717 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005718}
5719
5720//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.
5721INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
5722{
developera3511852023-06-14 14:12:59 +08005723 if (NULL == output)
5724 return RETURN_ERR;
5725 *output=100;
developer72fb0bb2023-01-11 09:46:29 +08005726
developera3511852023-06-14 14:12:59 +08005727 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005728}
5729
5730//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.
5731INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
5732{
developera3511852023-06-14 14:12:59 +08005733 if (NULL == output)
5734 return RETURN_ERR;
5735 *output = -99;
developer72fb0bb2023-01-11 09:46:29 +08005736
developera3511852023-06-14 14:12:59 +08005737 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005738}
5739
5740INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
5741{
developera3511852023-06-14 14:12:59 +08005742 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005743}
5744
5745
5746//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
5747INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
5748{
developera3511852023-06-14 14:12:59 +08005749 char interface_name[16] = {0};
5750 char cmd[MAX_BUF_SIZE]={'\0'};
5751 char buf[MAX_CMD_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08005752 int res;
developer72fb0bb2023-01-11 09:46:29 +08005753
developera3511852023-06-14 14:12:59 +08005754 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5755 if(output == NULL)
5756 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005757
developera3511852023-06-14 14:12:59 +08005758 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5759 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005760 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
5761 if (os_snprintf_error(sizeof(cmd), res)) {
5762 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5763 return RETURN_ERR;
5764 }
5765
developera3511852023-06-14 14:12:59 +08005766 _syscmd(cmd, buf, sizeof(buf));
5767 *output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08005768
developera3511852023-06-14 14:12:59 +08005769 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5770 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005771}
developer69b61b02023-03-07 17:17:44 +08005772
developer72fb0bb2023-01-11 09:46:29 +08005773INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
5774{
developera3511852023-06-14 14:12:59 +08005775 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5776 struct params params={'\0'};
5777 char buf[MAX_BUF_SIZE] = {'\0'};
5778 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08005779 int res;
developer72fb0bb2023-01-11 09:46:29 +08005780
developera3511852023-06-14 14:12:59 +08005781 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
5782 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005783
developera3511852023-06-14 14:12:59 +08005784 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08005785 res = snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
5786 if (os_snprintf_error(sizeof(buf), res)) {
5787 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5788 return RETURN_ERR;
5789 }
5790
developera3511852023-06-14 14:12:59 +08005791 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08005792
developer75bd10c2023-06-27 11:34:08 +08005793 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5794 if (os_snprintf_error(sizeof(config_file), res)) {
5795 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5796 return RETURN_ERR;
5797 }
developera3511852023-06-14 14:12:59 +08005798 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08005799
developera3511852023-06-14 14:12:59 +08005800 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
5801 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5802 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005803}
5804
5805//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.
5806INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
5807{
developera3511852023-06-14 14:12:59 +08005808 //TODO: need to revisit below implementation
5809 char *temp;
5810 char temp_output[128] = {0};
5811 char temp_TransmitRates[64] = {0};
5812 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +08005813 int res;
developer72fb0bb2023-01-11 09:46:29 +08005814
developera3511852023-06-14 14:12:59 +08005815 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5816 if (NULL == output)
5817 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08005818
5819 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5820 if (os_snprintf_error(sizeof(config_file), res)) {
5821 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5822 return RETURN_ERR;
5823 }
developera3511852023-06-14 14:12:59 +08005824 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08005825
developera3511852023-06-14 14:12:59 +08005826 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
5827 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
5828 } else {
5829 temp = strtok(temp_TransmitRates," ");
5830 while(temp!=NULL)
5831 {
5832 // Convert 100 kbps to Mbps
5833 temp[strlen(temp)-1]=0;
5834 if((temp[0]=='5') && (temp[1]=='\0'))
5835 {
5836 temp="5.5";
5837 }
developer32f2a182023-06-27 19:50:41 +08005838 if (strlen(temp) >= sizeof(temp_output))
5839 return RETURN_ERR;
5840 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005841 temp = strtok(NULL," ");
5842 if(temp!=NULL)
5843 {
developer32f2a182023-06-27 19:50:41 +08005844 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
5845 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005846 }
5847 }
developer32f2a182023-06-27 19:50:41 +08005848 memcpy(output, temp_output, strlen(temp_output));
5849 output[strlen(temp_output)] = '\0';
developera3511852023-06-14 14:12:59 +08005850 }
5851 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5852 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005853}
5854
5855INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
5856{
developera3511852023-06-14 14:12:59 +08005857 char *temp;
developer32f2a182023-06-27 19:50:41 +08005858 char temp1[128] = {0};
5859 char temp_output[128] = {0};
5860 char temp_TransmitRates[128] = {0};
5861 char set[128] = {0};
5862 char sub_set[128] = {0};
developera3511852023-06-14 14:12:59 +08005863 int set_count=0,subset_count=0;
5864 int set_index=0,subset_index=0;
5865 char *token;
5866 int flag=0, i=0;
5867 struct params params={'\0'};
5868 char config_file[MAX_BUF_SIZE] = {0};
5869 wifi_band band = wifi_index_to_band(radioIndex);
developer32f2a182023-06-27 19:50:41 +08005870 int res;
developer72fb0bb2023-01-11 09:46:29 +08005871
developera3511852023-06-14 14:12:59 +08005872 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5873 if(NULL == TransmitRates)
5874 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +08005875 if (strlen(TransmitRates) >= sizeof(sub_set))
5876 return RETURN_ERR;
5877
5878 memcpy(sub_set, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08005879
developera3511852023-06-14 14:12:59 +08005880 //Allow only supported Data transmit rate to be set
5881 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
5882 token = strtok(sub_set,",");
5883 while( token != NULL ) /* split the basic rate to be set, by comma */
5884 {
5885 sub_set[subset_count]=atoi(token);
5886 subset_count++;
5887 token=strtok(NULL,",");
5888 }
5889 token=strtok(set,",");
5890 while(token!=NULL) /* split the supported rate by comma */
5891 {
5892 set[set_count]=atoi(token);
5893 set_count++;
5894 token=strtok(NULL,",");
5895 }
5896 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
5897 {
5898 for(set_index=0;set_index < set_count;set_index++)
5899 {
5900 flag=0;
5901 if(sub_set[subset_index]==set[set_index])
5902 break;
5903 else
5904 flag=1; /* No match found */
5905 }
5906 if(flag==1)
5907 return RETURN_ERR; //If value not found return Error
5908 }
developer32f2a182023-06-27 19:50:41 +08005909
5910 if (strlen(TransmitRates) >= sizeof(temp_TransmitRates))
5911 return RETURN_ERR;
5912
5913 memcpy(temp_TransmitRates, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08005914
developera3511852023-06-14 14:12:59 +08005915 for(i=0;i<strlen(temp_TransmitRates);i++)
5916 {
5917 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
5918 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
5919 {
5920 continue;
5921 }
5922 else
5923 {
5924 return RETURN_ERR;
5925 }
5926 }
developera3511852023-06-14 14:12:59 +08005927 temp = strtok(temp_TransmitRates,",");
5928 while(temp!=NULL)
5929 {
developer32f2a182023-06-27 19:50:41 +08005930 if (strlen(temp) >= sizeof(temp1))
5931 return RETURN_ERR;
5932 strncpy(temp1, temp, strlen(temp));
developera3511852023-06-14 14:12:59 +08005933 if(band == band_5)
5934 {
5935 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
5936 {
5937 return RETURN_ERR;
5938 }
5939 }
developer72fb0bb2023-01-11 09:46:29 +08005940
developera3511852023-06-14 14:12:59 +08005941 if(strcmp(temp,"5.5")==0)
5942 {
developer32f2a182023-06-27 19:50:41 +08005943 memcpy(temp1, "55", 2);
developera3511852023-06-14 14:12:59 +08005944 }
5945 else
5946 {
developer32f2a182023-06-27 19:50:41 +08005947 if (strlen(temp1) >= (sizeof(temp1) - 1))
5948 return RETURN_ERR;
5949 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +08005950 }
developer32f2a182023-06-27 19:50:41 +08005951 if (strlen(temp1) >= (sizeof(temp_output) - strlen(temp_output)))
5952 return RETURN_ERR;
5953 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005954 temp = strtok(NULL,",");
5955 if(temp!=NULL)
5956 {
developer32f2a182023-06-27 19:50:41 +08005957 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
5958 return RETURN_ERR;
5959 strncat(temp_output," ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005960 }
5961 }
developer32f2a182023-06-27 19:50:41 +08005962 memcpy(TransmitRates, temp_output, strlen(temp_output));
5963 TransmitRates[strlen(temp_output)] = '\0';
5964
developera3511852023-06-14 14:12:59 +08005965 params.name= "basic_rates";
5966 params.value =TransmitRates;
developer72fb0bb2023-01-11 09:46:29 +08005967
developera3511852023-06-14 14:12:59 +08005968 wifi_dbg_printf("\n%s:",__func__);
5969 wifi_dbg_printf("\nparams.value=%s\n",params.value);
5970 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
developer32f2a182023-06-27 19:50:41 +08005971 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,radioIndex);
5972 if (os_snprintf_error(sizeof(config_file), res)) {
5973 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5974 return RETURN_ERR;
5975 }
5976
developera3511852023-06-14 14:12:59 +08005977 wifi_hostapdWrite(config_file,&params,1);
5978 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5979 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005980}
5981
developer72fb0bb2023-01-11 09:46:29 +08005982INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
5983{
developera3511852023-06-14 14:12:59 +08005984 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5985 output_struct->radio_BytesSent = 0;
5986 output_struct->radio_BytesReceived = 0;
5987 output_struct->radio_PacketsSent = 0;
5988 output_struct->radio_PacketsReceived = 0;
5989 output_struct->radio_ErrorsSent = 0;
5990 output_struct->radio_ErrorsReceived = 0;
5991 output_struct->radio_DiscardPacketsSent = 0;
5992 output_struct->radio_DiscardPacketsReceived = 0;
5993 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5994 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005995}
5996
5997
5998INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
5999{
developera3511852023-06-14 14:12:59 +08006000 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6001 CHAR buf[MAX_CMD_SIZE] = {0};
6002 CHAR Value[MAX_BUF_SIZE] = {0};
6003 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08006004 int res;
developer37646972023-06-29 10:58:43 +08006005 unsigned long ret;
developer72fb0bb2023-01-11 09:46:29 +08006006
developera3511852023-06-14 14:12:59 +08006007 if (ifname == NULL || strlen(ifname) <= 1)
6008 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006009
developere40952c2023-06-15 18:46:43 +08006010 res = snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
6011 if (os_snprintf_error(sizeof(buf), res)) {
6012 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6013 return RETURN_ERR;
6014 }
6015
developera3511852023-06-14 14:12:59 +08006016 system(buf);
developer72fb0bb2023-01-11 09:46:29 +08006017
developera3511852023-06-14 14:12:59 +08006018 fp = fopen("/tmp/Radio_Stats.txt", "r");
6019 if(fp == NULL)
6020 {
6021 printf("/tmp/Radio_Stats.txt not exists \n");
6022 return RETURN_ERR;
6023 }
developerd14dff12023-06-28 22:47:44 +08006024 if (fclose(fp) != 0) {
6025 wifi_debug(DEBUG_ERROR, "fclose fail\n");
6026 return RETURN_ERR;
6027 }
developer72fb0bb2023-01-11 09:46:29 +08006028
developer75bd10c2023-06-27 11:34:08 +08006029 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
6030 if (os_snprintf_error(sizeof(buf), res)) {
6031 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6032 return RETURN_ERR;
6033 }
developera3511852023-06-14 14:12:59 +08006034 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006035
6036 if (hal_strtoul(Value, 10, &ret) < 0) {
developer37646972023-06-29 10:58:43 +08006037 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6038 return RETURN_ERR;
6039 }
developerc14d83a2023-06-29 20:09:42 +08006040
developer37646972023-06-29 10:58:43 +08006041 pStats->radio_PacketsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006042
developer86035662023-06-28 19:21:12 +08006043 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
6044 if (os_snprintf_error(sizeof(buf), res)) {
6045 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6046 return RETURN_ERR;
6047 }
developera3511852023-06-14 14:12:59 +08006048 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006049
6050 if (hal_strtoul(Value, 10, &ret) < 0) {
6051 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006052 }
developerc14d83a2023-06-29 20:09:42 +08006053
developer37646972023-06-29 10:58:43 +08006054 pStats->radio_PacketsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006055
developer86035662023-06-28 19:21:12 +08006056 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
6057 if (os_snprintf_error(sizeof(buf), res)) {
6058 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6059 return RETURN_ERR;
6060 }
developera3511852023-06-14 14:12:59 +08006061 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006062 if (hal_strtoul(Value, 10, &ret) < 0) {
6063 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006064 }
6065 pStats->radio_BytesReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006066
developer86035662023-06-28 19:21:12 +08006067 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6068 if (os_snprintf_error(sizeof(buf), res)) {
6069 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6070 return RETURN_ERR;
6071 }
developera3511852023-06-14 14:12:59 +08006072 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006073 if (hal_strtoul(Value, 10, &ret) < 0) {
6074 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006075 }
6076 pStats->radio_BytesSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006077
developer86035662023-06-28 19:21:12 +08006078 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6079 if (os_snprintf_error(sizeof(buf), res)) {
6080 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6081 return RETURN_ERR;
6082 }
developera3511852023-06-14 14:12:59 +08006083 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006084 if (hal_strtoul(Value, 10, &ret) < 0) {
6085 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006086 }
6087 pStats->radio_ErrorsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006088
developer86035662023-06-28 19:21:12 +08006089 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6090 if (os_snprintf_error(sizeof(buf), res)) {
6091 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6092 return RETURN_ERR;
6093 }
developera3511852023-06-14 14:12:59 +08006094 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006095 if (hal_strtoul(Value, 10, &ret) < 0) {
6096 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006097 }
6098 pStats->radio_ErrorsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006099
developer86035662023-06-28 19:21:12 +08006100 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
6101 if (os_snprintf_error(sizeof(buf), res)) {
6102 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6103 return RETURN_ERR;
6104 }
developera3511852023-06-14 14:12:59 +08006105 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006106 if (hal_strtoul(Value, 10, &ret) < 0) {
6107 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006108 }
6109 pStats->radio_DiscardPacketsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006110
developer86035662023-06-28 19:21:12 +08006111 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
6112 if (os_snprintf_error(sizeof(buf), res)) {
6113 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6114 return RETURN_ERR;
6115 }
developera3511852023-06-14 14:12:59 +08006116 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08006117 if (hal_strtoul(Value, 10, &ret) < 0) {
6118 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08006119 }
6120 pStats->radio_DiscardPacketsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006121
developera3511852023-06-14 14:12:59 +08006122 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6123 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006124}
6125
6126INT GetIfacestatus(CHAR *interface_name, CHAR *status)
6127{
developer7e4a2a62023-04-06 19:56:03 +08006128 CHAR buf[MAX_CMD_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006129 int res;
developer72fb0bb2023-01-11 09:46:29 +08006130
developer7e4a2a62023-04-06 19:56:03 +08006131 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6132
6133 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
developer75bd10c2023-06-27 11:34:08 +08006134 res = snprintf(buf, sizeof(buf), "%s%s%s%s%s", "ifconfig -a ",
6135 interface_name, " | grep ", interface_name, " | wc -l");
6136
6137 if (os_snprintf_error(sizeof(buf), res)) {
6138 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6139 return RETURN_ERR;
6140 }
developer7e4a2a62023-04-06 19:56:03 +08006141 File_Reading(buf, status);
6142 }
6143
6144 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6145 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006146}
6147
6148//Get detail radio traffic static info
6149INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
6150{
developera3511852023-06-14 14:12:59 +08006151 CHAR interface_name[64] = {0};
6152 BOOL iface_status = FALSE;
6153 wifi_radioTrafficStats2_t radioTrafficStats = {0};
developer72fb0bb2023-01-11 09:46:29 +08006154
developera3511852023-06-14 14:12:59 +08006155 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6156 if (NULL == output_struct)
6157 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006158
developera3511852023-06-14 14:12:59 +08006159 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6160 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006161
developera3511852023-06-14 14:12:59 +08006162 wifi_getApEnable(radioIndex, &iface_status);
developer72fb0bb2023-01-11 09:46:29 +08006163
developera3511852023-06-14 14:12:59 +08006164 if (iface_status == TRUE)
6165 wifi_halGetIfStats(interface_name, &radioTrafficStats);
6166 else
6167 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
developer72fb0bb2023-01-11 09:46:29 +08006168
developera3511852023-06-14 14:12:59 +08006169 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
6170 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
6171 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
6172 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
6173 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
6174 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
6175 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
6176 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +08006177
developera3511852023-06-14 14:12:59 +08006178 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
6179 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].
6180 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
6181 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.
6182 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
6183 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
6184 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
6185 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
6186 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
developer72fb0bb2023-01-11 09:46:29 +08006187
developera3511852023-06-14 14:12:59 +08006188 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
6189 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
6190 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
6191 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.
developer72fb0bb2023-01-11 09:46:29 +08006192
developera3511852023-06-14 14:12:59 +08006193 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006194
developera3511852023-06-14 14:12:59 +08006195 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006196}
6197
6198//Set radio traffic static Measureing rules
6199INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
6200{
developera39cfb22023-06-20 16:28:17 +08006201 char inf_name[IF_NAME_SIZE] = {0};
6202 unsigned int if_idx = 0;
6203 int ret = -1;
6204 struct unl unl_ins;
6205 struct nl_msg *msg = NULL;
6206 struct nlattr * msg_data = NULL;
6207 struct mtk_nl80211_param param;
6208
6209 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
6210 return RETURN_ERR;
6211 if_idx = if_nametoindex(inf_name);
6212 if (!if_idx) {
6213 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6214 return RETURN_ERR;
6215 }
6216 /*init mtk nl80211 vendor cmd*/
6217 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
6218 param.if_type = NL80211_ATTR_IFINDEX;
6219 param.if_idx = if_idx;
6220
6221 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6222 if (ret) {
6223 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6224 return RETURN_ERR;
6225 }
6226 /*add mtk vendor cmd data*/
6227 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD,
6228 sizeof(wifi_radioTrafficStatsMeasure_t), input_struct)) {
6229 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
6230 MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD);
6231 nlmsg_free(msg);
6232 goto err;
6233 }
6234
6235 /*send mtk nl80211 vendor msg*/
6236 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6237 if (ret) {
6238 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6239 goto err;
6240 }
6241 /*deinit mtk nl80211 vendor msg*/
6242 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08006243 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08006244err:
6245 mtk_nl80211_deint(&unl_ins);
6246 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6247 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006248}
6249
6250//To start or stop RadioTrafficStats
6251INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
6252{
developera39cfb22023-06-20 16:28:17 +08006253 char inf_name[IF_NAME_SIZE] = {0};
6254 unsigned int if_idx = 0;
6255 int ret = -1;
6256 struct unl unl_ins;
6257 struct nl_msg *msg = NULL;
6258 struct nlattr * msg_data = NULL;
6259 struct mtk_nl80211_param param;
6260
6261 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
6262 return RETURN_ERR;
6263 if_idx = if_nametoindex(inf_name);
6264 if (!if_idx) {
6265 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6266 return RETURN_ERR;
6267 }
6268 /*init mtk nl80211 vendor cmd*/
6269 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
6270 param.if_type = NL80211_ATTR_IFINDEX;
6271 param.if_idx = if_idx;
6272
6273 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6274 if (ret) {
6275 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6276 return RETURN_ERR;
6277 }
6278 /*add mtk vendor cmd data*/
6279 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL, enable)) {
6280 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
6281 MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL);
6282 nlmsg_free(msg);
6283 goto err;
6284 }
6285
6286 /*send mtk nl80211 vendor msg*/
6287 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6288 if (ret) {
6289 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6290 goto err;
6291 }
6292 /*deinit mtk nl80211 vendor msg*/
6293 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08006294 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08006295err:
6296 mtk_nl80211_deint(&unl_ins);
6297 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6298 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006299}
6300
6301//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
6302INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
6303{
developera3511852023-06-14 14:12:59 +08006304 if (NULL == SignalLevel)
6305 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08006306
developer9ce44382023-06-28 11:09:37 +08006307 *SignalLevel = -19;
developer72fb0bb2023-01-11 09:46:29 +08006308
developera3511852023-06-14 14:12:59 +08006309 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006310}
6311
6312//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
6313INT wifi_applyRadioSettings(INT radioIndex)
6314{
developera3511852023-06-14 14:12:59 +08006315 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006316}
6317
6318//Get the radio index assocated with this SSID entry
6319INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
6320{
developera3511852023-06-14 14:12:59 +08006321 if(NULL == radioIndex)
6322 return RETURN_ERR;
6323 int max_radio_num = 0;
6324 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08006325 if(max_radio_num == 0){
6326 return RETURN_ERR;
6327 }
developera3511852023-06-14 14:12:59 +08006328 *radioIndex = ssidIndex%max_radio_num;
6329 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006330}
6331
6332//Device.WiFi.SSID.{i}.Enable
6333//Get SSID enable configuration parameters (not the SSID enable status)
6334INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
6335{
developera3511852023-06-14 14:12:59 +08006336 if (NULL == output_bool)
6337 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006338
developera3511852023-06-14 14:12:59 +08006339 return wifi_getApEnable(ssidIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006340}
6341
6342//Device.WiFi.SSID.{i}.Enable
6343//Set SSID enable configuration parameters
6344INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
6345{
developera3511852023-06-14 14:12:59 +08006346 return wifi_setApEnable(ssidIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08006347}
6348
6349//Device.WiFi.SSID.{i}.Status
6350//Get the SSID enable status
6351INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
6352{
developer9ce44382023-06-28 11:09:37 +08006353 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +08006354 int res;
developer72fb0bb2023-01-11 09:46:29 +08006355
developera3511852023-06-14 14:12:59 +08006356 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6357 if (NULL == output_string)
6358 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08006359
developera3511852023-06-14 14:12:59 +08006360 wifi_getApEnable(ssidIndex,&output_bool);
developere40952c2023-06-15 18:46:43 +08006361 res = snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
6362 if (os_snprintf_error(32, res)) {
6363 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6364 return RETURN_ERR;
6365 }
developer72fb0bb2023-01-11 09:46:29 +08006366
developera3511852023-06-14 14:12:59 +08006367 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6368 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006369}
6370
6371// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
6372INT wifi_getSSIDName(INT apIndex, CHAR *output)
6373{
developera3511852023-06-14 14:12:59 +08006374 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006375 int res;
developer72fb0bb2023-01-11 09:46:29 +08006376
developera3511852023-06-14 14:12:59 +08006377 if (NULL == output)
6378 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006379
developer75bd10c2023-06-27 11:34:08 +08006380 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6381 if (os_snprintf_error(sizeof(config_file), res)) {
6382 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6383 return RETURN_ERR;
6384 }
developera3511852023-06-14 14:12:59 +08006385 wifi_hostapdRead(config_file,"ssid",output,32);
developer72fb0bb2023-01-11 09:46:29 +08006386
developera3511852023-06-14 14:12:59 +08006387 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
6388 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006389}
6390
developer69b61b02023-03-07 17:17:44 +08006391// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08006392INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
6393{
developera3511852023-06-14 14:12:59 +08006394 struct params params;
6395 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006396 int res;
developer72fb0bb2023-01-11 09:46:29 +08006397
developera3511852023-06-14 14:12:59 +08006398 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6399 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
6400 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006401
developera3511852023-06-14 14:12:59 +08006402 params.name = "ssid";
6403 params.value = ssid_string;
developer75bd10c2023-06-27 11:34:08 +08006404
6405 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6406 if (os_snprintf_error(sizeof(config_file), res)) {
6407 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6408 return RETURN_ERR;
6409 }
6410
developera3511852023-06-14 14:12:59 +08006411 wifi_hostapdWrite(config_file, &params, 1);
6412 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6413 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006414
developera3511852023-06-14 14:12:59 +08006415 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006416}
6417
6418//Get the BSSID
6419INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
6420{
developer7e4a2a62023-04-06 19:56:03 +08006421 char cmd[MAX_CMD_SIZE] = {0};
6422 char inf_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08006423 int res;
developer72fb0bb2023-01-11 09:46:29 +08006424
developera3511852023-06-14 14:12:59 +08006425 if (!output_string)
developerdaf24792023-06-06 11:40:04 +08006426 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006427
developer47cc27a2023-05-17 23:09:58 +08006428 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
6429 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08006430
developer5b2f10c2023-05-25 17:02:21 +08006431 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
6432 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
6433 strncpy(output_string, "\0", 1);
6434 return RETURN_ERR;
6435 }
developere40952c2023-06-15 18:46:43 +08006436 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
6437 if (os_snprintf_error(sizeof(cmd), res)) {
6438 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6439 return RETURN_ERR;
6440 }
6441
developer5b2f10c2023-05-25 17:02:21 +08006442 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08006443
developer5b2f10c2023-05-25 17:02:21 +08006444 /* if hostapd does not control interface even if this interface has been brought up,
6445 * try to get its mac address by iw command.
6446 */
6447 if(strlen(output_string) == 0) {
6448 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08006449 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
6450 if (os_snprintf_error(sizeof(cmd), res)) {
6451 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6452 return RETURN_ERR;
6453 }
6454
developer5b2f10c2023-05-25 17:02:21 +08006455 _syscmd(cmd, output_string, 64);
6456 }
developer72fb0bb2023-01-11 09:46:29 +08006457
developer5b2f10c2023-05-25 17:02:21 +08006458 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006459}
6460
6461//Get the MAC address associated with this Wifi SSID
6462INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
6463{
developera3511852023-06-14 14:12:59 +08006464 wifi_getBaseBSSID(ssidIndex,output_string);
6465 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006466}
6467
6468//Get the basic SSID traffic static info
6469//Apply SSID and AP (in the case of Acess Point devices) to the hardware
6470//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
6471INT wifi_applySSIDSettings(INT ssidIndex)
6472{
developera3511852023-06-14 14:12:59 +08006473 char interface_name[16] = {0};
6474 BOOL status = false;
6475 char cmd[MAX_CMD_SIZE] = {0};
6476 char buf[MAX_CMD_SIZE] = {0};
6477 int apIndex, ret;
6478 int max_radio_num = 0;
6479 int radioIndex = 0;
developere40952c2023-06-15 18:46:43 +08006480 int res;
developer72fb0bb2023-01-11 09:46:29 +08006481
developera3511852023-06-14 14:12:59 +08006482 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08006483 if(max_radio_num == 0){
6484 return RETURN_ERR;
6485 }
developera3511852023-06-14 14:12:59 +08006486 radioIndex = ssidIndex % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +08006487
developera3511852023-06-14 14:12:59 +08006488 wifi_getApEnable(ssidIndex,&status);
6489 // Do not apply when ssid index is disabled
6490 if (status == false)
6491 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006492
developera3511852023-06-14 14:12:59 +08006493 /* Doing full remove and add for ssid Index
6494 * Not all hostapd options are supported with reload
6495 * for example macaddr_acl
6496 */
6497 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
6498 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006499
developera3511852023-06-14 14:12:59 +08006500 ret = wifi_setApEnable(ssidIndex,true);
developer72fb0bb2023-01-11 09:46:29 +08006501
developera3511852023-06-14 14:12:59 +08006502 /* Workaround for hostapd issue with multiple bss definitions
6503 * when first created interface will be removed
6504 * then all vaps other vaps on same phy are removed
6505 * after calling setApEnable to false readd all enabled vaps */
6506 for(int i=0; i < MAX_APS/max_radio_num; i++) {
6507 apIndex = max_radio_num*i+radioIndex;
6508 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6509 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006510 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
6511 if (os_snprintf_error(sizeof(cmd), res)) {
6512 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6513 return RETURN_ERR;
6514 }
6515
developera3511852023-06-14 14:12:59 +08006516 _syscmd(cmd, buf, sizeof(buf));
6517 if(*buf == '1')
6518 wifi_setApEnable(apIndex, true);
6519 }
developer72fb0bb2023-01-11 09:46:29 +08006520
developera3511852023-06-14 14:12:59 +08006521 return ret;
developer72fb0bb2023-01-11 09:46:29 +08006522}
6523
6524struct channels_noise {
developera3511852023-06-14 14:12:59 +08006525 int channel;
6526 int noise;
developer72fb0bb2023-01-11 09:46:29 +08006527};
6528
6529// Return noise array for each channel
6530int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
6531{
developera3511852023-06-14 14:12:59 +08006532 char interface_name[16] = {0};
6533 FILE *f = NULL;
6534 char cmd[128] = {0};
6535 char line[256] = {0};
developer75bd10c2023-06-27 11:34:08 +08006536 int tmp = 0, arr_index = -1, res;
developer72fb0bb2023-01-11 09:46:29 +08006537
developera3511852023-06-14 14:12:59 +08006538 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6539 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08006540
6541 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
6542 if (os_snprintf_error(sizeof(cmd), res)) {
6543 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6544 return RETURN_ERR;
6545 }
developer72fb0bb2023-01-11 09:46:29 +08006546
developera3511852023-06-14 14:12:59 +08006547 if ((f = popen(cmd, "r")) == NULL) {
6548 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6549 return RETURN_ERR;
6550 }
developer69b61b02023-03-07 17:17:44 +08006551
developera3511852023-06-14 14:12:59 +08006552 while(fgets(line, sizeof(line), f) != NULL) {
6553 if(arr_index < channels_num){
developer37646972023-06-29 10:58:43 +08006554 if (sscanf(line, "%d", &tmp) == EOF)
6555 continue;
developera3511852023-06-14 14:12:59 +08006556 if (tmp > 0) { // channel frequency, the first line must be frequency
6557 arr_index++;
6558 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
6559 } else { // noise
6560 channels_noise_arr[arr_index].noise = tmp;
6561 }
6562 }else{
6563 break;
6564 }
6565 }
6566 pclose(f);
6567 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006568}
6569
6570//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
6571//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08006572INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08006573{
developera3511852023-06-14 14:12:59 +08006574 int index = -1;
6575 wifi_neighbor_ap2_t *scan_array = NULL;
6576 char cmd[256]={0};
6577 char buf[128]={0};
6578 char file_name[32] = {0};
6579 char filter_SSID[32] = {0};
6580 char line[256] = {0};
6581 char interface_name[16] = {0};
6582 char *ret = NULL;
6583 int freq=0;
6584 FILE *f = NULL;
developerc14d83a2023-06-29 20:09:42 +08006585 unsigned long channels_num = 0;
developera3511852023-06-14 14:12:59 +08006586 int vht_channel_width = 0;
6587 int get_noise_ret = RETURN_ERR;
6588 bool filter_enable = false;
6589 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
developere40952c2023-06-15 18:46:43 +08006590 int phyId = 0, res;
developerc14d83a2023-06-29 20:09:42 +08006591 unsigned long len, tmp;
developer72fb0bb2023-01-11 09:46:29 +08006592
developera3511852023-06-14 14:12:59 +08006593 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006594
developera3511852023-06-14 14:12:59 +08006595 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6596 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006597
6598 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
6599 if (os_snprintf_error(sizeof(file_name), res)) {
6600 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6601 return RETURN_ERR;
6602 }
developer72fb0bb2023-01-11 09:46:29 +08006603
developera3511852023-06-14 14:12:59 +08006604 f = fopen(file_name, "r");
6605 if (f != NULL) {
developerd14dff12023-06-28 22:47:44 +08006606 if (fgets(buf, sizeof(file_name), f) == NULL)
6607 wifi_debug(DEBUG_ERROR, "fgets failed\n");
developera3511852023-06-14 14:12:59 +08006608 if ((strncmp(buf, "0", 1)) != 0) {
developerd14dff12023-06-28 22:47:44 +08006609 if (fgets(filter_SSID, sizeof(file_name), f) == NULL)
6610 wifi_debug(DEBUG_ERROR, "fgets failed\n");
developera3511852023-06-14 14:12:59 +08006611 if (strlen(filter_SSID) != 0)
6612 filter_enable = true;
6613 }
developerd14dff12023-06-28 22:47:44 +08006614 if (fclose(f) != 0) {
6615 wifi_debug(DEBUG_ERROR, "fclose fail\n");
6616 return RETURN_ERR;
6617 }
developera3511852023-06-14 14:12:59 +08006618 }
developer72fb0bb2023-01-11 09:46:29 +08006619
developera3511852023-06-14 14:12:59 +08006620 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08006621 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
6622 if (os_snprintf_error(sizeof(cmd), res)) {
6623 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6624 return RETURN_ERR;
6625 }
6626
developera3511852023-06-14 14:12:59 +08006627 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +08006628 if (hal_strtoul(buf, 10, &tmp) < 0) {
6629 wifi_debug(DEBUG_ERROR, "strtol fail\n");
6630 }
developer72fb0bb2023-01-11 09:46:29 +08006631
developerc14d83a2023-06-29 20:09:42 +08006632 channels_num = tmp;
developer32f2a182023-06-27 19:50:41 +08006633 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
developera3511852023-06-14 14:12:59 +08006634 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
developer32f2a182023-06-27 19:50:41 +08006635 if (os_snprintf_error(sizeof(cmd), res)) {
6636 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6637 return RETURN_ERR;
6638 }
developer86035662023-06-28 19:21:12 +08006639 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developera3511852023-06-14 14:12:59 +08006640 if ((f = popen(cmd, "r")) == NULL) {
6641 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6642 return RETURN_ERR;
6643 }
developer9ce44382023-06-28 11:09:37 +08006644 struct channels_noise *channels_noise_arr = NULL;
6645 if(channels_num > 0 && channels_num <= 243){
6646 channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
6647 } else{
developerc14d83a2023-06-29 20:09:42 +08006648 pclose(f);
developer9ce44382023-06-28 11:09:37 +08006649 return RETURN_ERR;
6650 }
6651
6652 if(channels_noise_arr != NULL){
6653 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
6654 } else{
developerc14d83a2023-06-29 20:09:42 +08006655 pclose(f);
developer9ce44382023-06-28 11:09:37 +08006656 return RETURN_ERR;
6657 }
6658
developer69b61b02023-03-07 17:17:44 +08006659
developera3511852023-06-14 14:12:59 +08006660 ret = fgets(line, sizeof(line), f);
6661 while (ret != NULL) {
6662 if(strstr(line, "BSS") != NULL) { // new neighbor info
6663 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
6664 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
6665 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
developer72fb0bb2023-01-11 09:46:29 +08006666
developera3511852023-06-14 14:12:59 +08006667 if (!filter_BSS) {
6668 index++;
6669 wifi_neighbor_ap2_t *tmp;
6670 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
6671 if (tmp == NULL) { // no more memory to use
6672 index--;
6673 wifi_dbg_printf("%s: realloc failed\n", __func__);
6674 break;
6675 }
6676 scan_array = tmp;
6677 }
6678 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +08006679
developera3511852023-06-14 14:12:59 +08006680 filter_BSS = false;
developer86035662023-06-28 19:21:12 +08006681 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
6682 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6683 goto err;
6684 }
developerc79e9172023-06-06 19:48:03 +08006685 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +08006686 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +08006687 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +08006688 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +08006689 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +08006690 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
6691 } else if (strstr(line, "freq") != NULL) {
developer86035662023-06-28 19:21:12 +08006692 if (sscanf(line," freq: %d", &freq) != 1) {
6693 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6694 goto err;
6695 }
developera3511852023-06-14 14:12:59 +08006696 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +08006697
developera3511852023-06-14 14:12:59 +08006698 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +08006699 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08006700 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +08006701 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08006702 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +08006703 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08006704 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
6705 }
6706 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +08006707 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08006708 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +08006709 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08006710 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +08006711 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08006712 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
6713 }
developer72fb0bb2023-01-11 09:46:29 +08006714
developera3511852023-06-14 14:12:59 +08006715 scan_array[index].ap_Noise = 0;
6716 if (get_noise_ret == RETURN_OK) {
6717 for (int i = 0; i < channels_num; i++) {
6718 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
6719 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
6720 break;
6721 }
6722 }
6723 }
6724 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +08006725 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
6726 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6727 goto err;
6728 }
developera3511852023-06-14 14:12:59 +08006729 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +08006730 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
6731 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6732 goto err;
6733 }
developera3511852023-06-14 14:12:59 +08006734 } else if (strstr(line,"SSID") != NULL) {
developer86035662023-06-28 19:21:12 +08006735 if (sscanf(line," SSID: %32s", scan_array[index].ap_SSID) != 1) {
6736 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6737 goto err;
6738 }
developera3511852023-06-14 14:12:59 +08006739 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
6740 filter_BSS = true;
6741 }
6742 } else if (strstr(line, "Supported rates") != NULL) {
6743 char SRate[80] = {0}, *tmp = NULL;
6744 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08006745 if (strlen(line) >= sizeof(SRate))
developer86035662023-06-28 19:21:12 +08006746 goto err;
developer32f2a182023-06-27 19:50:41 +08006747 strncpy(SRate, line, strlen(line));
developera3511852023-06-14 14:12:59 +08006748 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +08006749 if (tmp == NULL)
6750 goto err;
developera3511852023-06-14 14:12:59 +08006751 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +08006752 if (tmp == NULL)
6753 goto err;
developer32f2a182023-06-27 19:50:41 +08006754 if (strlen(tmp) >= sizeof(buf))
developer86035662023-06-28 19:21:12 +08006755 goto err;
developer32f2a182023-06-27 19:50:41 +08006756 strncpy(buf, tmp, strlen(tmp));
developera3511852023-06-14 14:12:59 +08006757 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +08006758
developera3511852023-06-14 14:12:59 +08006759 tmp = strtok(buf, " \n");
6760 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +08006761 if (strlen(tmp) >= (sizeof(SRate) - strlen(SRate)))
developer86035662023-06-28 19:21:12 +08006762 goto err;
developer32f2a182023-06-27 19:50:41 +08006763 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +08006764 if (SRate[strlen(SRate) - 1] == '*') {
6765 SRate[strlen(SRate) - 1] = '\0';
6766 }
developer32f2a182023-06-27 19:50:41 +08006767 if (strlen(SRate) >= (sizeof(SRate) - 1))
developer86035662023-06-28 19:21:12 +08006768 goto err;
developer32f2a182023-06-27 19:50:41 +08006769 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +08006770
developera3511852023-06-14 14:12:59 +08006771 tmp = strtok(NULL, " \n");
6772 }
6773 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +08006774 if (sizeof(scan_array[index].ap_SupportedDataTransferRates) <= strlen(SRate))
developer86035662023-06-28 19:21:12 +08006775 goto err;
developer32f2a182023-06-27 19:50:41 +08006776 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, strlen(SRate));
developera3511852023-06-14 14:12:59 +08006777 } else if (strstr(line, "DTIM") != NULL) {
developer86035662023-06-28 19:21:12 +08006778 if (sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod)) != 1) {
6779 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6780 goto err;
6781 }
developera3511852023-06-14 14:12:59 +08006782 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006783 if (sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) <= 4)
developer86035662023-06-28 19:21:12 +08006784 goto err;
developer32f2a182023-06-27 19:50:41 +08006785 strncat(scan_array[index].ap_SupportedStandards, ",ac",
6786 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6787 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
6788 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +08006789 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006790 strncat(scan_array[index].ap_SupportedStandards, ",n", sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6791 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
6792 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +08006793 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08006794 if (fgets(line, sizeof(line), f) == NULL) {
6795 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6796 goto err;
6797 }
6798 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
6799 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6800 goto err;
6801 }
developera3511852023-06-14 14:12:59 +08006802 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +08006803 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +08006804 } else {
developere40952c2023-06-15 18:46:43 +08006805 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +08006806 }
developere40952c2023-06-15 18:46:43 +08006807 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
6808 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +08006809 goto err;
developere40952c2023-06-15 18:46:43 +08006810 }
6811
developera3511852023-06-14 14:12:59 +08006812 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
6813 continue;
6814 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08006815 if (fgets(line, sizeof(line), f) == NULL) {
6816 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6817 goto err;
6818 }
developerc14d83a2023-06-29 20:09:42 +08006819 if (sscanf(line," * secondary channel offset: %127s", buf) != 1) {
developer86035662023-06-28 19:21:12 +08006820 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6821 goto err;
6822 }
developera3511852023-06-14 14:12:59 +08006823 if (!strcmp(buf, "above")) {
6824 //40Mhz +
developere40952c2023-06-15 18:46:43 +08006825 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
developera3511852023-06-14 14:12:59 +08006826 }
6827 else if (!strcmp(buf, "below")) {
6828 //40Mhz -
developere40952c2023-06-15 18:46:43 +08006829 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
developera3511852023-06-14 14:12:59 +08006830 } else {
6831 //20Mhz
developere40952c2023-06-15 18:46:43 +08006832 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
6833 }
6834 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
6835 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +08006836 goto err;
developera3511852023-06-14 14:12:59 +08006837 }
developere40952c2023-06-15 18:46:43 +08006838
developera3511852023-06-14 14:12:59 +08006839 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
6840 continue;
6841 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006842 strncat(scan_array[index].ap_SupportedStandards, ",ax",
6843 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6844 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
6845 scan_array[index].ap_OperatingStandards[2] = '\0';
developer86035662023-06-28 19:21:12 +08006846 if (fgets(line, sizeof(line), f) == NULL) {
6847 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6848 goto err;
6849 }
developera3511852023-06-14 14:12:59 +08006850 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +08006851 if (strstr(line, "HE40/2.4GHz") != NULL) {
6852 len = strlen("11AXHE40PLUS");
6853 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
6854 } else {
6855 len = strlen("11AXHE20");
6856 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
6857 }
6858 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +08006859 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
6860 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006861 len = strlen("11AXHE80");
6862 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
6863 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developer86035662023-06-28 19:21:12 +08006864 if (fgets(line, sizeof(line), f) == NULL) {
6865 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6866 goto err;
6867 }
developera3511852023-06-14 14:12:59 +08006868 } else
6869 continue;
developer32f2a182023-06-27 19:50:41 +08006870 if (strstr(line, "HE160/5GHz") != NULL) {
6871 len = strlen("11AXHE160");
6872 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
6873 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
6874 }
developera3511852023-06-14 14:12:59 +08006875 }
6876 continue;
6877 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006878 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
6879 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08006880 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006881 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
6882 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08006883 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +08006884 if (sscanf(line, " * Group cipher: %64s", scan_array[index].ap_EncryptionMode) != 1) {
6885 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6886 goto err;
6887 }
developera3511852023-06-14 14:12:59 +08006888 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +08006889 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
6890 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +08006891 }
6892 }
developer86035662023-06-28 19:21:12 +08006893 if (fgets(line, sizeof(line), f) == NULL) {
6894 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6895 goto err;
6896 }
developera3511852023-06-14 14:12:59 +08006897 }
developer72fb0bb2023-01-11 09:46:29 +08006898
developera3511852023-06-14 14:12:59 +08006899 if (!filter_BSS) {
6900 *output_array_size = index + 1;
6901 } else {
6902 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
6903 *output_array_size = index;
6904 }
6905 *neighbor_ap_array = scan_array;
6906 pclose(f);
6907 free(channels_noise_arr);
6908 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6909 return RETURN_OK;
developer86035662023-06-28 19:21:12 +08006910err:
6911 pclose(f);
6912 free(channels_noise_arr);
developerc14d83a2023-06-29 20:09:42 +08006913 if (scan_array)
6914 free(scan_array);
developer86035662023-06-28 19:21:12 +08006915 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6916 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006917}
6918
6919//>> Deprecated: used for old RDKB code.
6920INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
6921{
developera3511852023-06-14 14:12:59 +08006922 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006923
developera3511852023-06-14 14:12:59 +08006924 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6925 output_struct->wifi_PLCPErrorCount = 0;
6926 output_struct->wifi_FCSErrorCount = 0;
6927 output_struct->wifi_InvalidMACCount = 0;
6928 output_struct->wifi_PacketsOtherReceived = 0;
6929 output_struct->wifi_Noise = 0;
6930 status = RETURN_OK;
6931 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6932 return status;
developer72fb0bb2023-01-11 09:46:29 +08006933}
6934
6935INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
6936{
developera3511852023-06-14 14:12:59 +08006937 char interface_name[16] = {0};
6938 char cmd[128] = {0};
6939 char buf[1280] = {0};
6940 char *pos = NULL;
developere40952c2023-06-15 18:46:43 +08006941 int res;
developer72fb0bb2023-01-11 09:46:29 +08006942
developera3511852023-06-14 14:12:59 +08006943 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6944 if (NULL == output_struct)
6945 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006946
developera3511852023-06-14 14:12:59 +08006947 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6948 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006949
developera3511852023-06-14 14:12:59 +08006950 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08006951
developere40952c2023-06-15 18:46:43 +08006952 res = snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
6953 if (os_snprintf_error(sizeof(cmd), res)) {
6954 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6955 return RETURN_ERR;
6956 }
6957
developera3511852023-06-14 14:12:59 +08006958 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006959
developera3511852023-06-14 14:12:59 +08006960 pos = buf;
6961 if ((pos = strstr(pos, "RX packets:")) == NULL)
6962 return RETURN_ERR;
6963 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08006964
developera3511852023-06-14 14:12:59 +08006965 if ((pos = strstr(pos, "TX packets:")) == NULL)
6966 return RETURN_ERR;
6967 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08006968
developera3511852023-06-14 14:12:59 +08006969 if ((pos = strstr(pos, "RX bytes:")) == NULL)
6970 return RETURN_ERR;
6971 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08006972
developera3511852023-06-14 14:12:59 +08006973 if ((pos = strstr(pos, "TX bytes:")) == NULL)
6974 return RETURN_ERR;
6975 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08006976
developer37646972023-06-29 10:58:43 +08006977 res = snprintf(cmd, sizeof(cmd),
6978 "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
6979 if (os_snprintf_error(sizeof(cmd), res)) {
6980 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6981 return RETURN_ERR;
6982 }
developera3511852023-06-14 14:12:59 +08006983 _syscmd(cmd, buf, sizeof(buf));
developer37646972023-06-29 10:58:43 +08006984 if (sscanf(buf, "%lu", &output_struct->wifi_Associations) == EOF)
6985 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developer72fb0bb2023-01-11 09:46:29 +08006986
developera3511852023-06-14 14:12:59 +08006987 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6988 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006989}
6990
6991INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
6992{
developera3511852023-06-14 14:12:59 +08006993 char interface_name[IF_NAME_SIZE] = {0};
6994 char interface_status[MAX_BUF_SIZE] = {0};
6995 char Value[MAX_BUF_SIZE] = {0};
6996 char buf[MAX_CMD_SIZE] = {0};
6997 char cmd[MAX_CMD_SIZE] = {0};
6998 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08006999 int res;
developerc14d83a2023-06-29 20:09:42 +08007000 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +08007001
developera3511852023-06-14 14:12:59 +08007002 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7003 if (NULL == output_struct)
7004 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007005
developera3511852023-06-14 14:12:59 +08007006 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08007007
developera3511852023-06-14 14:12:59 +08007008 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
7009 return RETURN_ERR;
7010 GetIfacestatus(interface_name, interface_status);
developer72fb0bb2023-01-11 09:46:29 +08007011
developera3511852023-06-14 14:12:59 +08007012 if(0 != strcmp(interface_status, "1"))
7013 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08007014
7015 res = snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
7016 if (os_snprintf_error(sizeof(cmd), res)) {
7017 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7018 return RETURN_ERR;
7019 }
developer72fb0bb2023-01-11 09:46:29 +08007020
developera3511852023-06-14 14:12:59 +08007021 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +08007022
developera3511852023-06-14 14:12:59 +08007023 fp = fopen("/tmp/SSID_Stats.txt", "r");
7024 if(fp == NULL)
7025 {
7026 printf("/tmp/SSID_Stats.txt not exists \n");
7027 return RETURN_ERR;
7028 }
developer37646972023-06-29 10:58:43 +08007029 if (fclose(fp) == EOF) {
7030 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
7031 return RETURN_ERR;
7032 }
developer72fb0bb2023-01-11 09:46:29 +08007033
developer37646972023-06-29 10:58:43 +08007034 res = snprintf(buf, sizeof(buf),
7035 "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
7036 if (os_snprintf_error(sizeof(buf), res)) {
7037 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7038 return RETURN_ERR;
7039 }
developera3511852023-06-14 14:12:59 +08007040 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08007041
7042 if (hal_strtoul(Value, 10, &tmp) < 0) {
7043 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007044 }
developerc14d83a2023-06-29 20:09:42 +08007045 output_struct->wifi_ErrorsReceived = tmp;
developer72fb0bb2023-01-11 09:46:29 +08007046
developer37646972023-06-29 10:58:43 +08007047 res = snprintf(buf, sizeof(buf),
7048 "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
7049 if (os_snprintf_error(sizeof(buf), res)) {
7050 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7051 return RETURN_ERR;
7052 }
developera3511852023-06-14 14:12:59 +08007053 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08007054
7055 if (hal_strtoul(Value, 10, &tmp) < 0) {
7056 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007057 }
developerc14d83a2023-06-29 20:09:42 +08007058 output_struct->wifi_ErrorsSent = tmp;
developer72fb0bb2023-01-11 09:46:29 +08007059
developer37646972023-06-29 10:58:43 +08007060 res = snprintf(buf, sizeof(buf),
7061 "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
7062 if (os_snprintf_error(sizeof(buf), res)) {
7063 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7064 return RETURN_ERR;
7065 }
developera3511852023-06-14 14:12:59 +08007066 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08007067
7068 if (hal_strtoul(Value, 10, &tmp) < 0) {
7069 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007070 }
developerc14d83a2023-06-29 20:09:42 +08007071 output_struct->wifi_DiscardedPacketsReceived = tmp;
developer72fb0bb2023-01-11 09:46:29 +08007072
developer37646972023-06-29 10:58:43 +08007073 res = snprintf(buf, sizeof(buf),
7074 "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
7075 if (os_snprintf_error(sizeof(buf), res)) {
7076 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7077 return RETURN_ERR;
7078 }
developera3511852023-06-14 14:12:59 +08007079 File_Reading(buf, Value);
developerc14d83a2023-06-29 20:09:42 +08007080
7081 if (hal_strtoul(Value, 10, &tmp) < 0) {
7082 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007083 }
developerc14d83a2023-06-29 20:09:42 +08007084 output_struct->wifi_DiscardedPacketsSent = tmp;
developer72fb0bb2023-01-11 09:46:29 +08007085
developera3511852023-06-14 14:12:59 +08007086 output_struct->wifi_UnicastPacketsSent = 0;
7087 output_struct->wifi_UnicastPacketsReceived = 0;
7088 output_struct->wifi_MulticastPacketsSent = 0;
7089 output_struct->wifi_MulticastPacketsReceived = 0;
7090 output_struct->wifi_BroadcastPacketsSent = 0;
7091 output_struct->wifi_BroadcastPacketsRecevied = 0;
7092 output_struct->wifi_UnknownPacketsReceived = 0;
developer72fb0bb2023-01-11 09:46:29 +08007093
developera3511852023-06-14 14:12:59 +08007094 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7095 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007096}
7097
7098INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
7099{
developera3511852023-06-14 14:12:59 +08007100 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007101
developera3511852023-06-14 14:12:59 +08007102 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7103 //Below values should get updated from hal
7104 output_struct->wifi_RetransCount=0;
7105 output_struct->wifi_FailedRetransCount=0;
7106 output_struct->wifi_RetryCount=0;
7107 output_struct->wifi_MultipleRetryCount=0;
7108 output_struct->wifi_ACKFailureCount=0;
7109 output_struct->wifi_AggregatedPacketCount=0;
developer72fb0bb2023-01-11 09:46:29 +08007110
developera3511852023-06-14 14:12:59 +08007111 status = RETURN_OK;
7112 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007113
developera3511852023-06-14 14:12:59 +08007114 return status;
developer72fb0bb2023-01-11 09:46:29 +08007115}
7116
7117INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
7118{
developera3511852023-06-14 14:12:59 +08007119 INT status = RETURN_ERR;
7120 UINT index;
7121 wifi_neighbor_ap_t *pt=NULL;
developer72fb0bb2023-01-11 09:46:29 +08007122
developera3511852023-06-14 14:12:59 +08007123 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7124 *output_array_size=2;
7125 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
7126 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
developer86035662023-06-28 19:21:12 +08007127 if (*neighbor_ap_array == NULL) {
7128 wifi_debug(DEBUG_ERROR, "calloc fail!\n");
7129 return RETURN_ERR;
7130 }
developera3511852023-06-14 14:12:59 +08007131 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
developer32f2a182023-06-27 19:50:41 +08007132 pt->ap_Radio[0] = '\0';
7133 pt->ap_SSID[0] = '\0';
7134 pt->ap_BSSID[0] = '\0';
7135 pt->ap_Mode[0] = '\0';
developera3511852023-06-14 14:12:59 +08007136 pt->ap_Channel=1;
7137 pt->ap_SignalStrength=0;
developer32f2a182023-06-27 19:50:41 +08007138 pt->ap_SecurityModeEnabled[0] = '\0';
7139 pt->ap_EncryptionMode[0] = '\0';
7140 pt->ap_OperatingFrequencyBand[0] = '\0';
7141 pt->ap_SupportedStandards[0] = '\0';
7142 pt->ap_OperatingStandards[0] = '\0';
7143 pt->ap_OperatingChannelBandwidth[0] = '\0';
7144 pt->ap_BasicDataTransferRates[0] = '\0';
7145 pt->ap_SupportedDataTransferRates[0] = '\0';
developera3511852023-06-14 14:12:59 +08007146 pt->ap_BeaconPeriod=1;
7147 pt->ap_Noise=0;
developera3511852023-06-14 14:12:59 +08007148 pt->ap_DTIMPeriod=1;
7149 pt->ap_ChannelUtilization = 1;
7150 }
developer72fb0bb2023-01-11 09:46:29 +08007151
developera3511852023-06-14 14:12:59 +08007152 status = RETURN_OK;
7153 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007154
developera3511852023-06-14 14:12:59 +08007155 return status;
developer72fb0bb2023-01-11 09:46:29 +08007156}
7157
7158//----------------- AP HAL -------------------------------
7159
7160//>> Deprecated: used for old RDKB code.
7161INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
7162{
developera3511852023-06-14 14:12:59 +08007163 if (NULL == output_ulong || NULL == output_struct)
7164 return RETURN_ERR;
7165 *output_ulong = 0;
7166 *output_struct = NULL;
7167 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007168}
7169
7170#ifdef HAL_NETLINK_IMPL
7171static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +08007172 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7173 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developerc14d83a2023-06-29 20:09:42 +08007174 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
7175 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
developera3511852023-06-14 14:12:59 +08007176 char mac_addr[20];
7177 static int count=0;
7178 int rate=0;
developer72fb0bb2023-01-11 09:46:29 +08007179
developera3511852023-06-14 14:12:59 +08007180 wifi_device_info_t *out = (wifi_device_info_t*)arg;
developer72fb0bb2023-01-11 09:46:29 +08007181
developera3511852023-06-14 14:12:59 +08007182 nla_parse(tb,
7183 NL80211_ATTR_MAX,
7184 genlmsg_attrdata(gnlh, 0),
7185 genlmsg_attrlen(gnlh, 0),
7186 NULL);
developer72fb0bb2023-01-11 09:46:29 +08007187
developera3511852023-06-14 14:12:59 +08007188 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +08007189 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +08007190 return NL_SKIP;
7191 }
developer72fb0bb2023-01-11 09:46:29 +08007192
7193
developera3511852023-06-14 14:12:59 +08007194 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +08007195 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +08007196 return NL_SKIP;
7197 }
developer72fb0bb2023-01-11 09:46:29 +08007198
developera3511852023-06-14 14:12:59 +08007199 //devIndex starts from 1
7200 if( ++count == out->wifi_devIndex )
7201 {
7202 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
7203 //Getting the mac addrress
7204 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
developer72fb0bb2023-01-11 09:46:29 +08007205
developera3511852023-06-14 14:12:59 +08007206 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +08007207 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +08007208 return NL_SKIP;
7209 }
developer72fb0bb2023-01-11 09:46:29 +08007210
developera3511852023-06-14 14:12:59 +08007211 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
7212 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
7213 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
7214 out->wifi_devTxRate = rate/10;
7215 }
7216 }
developer72fb0bb2023-01-11 09:46:29 +08007217
developera3511852023-06-14 14:12:59 +08007218 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +08007219 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +08007220 return NL_SKIP;
7221 }
developer72fb0bb2023-01-11 09:46:29 +08007222
developera3511852023-06-14 14:12:59 +08007223 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
7224 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
7225 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
7226 out->wifi_devRxRate = rate/10;
7227 }
7228 }
7229 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
7230 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
developer72fb0bb2023-01-11 09:46:29 +08007231
developera3511852023-06-14 14:12:59 +08007232 out->wifi_devAssociatedDeviceAuthentiationState = 1;
7233 count = 0; //starts the count for next cycle
7234 return NL_STOP;
7235 }
developer72fb0bb2023-01-11 09:46:29 +08007236
developera3511852023-06-14 14:12:59 +08007237 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08007238
7239}
7240#endif
7241
7242INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
7243{
developera3511852023-06-14 14:12:59 +08007244 Netlink nl = {0};
7245 char if_name[IF_NAME_SIZE] = {0};
7246 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08007247 int res;
developer72fb0bb2023-01-11 09:46:29 +08007248
developera3511852023-06-14 14:12:59 +08007249 wifi_device_info_t info = {0};
7250 info.wifi_devIndex = devIndex;
developer72fb0bb2023-01-11 09:46:29 +08007251
developera3511852023-06-14 14:12:59 +08007252 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7253 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007254
developere40952c2023-06-15 18:46:43 +08007255 res = snprintf(if_name,sizeof(if_name),"%s", interface_name);
7256 if (os_snprintf_error(sizeof(if_name), res)) {
7257 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7258 return RETURN_ERR;
7259 }
developer72fb0bb2023-01-11 09:46:29 +08007260
developera3511852023-06-14 14:12:59 +08007261 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +08007262
developera3511852023-06-14 14:12:59 +08007263 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +08007264 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +08007265 return -1;
7266 }
developer72fb0bb2023-01-11 09:46:29 +08007267
developera3511852023-06-14 14:12:59 +08007268 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +08007269
developera3511852023-06-14 14:12:59 +08007270 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +08007271 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +08007272 nlfree(&nl);
7273 return -2;
7274 }
developer72fb0bb2023-01-11 09:46:29 +08007275
developera3511852023-06-14 14:12:59 +08007276 genlmsg_put(msg,
7277 NL_AUTO_PID,
7278 NL_AUTO_SEQ,
7279 nl.id,
7280 0,
7281 NLM_F_DUMP,
7282 NL80211_CMD_GET_STATION,
7283 0);
developer72fb0bb2023-01-11 09:46:29 +08007284
developera3511852023-06-14 14:12:59 +08007285 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
7286 nl_send_auto_complete(nl.socket, msg);
7287 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
7288 nl_recvmsgs(nl.socket, nl.cb);
7289 nlmsg_free(msg);
7290 nlfree(&nl);
developer72fb0bb2023-01-11 09:46:29 +08007291
developera3511852023-06-14 14:12:59 +08007292 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
7293 output_struct->wifi_devRxRate = info.wifi_devRxRate;
7294 output_struct->wifi_devTxRate = info.wifi_devTxRate;
7295 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
7296 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
7297 return RETURN_OK;
7298}
developer72fb0bb2023-01-11 09:46:29 +08007299
developera3511852023-06-14 14:12:59 +08007300INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
7301{
7302 if (NULL == device)
7303 return RETURN_ERR;
7304 return RETURN_OK;
7305}
7306//<<
developer72fb0bb2023-01-11 09:46:29 +08007307
developer72fb0bb2023-01-11 09:46:29 +08007308
7309//--------------wifi_ap_hal-----------------------------
7310//enables CTS protection for the radio used by this AP
7311INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
7312{
developera3511852023-06-14 14:12:59 +08007313 //save config and Apply instantly
7314 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007315}
7316
7317// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
7318INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
7319{
developera3511852023-06-14 14:12:59 +08007320 char config_file[64] = {'\0'};
7321 char config_dat_file[64] = {'\0'};
7322 char buf[64] = {'\0'};
7323 struct params list = {0};
7324 struct params dat = {0};
7325 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007326 int res;
developer72fb0bb2023-01-11 09:46:29 +08007327
developera3511852023-06-14 14:12:59 +08007328 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7329 list.name = "ht_coex";
developere40952c2023-06-15 18:46:43 +08007330 res = snprintf(buf, sizeof(buf), "%d", enable);
7331 if (os_snprintf_error(sizeof(buf), res)) {
7332 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7333 return RETURN_ERR;
7334 }
7335
developera3511852023-06-14 14:12:59 +08007336 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007337
developera3511852023-06-14 14:12:59 +08007338 dat.name = "HT_BSSCoexistence";
7339 dat.value = buf;
developerd1824452023-05-18 12:30:04 +08007340
developera3511852023-06-14 14:12:59 +08007341 band = wifi_index_to_band(apIndex);
developere40952c2023-06-15 18:46:43 +08007342 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7343 if (os_snprintf_error(sizeof(config_file), res)) {
7344 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7345 return RETURN_ERR;
7346 }
7347
7348 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7349 if (os_snprintf_error(sizeof(config_dat_file), res)) {
7350 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7351 return RETURN_ERR;
7352 }
7353
developera3511852023-06-14 14:12:59 +08007354 wifi_hostapdWrite(config_file, &list, 1);
7355 wifi_datfileWrite(config_dat_file, &dat, 1);
7356 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08007357
developera3511852023-06-14 14:12:59 +08007358 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007359
developera3511852023-06-14 14:12:59 +08007360 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007361}
7362
7363//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
7364INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
7365{
developera3511852023-06-14 14:12:59 +08007366 char config_file[MAX_BUF_SIZE] = {'\0'};
7367 char buf[MAX_BUF_SIZE] = {'\0'};
7368 struct params list;
developere40952c2023-06-15 18:46:43 +08007369 int res;
developer72fb0bb2023-01-11 09:46:29 +08007370
developera3511852023-06-14 14:12:59 +08007371 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7372 if (threshold < 256 || threshold > 2346 )
7373 return RETURN_ERR;
7374 list.name = "fragm_threshold";
developere40952c2023-06-15 18:46:43 +08007375 res = snprintf(buf, sizeof(buf), "%d", threshold);
7376 if (os_snprintf_error(sizeof(buf), res)) {
7377 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7378 return RETURN_ERR;
7379 }
7380
developera3511852023-06-14 14:12:59 +08007381 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007382
developere40952c2023-06-15 18:46:43 +08007383 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7384 if (os_snprintf_error(sizeof(config_file), res)) {
7385 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7386 return RETURN_ERR;
7387 }
7388
developera3511852023-06-14 14:12:59 +08007389 wifi_hostapdWrite(config_file, &list, 1);
7390 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08007391
developera3511852023-06-14 14:12:59 +08007392 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007393
developera3511852023-06-14 14:12:59 +08007394 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007395}
7396
7397// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
7398INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
7399{
developera3511852023-06-14 14:12:59 +08007400 char config_file[64] = {'\0'};
7401 char cmd[512] = {'\0'};
7402 char buf[512] = {'\0'};
7403 char stbc_config[16] = {'\0'};
7404 wifi_band band;
7405 int iterator = 0;
7406 BOOL current_stbc = FALSE;
7407 int ant_count = 0;
7408 int ant_bitmap = 0;
7409 struct params list;
7410 char dat_file[64] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007411 int res;
developer72fb0bb2023-01-11 09:46:29 +08007412
developera3511852023-06-14 14:12:59 +08007413 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007414
developera3511852023-06-14 14:12:59 +08007415 band = wifi_index_to_band(radioIndex);
7416 if (band == band_invalid)
7417 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007418
developera3511852023-06-14 14:12:59 +08007419 if (band == band_2_4)
7420 iterator = 1;
7421 else if ((band == band_5) || (band == band_6))
7422 iterator = 2;
7423 else
7424 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007425
developera3511852023-06-14 14:12:59 +08007426 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
7427 for (; ant_bitmap > 0; ant_bitmap >>= 1)
7428 ant_count += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08007429
developera3511852023-06-14 14:12:59 +08007430 if (ant_count == 1 && STBC_Enable == TRUE) {
developer75bd10c2023-06-27 11:34:08 +08007431 wifi_debug(DEBUG_ERROR, "can not enable STBC when using only one antenna\n");
developera3511852023-06-14 14:12:59 +08007432 return RETURN_OK;
7433 }
developer72fb0bb2023-01-11 09:46:29 +08007434
developere40952c2023-06-15 18:46:43 +08007435 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
7436 if (os_snprintf_error(sizeof(config_file), res)) {
7437 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7438 return RETURN_ERR;
7439 }
developer72fb0bb2023-01-11 09:46:29 +08007440
developera3511852023-06-14 14:12:59 +08007441 // set ht and vht config
7442 for (int i = 0; i < iterator; i++) {
7443 memset(stbc_config, 0, sizeof(stbc_config));
7444 memset(cmd, 0, sizeof(cmd));
7445 memset(buf, 0, sizeof(buf));
7446 list.name = (i == 0)?"ht_capab":"vht_capab";
developere40952c2023-06-15 18:46:43 +08007447 res = snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
7448 if (os_snprintf_error(sizeof(stbc_config), res)) {
7449 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7450 return RETURN_ERR;
7451 }
7452
7453 res = snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
7454 if (os_snprintf_error(sizeof(cmd), res)) {
7455 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7456 return RETURN_ERR;
7457 }
7458
developera3511852023-06-14 14:12:59 +08007459 _syscmd(cmd, buf, sizeof(buf));
7460 if (strlen(buf) != 0)
7461 current_stbc = TRUE;
7462 if (current_stbc == STBC_Enable)
7463 continue;
developer72fb0bb2023-01-11 09:46:29 +08007464
developera3511852023-06-14 14:12:59 +08007465 if (STBC_Enable == TRUE) {
7466 // Append the STBC flags in capab config
7467 memset(cmd, 0, sizeof(cmd));
7468 if (i == 0)
developere40952c2023-06-15 18:46:43 +08007469 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
developera3511852023-06-14 14:12:59 +08007470 else
developere40952c2023-06-15 18:46:43 +08007471 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
7472 if (os_snprintf_error(sizeof(cmd), res)) {
7473 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7474 return RETURN_ERR;
7475 }
7476
developera3511852023-06-14 14:12:59 +08007477 _syscmd(cmd, buf, sizeof(buf));
7478 } else if (STBC_Enable == FALSE) {
7479 // Remove the STBC flags and remain other flags in capab
7480 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08007481 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
7482 if (os_snprintf_error(sizeof(cmd), res)) {
7483 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7484 return RETURN_ERR;
7485 }
7486
developera3511852023-06-14 14:12:59 +08007487 _syscmd(cmd, buf, sizeof(buf));
7488 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08007489 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
7490 if (os_snprintf_error(sizeof(cmd), res)) {
7491 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7492 return RETURN_ERR;
7493 }
7494
developera3511852023-06-14 14:12:59 +08007495 _syscmd(cmd, buf, sizeof(buf));
7496 }
7497 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
7498 list.value = buf;
7499 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
7500 }
developere40952c2023-06-15 18:46:43 +08007501 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7502 if (os_snprintf_error(sizeof(dat_file), res)) {
7503 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7504 return RETURN_ERR;
7505 }
7506
7507 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
7508 if (os_snprintf_error(sizeof(cmd), res)) {
7509 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7510 return RETURN_ERR;
7511 }
7512
developera1255e42023-05-13 17:45:02 +08007513 _syscmd(cmd, buf, sizeof(buf));
7514 if ((band == band_5) || (band == band_6)) {
developere40952c2023-06-15 18:46:43 +08007515 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
7516 if (os_snprintf_error(sizeof(cmd), res)) {
7517 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7518 return RETURN_ERR;
7519 }
7520
developera1255e42023-05-13 17:45:02 +08007521 _syscmd(cmd, buf, sizeof(buf));
7522 }
developera3511852023-06-14 14:12:59 +08007523 /*wifi_reloadAp(radioIndex);
developera1255e42023-05-13 17:45:02 +08007524 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08007525
developera3511852023-06-14 14:12:59 +08007526 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7527 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007528}
7529
7530// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
7531INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
7532{
developera3511852023-06-14 14:12:59 +08007533 char dat_file[128] = {0};
developer2c22d832023-05-18 17:46:26 +08007534 wifi_band band;
7535 char amdus_buff[8] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007536 int res;
developer72fb0bb2023-01-11 09:46:29 +08007537
developer2c22d832023-05-18 17:46:26 +08007538 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007539
developer2c22d832023-05-18 17:46:26 +08007540 band = wifi_index_to_band(radioIndex);
7541 if (band == band_invalid) {
7542 printf("%s:Band Error\n", __func__);
7543 return RETURN_ERR;
7544 }
developere40952c2023-06-15 18:46:43 +08007545 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7546 if (os_snprintf_error(sizeof(dat_file), res)) {
7547 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7548 return RETURN_ERR;
7549 }
7550
developer2c22d832023-05-18 17:46:26 +08007551 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
7552 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08007553 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08007554 else
7555 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08007556
developer2c22d832023-05-18 17:46:26 +08007557 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7558
7559 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007560}
7561
7562// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
7563INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
7564{
developer2c22d832023-05-18 17:46:26 +08007565 char dat_file[128] = {0};
7566 BOOL enable;
7567 wifi_band band;
7568 char amdus_buff[8] = {'\0'};
7569 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08007570 int res;
developer72fb0bb2023-01-11 09:46:29 +08007571
developer2c22d832023-05-18 17:46:26 +08007572 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007573
developer2c22d832023-05-18 17:46:26 +08007574 band = wifi_index_to_band(radioIndex);
7575 if (band == band_invalid) {
7576 printf("%s:Band Error\n", __func__);
7577 return RETURN_ERR;
7578 }
developere40952c2023-06-15 18:46:43 +08007579 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7580 if (os_snprintf_error(sizeof(dat_file), res)) {
7581 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7582 return RETURN_ERR;
7583 }
7584
developer2c22d832023-05-18 17:46:26 +08007585 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
7586 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08007587 enable = TRUE;
developer2c22d832023-05-18 17:46:26 +08007588 else
7589 enable = FALSE;
7590 if (amsduEnable == enable)
developera3511852023-06-14 14:12:59 +08007591 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007592
developer2c22d832023-05-18 17:46:26 +08007593 params.name = "HT_AMSDU";
7594 if (amsduEnable)
7595 params.value = "1";
7596 else
7597 params.value = "0";
7598 wifi_datfileWrite(dat_file, &params, 1);
7599 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08007600
developer2c22d832023-05-18 17:46:26 +08007601 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007602
developera3511852023-06-14 14:12:59 +08007603 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007604}
7605
7606//P2 // outputs the number of Tx streams
7607INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
7608{
developera3511852023-06-14 14:12:59 +08007609 char buf[8] = {0};
7610 char cmd[128] = {0};
7611 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08007612 int res;
developerc14d83a2023-06-29 20:09:42 +08007613 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08007614
developera3511852023-06-14 14:12:59 +08007615 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007616
developera3511852023-06-14 14:12:59 +08007617 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08007618 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
7619 if (os_snprintf_error(sizeof(cmd), res)) {
7620 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7621 return RETURN_ERR;
7622 }
7623
developera3511852023-06-14 14:12:59 +08007624 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007625
developerc14d83a2023-06-29 20:09:42 +08007626 if (hal_strtol(buf, 16, &tmp) < 0) {
7627 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08007628 }
developerc14d83a2023-06-29 20:09:42 +08007629 *output_int = tmp;
developer72fb0bb2023-01-11 09:46:29 +08007630
developera3511852023-06-14 14:12:59 +08007631 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007632
developera3511852023-06-14 14:12:59 +08007633 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007634}
7635
7636INT fitChainMask(INT radioIndex, int antcount)
7637{
developera3511852023-06-14 14:12:59 +08007638 char buf[128] = {0};
7639 char cmd[128] = {0};
7640 char config_file[64] = {0};
7641 wifi_band band;
7642 struct params list[2] = {0};
developere40952c2023-06-15 18:46:43 +08007643 int res;
developer72fb0bb2023-01-11 09:46:29 +08007644
developera3511852023-06-14 14:12:59 +08007645 band = wifi_index_to_band(radioIndex);
7646 if (band == band_invalid)
7647 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007648
developera3511852023-06-14 14:12:59 +08007649 list[0].name = "he_mu_beamformer";
7650 list[1].name = "he_su_beamformer";
developer72fb0bb2023-01-11 09:46:29 +08007651
developere40952c2023-06-15 18:46:43 +08007652 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
7653 if (os_snprintf_error(sizeof(config_file), res)) {
7654 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7655 return RETURN_ERR;
7656 }
7657
developera3511852023-06-14 14:12:59 +08007658 if (antcount == 1) {
7659 // remove config about multiple antennas
developere40952c2023-06-15 18:46:43 +08007660 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
7661 if (os_snprintf_error(sizeof(cmd), res)) {
7662 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7663 return RETURN_ERR;
7664 }
7665
developera3511852023-06-14 14:12:59 +08007666 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007667
developere40952c2023-06-15 18:46:43 +08007668 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
7669 if (os_snprintf_error(sizeof(cmd), res)) {
7670 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7671 return RETURN_ERR;
7672 }
7673
developera3511852023-06-14 14:12:59 +08007674 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007675
developere40952c2023-06-15 18:46:43 +08007676 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
7677 if (os_snprintf_error(sizeof(cmd), res)) {
7678 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7679 return RETURN_ERR;
7680 }
7681
developera3511852023-06-14 14:12:59 +08007682 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007683
developere40952c2023-06-15 18:46:43 +08007684 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
7685 if (os_snprintf_error(sizeof(cmd), res)) {
7686 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7687 return RETURN_ERR;
7688 }
7689
developera3511852023-06-14 14:12:59 +08007690 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007691
developera3511852023-06-14 14:12:59 +08007692 list[0].value = "0";
7693 list[1].value = "0";
7694 } else {
7695 // 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.
7696 if (band == band_2_4 || band == band_5) {
developere40952c2023-06-15 18:46:43 +08007697 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
7698 if (os_snprintf_error(sizeof(cmd), res)) {
7699 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7700 return RETURN_ERR;
7701 }
7702
developera3511852023-06-14 14:12:59 +08007703 _syscmd(cmd, buf, sizeof(buf));
7704 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08007705 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
7706 if (os_snprintf_error(sizeof(cmd), res)) {
7707 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7708 return RETURN_ERR;
7709 }
7710
developera3511852023-06-14 14:12:59 +08007711 _syscmd(cmd, buf, sizeof(buf));
7712 }
7713 }
7714 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08007715 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
7716 if (os_snprintf_error(sizeof(cmd), res)) {
7717 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7718 return RETURN_ERR;
7719 }
7720
developera3511852023-06-14 14:12:59 +08007721 _syscmd(cmd, buf, sizeof(buf));
7722 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08007723 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
7724 if (os_snprintf_error(sizeof(cmd), res)) {
7725 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7726 return RETURN_ERR;
7727 }
7728
developera3511852023-06-14 14:12:59 +08007729 _syscmd(cmd, buf, sizeof(buf));
7730 }
7731 }
developer72fb0bb2023-01-11 09:46:29 +08007732
developere40952c2023-06-15 18:46:43 +08007733 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
7734 if (os_snprintf_error(sizeof(cmd), res)) {
7735 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7736 return RETURN_ERR;
7737 }
7738
developera3511852023-06-14 14:12:59 +08007739 _syscmd(cmd, buf, sizeof(buf));
7740 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007741 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
7742 if (os_snprintf_error(sizeof(cmd), res)) {
7743 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7744 return RETURN_ERR;
7745 }
7746
developera3511852023-06-14 14:12:59 +08007747 _syscmd(cmd, buf, sizeof(buf));
7748 }
developer72fb0bb2023-01-11 09:46:29 +08007749
developere40952c2023-06-15 18:46:43 +08007750 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
developerc14d83a2023-06-29 20:09:42 +08007751 if (os_snprintf_error(sizeof(cmd), res)) {
7752 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7753 return RETURN_ERR;
7754 }
developera3511852023-06-14 14:12:59 +08007755 _syscmd(cmd, buf, sizeof(buf));
7756 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007757 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
7758 if (os_snprintf_error(sizeof(cmd), res)) {
7759 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7760 return RETURN_ERR;
7761 }
7762
developera3511852023-06-14 14:12:59 +08007763 _syscmd(cmd, buf, sizeof(buf));
7764 }
developer72fb0bb2023-01-11 09:46:29 +08007765
developere40952c2023-06-15 18:46:43 +08007766 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
7767 if (os_snprintf_error(sizeof(cmd), res)) {
7768 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7769 return RETURN_ERR;
7770 }
7771
developera3511852023-06-14 14:12:59 +08007772 _syscmd(cmd, buf, sizeof(buf));
7773 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007774 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
developera3511852023-06-14 14:12:59 +08007775 } else {
developere40952c2023-06-15 18:46:43 +08007776 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
7777 }
7778 if (os_snprintf_error(sizeof(cmd), res)) {
7779 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7780 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08007781 }
developere40952c2023-06-15 18:46:43 +08007782
developera3511852023-06-14 14:12:59 +08007783 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007784
developera3511852023-06-14 14:12:59 +08007785 list[0].value = "1";
7786 list[1].value = "1";
7787 }
7788 wifi_hostapdWrite(config_file, list, 2);
developerdaf24792023-06-06 11:40:04 +08007789 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007790}
7791
7792//P2 // sets the number of Tx streams to an enviornment variable
7793INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
7794{
developera3511852023-06-14 14:12:59 +08007795 char cmd[128] = {0};
7796 char buf[128] = {0};
7797 int phyId = 0;
7798 int cur_mask = 0;
7799 int antcountmsk = 0;
developera1255e42023-05-13 17:45:02 +08007800 INT cur_nss = 0;
developer863a4a62023-06-06 16:55:59 +08007801 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +08007802 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007803 int res;
developer72fb0bb2023-01-11 09:46:29 +08007804
developera3511852023-06-14 14:12:59 +08007805 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007806
developera3511852023-06-14 14:12:59 +08007807 if (numStreams <= 0) {
developer75bd10c2023-06-27 11:34:08 +08007808 wifi_debug(DEBUG_ERROR, "chainmask is not supported %d.\n", numStreams);
developera3511852023-06-14 14:12:59 +08007809 return RETURN_ERR;
7810 }
developer72fb0bb2023-01-11 09:46:29 +08007811
developera3511852023-06-14 14:12:59 +08007812 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
developera1255e42023-05-13 17:45:02 +08007813 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
7814 cur_nss += 1;
7815 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
developera3511852023-06-14 14:12:59 +08007816 if (cur_nss == numStreams)
7817 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007818
developera3511852023-06-14 14:12:59 +08007819 wifi_setRadioEnable(radioIndex, FALSE);
developer72fb0bb2023-01-11 09:46:29 +08007820
developera3511852023-06-14 14:12:59 +08007821 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08007822 //iw need mask value.
7823 for (;numStreams > 0; numStreams--)
7824 antcountmsk |= 0x1 << (numStreams - 1);
developere40952c2023-06-15 18:46:43 +08007825 res = snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
7826 if (os_snprintf_error(sizeof(cmd), res)) {
7827 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7828 return RETURN_ERR;
7829 }
developerb758dfd2023-06-21 17:32:07 +08007830
developera3511852023-06-14 14:12:59 +08007831 _syscmd(cmd, buf, sizeof(buf));
7832 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007833 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007834 return RETURN_ERR;
7835 }
7836 band = wifi_index_to_band(radioIndex);
developera1255e42023-05-13 17:45:02 +08007837 if (band == band_invalid) {
7838 printf("%s:Band Error\n", __func__);
7839 return RETURN_ERR;
7840 }
developere40952c2023-06-15 18:46:43 +08007841 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7842 if (os_snprintf_error(sizeof(dat_file), res)) {
7843 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7844 return RETURN_ERR;
7845 }
developerb758dfd2023-06-21 17:32:07 +08007846
developere40952c2023-06-15 18:46:43 +08007847 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
7848 if (os_snprintf_error(sizeof(cmd), res)) {
7849 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7850 return RETURN_ERR;
7851 }
developerb758dfd2023-06-21 17:32:07 +08007852
developera1255e42023-05-13 17:45:02 +08007853 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08007854 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007855 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007856 return RETURN_ERR;
7857 }
developere40952c2023-06-15 18:46:43 +08007858 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
7859 if (os_snprintf_error(sizeof(cmd), res)) {
7860 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7861 return RETURN_ERR;
7862 }
developerb758dfd2023-06-21 17:32:07 +08007863
developera1255e42023-05-13 17:45:02 +08007864 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08007865 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007866 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007867 return RETURN_ERR;
7868 }
7869 fitChainMask(radioIndex, numStreams);
7870 wifi_setRadioEnable(radioIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +08007871
developera3511852023-06-14 14:12:59 +08007872 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7873 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007874}
7875
7876//P2 // outputs the number of Rx streams
7877INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
7878{
developera3511852023-06-14 14:12:59 +08007879 char buf[8] = {0};
7880 char cmd[128] = {0};
7881 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +08007882 int res;
developerc14d83a2023-06-29 20:09:42 +08007883 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08007884
developera3511852023-06-14 14:12:59 +08007885 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007886
developera3511852023-06-14 14:12:59 +08007887 phyId = radio_index_to_phy(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08007888
7889 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
7890 if (os_snprintf_error(sizeof(cmd), res)) {
7891 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7892 return RETURN_ERR;
7893 }
developera3511852023-06-14 14:12:59 +08007894 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007895
developerc14d83a2023-06-29 20:09:42 +08007896 if (hal_strtol(buf, 16, &tmp) < 0) {
7897 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08007898 }
developerc14d83a2023-06-29 20:09:42 +08007899 *output_int = tmp;
developer72fb0bb2023-01-11 09:46:29 +08007900
developera3511852023-06-14 14:12:59 +08007901 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007902
developera3511852023-06-14 14:12:59 +08007903 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007904}
7905
7906//P2 // sets the number of Rx streams to an enviornment variable
7907INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
7908{
developera3511852023-06-14 14:12:59 +08007909 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7910 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08007911 wifi_debug(DEBUG_ERROR, "wifi_setRadioTxChainMask return error.\n");
developera3511852023-06-14 14:12:59 +08007912 return RETURN_ERR;
7913 }
7914 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7915 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007916}
7917
7918//Get radio RDG enable setting
7919INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
7920{
developer47cc27a2023-05-17 23:09:58 +08007921 if (NULL == output_bool)
7922 return RETURN_ERR;
7923
7924 *output_bool = TRUE;
7925 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007926}
7927
7928//Get radio RDG enable setting
7929INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
7930{
developer47cc27a2023-05-17 23:09:58 +08007931 char rdg_status[2] = {0};
7932 char dat_file[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08007933 int res;
developer47cc27a2023-05-17 23:09:58 +08007934
7935 if (NULL == output_bool)
7936 return RETURN_ERR;
7937
7938 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08007939 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7940 if (os_snprintf_error(sizeof(dat_file), res)) {
7941 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7942 return RETURN_ERR;
7943 }
developer47cc27a2023-05-17 23:09:58 +08007944
7945 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
7946 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
7947 *output_bool = TRUE;
7948 else
7949 *output_bool = FALSE;
7950
7951 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007952}
7953
7954//Set radio RDG enable setting
7955INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
7956{
developer47cc27a2023-05-17 23:09:58 +08007957 char dat_file[MAX_CMD_SIZE] = {0};
7958 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08007959 int res;
developer47cc27a2023-05-17 23:09:58 +08007960
7961 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08007962 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7963 if (os_snprintf_error(sizeof(dat_file), res)) {
7964 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7965 return RETURN_ERR;
7966 }
developer47cc27a2023-05-17 23:09:58 +08007967
7968 params.name = "HT_RDG";
7969
developera3511852023-06-14 14:12:59 +08007970 if (enable) {
7971 params.value = "1";
7972 } else {
7973 params.value = "0";
7974 }
developer47cc27a2023-05-17 23:09:58 +08007975
7976 wifi_datfileWrite(dat_file, &params, 1);
7977
7978 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007979}
7980
developer5cd4c862023-05-26 09:34:42 +08007981
7982int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08007983{
developer5cd4c862023-05-26 09:34:42 +08007984 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7985 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
7986 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7987 unsigned char status;
7988 unsigned char *out_status = data;
7989 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08007990
developer5cd4c862023-05-26 09:34:42 +08007991 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7992 genlmsg_attrlen(gnlh, 0), NULL);
7993 if (err < 0){
7994 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7995 return err;
7996 }
developer8e6583c2023-05-23 13:36:06 +08007997
developer5cd4c862023-05-26 09:34:42 +08007998 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7999 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
8000 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8001 if (err < 0){
8002 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
8003 return err;
8004 }
developer8e6583c2023-05-23 13:36:06 +08008005
developer5cd4c862023-05-26 09:34:42 +08008006 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
8007 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
8008 if (status == 0) {
8009 wifi_debug(DEBUG_NOTICE, "disabled\n");
8010 } else {
8011 wifi_debug(DEBUG_NOTICE, "enabled\n");
8012 }
8013 *out_status = status;
8014 }
8015 }
developer8e6583c2023-05-23 13:36:06 +08008016
developer5cd4c862023-05-26 09:34:42 +08008017 return 0;
8018}
developer8e6583c2023-05-23 13:36:06 +08008019
developer5cd4c862023-05-26 09:34:42 +08008020int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
8021{
8022 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8023 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
8024 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8025 unsigned char status;
8026 unsigned char *out_status = data;
8027 int err = 0;
8028
8029 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8030 genlmsg_attrlen(gnlh, 0), NULL);
8031 if (err < 0) {
8032 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
8033 return err;
8034 }
8035
8036 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8037 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
8038 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8039 if (err < 0) {
8040 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
8041 return err;
8042 }
8043
8044 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
8045 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
8046 if (status == 0) {
8047 wifi_debug(DEBUG_NOTICE, "disabled\n");
8048 } else {
8049 wifi_debug(DEBUG_NOTICE, "enabled\n");
8050 }
8051 *out_status = status;
8052 }
8053 }
8054
8055 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08008056}
8057
developer5cd4c862023-05-26 09:34:42 +08008058INT mtk_wifi_get_ba_decl_auto_status(
8059 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
8060{
8061 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08008062 unsigned int if_idx = 0;
8063 int ret = -1;
8064 struct unl unl_ins;
8065 struct nl_msg *msg = NULL;
8066 struct nlattr * msg_data = NULL;
8067 struct mtk_nl80211_param param;
8068
8069 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8070 return RETURN_ERR;
8071 if_idx = if_nametoindex(inf_name);
8072 if (!if_idx) {
8073 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8074 return RETURN_ERR;
8075 }
8076 /*init mtk nl80211 vendor cmd*/
8077 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
8078 param.if_type = NL80211_ATTR_IFINDEX;
8079 param.if_idx = if_idx;
8080
8081 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8082 if (ret) {
8083 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8084 return RETURN_ERR;
8085 }
8086 /*add mtk vendor cmd data*/
8087 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
8088 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8089 nlmsg_free(msg);
8090 goto err;
8091 }
8092
8093 /*send mtk nl80211 vendor msg*/
8094 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
8095 if (ret) {
8096 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8097 goto err;
8098 }
8099 /*deinit mtk nl80211 vendor msg*/
8100 mtk_nl80211_deint(&unl_ins);
8101 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
8102 return RETURN_OK;
8103err:
8104 mtk_nl80211_deint(&unl_ins);
8105 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8106 return RETURN_ERR;
8107}
developere0ff7232023-06-08 16:33:14 +08008108
8109INT mtk_wifi_set_auto_ba_en(
8110 INT apIndex, INT vendor_data_attr, BOOL enable)
8111{
8112 char inf_name[IF_NAME_SIZE] = {0};
8113 unsigned int if_idx = 0;
8114 int ret = -1;
8115 struct unl unl_ins;
8116 struct nl_msg *msg = NULL;
8117 struct nlattr * msg_data = NULL;
8118 struct mtk_nl80211_param param;
8119
8120 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8121 return RETURN_ERR;
8122 if_idx = if_nametoindex(inf_name);
8123 if (!if_idx) {
8124 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8125 return RETURN_ERR;
8126 }
8127 /*init mtk nl80211 vendor cmd*/
8128 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
8129 param.if_type = NL80211_ATTR_IFINDEX;
8130 param.if_idx = if_idx;
8131
8132 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8133 if (ret) {
8134 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8135 return RETURN_ERR;
8136 }
8137 /*add mtk vendor cmd data*/
8138 if (nla_put_u8(msg, vendor_data_attr, enable)) {
8139 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8140 nlmsg_free(msg);
8141 goto err;
8142 }
8143
8144 /*send mtk nl80211 vendor msg*/
8145 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8146 if (ret) {
8147 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8148 goto err;
8149 }
8150 /*deinit mtk nl80211 vendor msg*/
8151 mtk_nl80211_deint(&unl_ins);
8152 return RETURN_OK;
8153err:
8154 mtk_nl80211_deint(&unl_ins);
8155 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8156 return RETURN_ERR;
8157}
8158
developer5cd4c862023-05-26 09:34:42 +08008159//Get radio ADDBA enable setting
8160INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
8161{
8162 if (output_bool == NULL) {
8163 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8164 return RETURN_ERR;
8165 }
8166 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
8167 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
8168 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
8169 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
8170 return RETURN_ERR;
8171 }
8172 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
8173 return RETURN_OK;
8174}
8175
developer72fb0bb2023-01-11 09:46:29 +08008176//Set radio ADDBA enable setting
8177INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
8178{
developera3511852023-06-14 14:12:59 +08008179 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008180}
8181
8182//Get radio auto block ack enable setting
8183INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
8184{
developer5cd4c862023-05-26 09:34:42 +08008185 if (output_bool == NULL) {
8186 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8187 return RETURN_ERR;
8188 }
developer8e6583c2023-05-23 13:36:06 +08008189
developera3511852023-06-14 14:12:59 +08008190 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
developer5cd4c862023-05-26 09:34:42 +08008191 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
8192 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
8193 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
8194 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
8195 return RETURN_ERR;
8196 }
8197 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
8198 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008199}
8200
8201//Set radio auto block ack enable setting
8202INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
8203{
developera3511852023-06-14 14:12:59 +08008204 if (mtk_wifi_set_auto_ba_en
developere0ff7232023-06-08 16:33:14 +08008205 (radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
8206 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
8207 return RETURN_ERR;
8208 }
8209 wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08008210 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008211}
8212
8213//Get radio 11n pure mode enable support
8214INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
8215{
developera3511852023-06-14 14:12:59 +08008216 if (NULL == output_bool)
8217 return RETURN_ERR;
8218 *output_bool = TRUE;
8219 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008220}
8221
8222//Get radio 11n pure mode enable setting
8223INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
8224{
developera3511852023-06-14 14:12:59 +08008225 if (NULL == output_bool)
8226 return RETURN_ERR;
8227 *output_bool = TRUE;
8228 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008229}
8230
8231//Set radio 11n pure mode enable setting
developer86035662023-06-28 19:21:12 +08008232INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
developer72fb0bb2023-01-11 09:46:29 +08008233{
developer82533be2023-06-28 17:21:01 +08008234 char interface_name[16] = {0};
8235 int if_idx, ret = 0;
8236 struct nl_msg *msg = NULL;
8237 struct nlattr * msg_data = NULL;
8238 struct mtk_nl80211_param param;
8239 struct unl unl_ins;
8240
8241 if (radioIndex > MAX_APS) {
8242 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", radioIndex);
8243 return RETURN_ERR;
8244 }
8245 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8246 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
8247 return RETURN_ERR;
developerd14dff12023-06-28 22:47:44 +08008248
developer82533be2023-06-28 17:21:01 +08008249 if_idx = if_nametoindex(interface_name);
8250 /*init mtk nl80211 vendor cmd*/
8251 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
8252 param.if_type = NL80211_ATTR_IFINDEX;
8253 param.if_idx = if_idx;
8254 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8255 if (ret) {
8256 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8257 return RETURN_ERR;
8258 }
8259 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_HT_OP_MODE, enable)) {
8260 printf("Nla put attribute error\n");
8261 nlmsg_free(msg);
8262 goto err;
8263 }
8264 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8265 if (ret) {
8266 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8267 goto err;
8268 }
8269 mtk_nl80211_deint(&unl_ins);
8270 //wifi_debug(DEBUG_NOTICE, "set Gf cmd success.\n");
8271 printf("set gf=%d cmd success.\n", enable);
8272 return RETURN_OK;
8273err:
8274 mtk_nl80211_deint(&unl_ins);
8275 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08008276 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008277}
8278
developer5cd4c862023-05-26 09:34:42 +08008279int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08008280{
developer5cd4c862023-05-26 09:34:42 +08008281 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8282 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
8283 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8284 unsigned char status = 0, *out_status = data;
8285 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08008286
developer5cd4c862023-05-26 09:34:42 +08008287 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8288 genlmsg_attrlen(gnlh, 0), NULL);
8289 if (err < 0) {
8290 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
8291 return err;
8292 }
developer72fb0bb2023-01-11 09:46:29 +08008293
developer5cd4c862023-05-26 09:34:42 +08008294 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8295 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
8296 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8297 if (err < 0){
8298 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
8299 return err;
8300 }
developer72fb0bb2023-01-11 09:46:29 +08008301
developer5cd4c862023-05-26 09:34:42 +08008302 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
8303 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
8304 if (status == 0) {
8305 wifi_debug(DEBUG_NOTICE, "disabled\n");
8306 } else {
8307 wifi_debug(DEBUG_NOTICE, "enabled\n");
8308 }
8309 *out_status = status;
8310 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
8311 }
8312 }
8313
8314 return 0;
8315}
8316
8317INT mtk_wifi_set_igmp_en_status(
8318 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
8319 unsigned char in_en_stat, BOOL *output_bool)
8320{
8321 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08008322 unsigned int if_idx = 0;
8323 int ret = -1;
8324 struct unl unl_ins;
8325 struct nl_msg *msg = NULL;
8326 struct nlattr * msg_data = NULL;
8327 struct mtk_nl80211_param param;
8328
8329 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8330 return RETURN_ERR;
8331 if_idx = if_nametoindex(inf_name);
8332 if (!if_idx) {
8333 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8334 return RETURN_ERR;
8335 }
8336 /*init mtk nl80211 vendor cmd*/
8337 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
8338 param.if_type = NL80211_ATTR_IFINDEX;
8339 param.if_idx = if_idx;
8340
8341 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8342 if (ret) {
8343 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8344 return RETURN_ERR;
8345 }
8346 /*add mtk vendor cmd data*/
8347 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
8348 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8349 nlmsg_free(msg);
8350 goto err;
8351 }
8352
8353 /*send mtk nl80211 vendor msg*/
8354 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
8355 if (ret) {
8356 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8357 goto err;
8358 }
8359 /*deinit mtk nl80211 vendor msg*/
8360 mtk_nl80211_deint(&unl_ins);
8361 if (output_bool) {
8362 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
8363 } else {
8364 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
8365 }
8366 return RETURN_OK;
8367err:
8368 mtk_nl80211_deint(&unl_ins);
8369 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8370 return RETURN_ERR;
8371}
8372
8373
8374//Get radio IGMP snooping enable setting
8375INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
8376{
8377 if (output_bool == NULL) {
8378 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8379 return RETURN_ERR;
8380 }
developera3511852023-06-14 14:12:59 +08008381 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08008382 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
8383 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
8384 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
8385 return RETURN_ERR;
8386 }
8387 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developera3511852023-06-14 14:12:59 +08008388 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008389}
8390
8391//Set radio IGMP snooping enable setting
8392INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
8393{
developera3511852023-06-14 14:12:59 +08008394 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08008395 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
8396 NULL, enable, NULL) != RETURN_OK) {
8397 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
8398 return RETURN_ERR;
8399 }
8400 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08008401 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008402}
8403
8404//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08008405INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08008406{
developera3511852023-06-14 14:12:59 +08008407 if (NULL == output_int)
8408 return RETURN_ERR;
8409 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08008410
developera3511852023-06-14 14:12:59 +08008411 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008412}
8413
8414
8415//---------------------------------------------------------------------------------------------------
8416//
8417// Additional Wifi AP level APIs used for Access Point devices
8418//
8419//---------------------------------------------------------------------------------------------------
8420
8421// creates a new ap and pushes these parameters to the hardware
8422INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
8423{
developera3511852023-06-14 14:12:59 +08008424 // Deprecated when use hal version 3, use wifi_createVap() instead.
8425 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008426}
8427
8428// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
8429INT wifi_deleteAp(INT apIndex)
8430{
developer7e4a2a62023-04-06 19:56:03 +08008431 char interface_name[16] = {0};
8432 char buf[MAX_BUF_SIZE];
8433 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08008434 int res;
developer72fb0bb2023-01-11 09:46:29 +08008435
developer7e4a2a62023-04-06 19:56:03 +08008436 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8437 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08008438
developere40952c2023-06-15 18:46:43 +08008439 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8440 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
8441 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8442 return RETURN_ERR;
8443 }
developer7e4a2a62023-04-06 19:56:03 +08008444 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008445
developer7e4a2a62023-04-06 19:56:03 +08008446 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008447
developer7e4a2a62023-04-06 19:56:03 +08008448 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008449}
8450
8451// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
8452INT wifi_getApName(INT apIndex, CHAR *output_string)
8453{
developer7e4a2a62023-04-06 19:56:03 +08008454 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008455 int radio_idx = 0;
8456 int bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08008457 int res;
developer72fb0bb2023-01-11 09:46:29 +08008458
developer7e4a2a62023-04-06 19:56:03 +08008459 if(!output_string)
8460 return RETURN_ERR;
8461
8462 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8463 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
8464
developere40952c2023-06-15 18:46:43 +08008465 res = snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model.
developer7e4a2a62023-04-06 19:56:03 +08008466 } else
developere40952c2023-06-15 18:46:43 +08008467 res = snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
8468
8469 if (os_snprintf_error(IF_NAME_SIZE, res)) {
8470 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8471 return RETURN_ERR;
8472 }
developer7e4a2a62023-04-06 19:56:03 +08008473
8474 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008475}
8476
8477// Outputs the index number in that corresponds to the SSID string
8478INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
8479{
developer7e4a2a62023-04-06 19:56:03 +08008480 char cmd [128] = {0};
8481 char buf[32] = {0};
8482 char ap_idx = 0;
8483 char *apIndex_str = NULL;
8484 char radio_idx = 0;
8485 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08008486 int res;
developerc14d83a2023-06-29 20:09:42 +08008487 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08008488
developere40952c2023-06-15 18:46:43 +08008489 res = snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +08008490 inputSsidString);
developere40952c2023-06-15 18:46:43 +08008491
8492 if (os_snprintf_error(sizeof(cmd), res)) {
8493 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8494 return RETURN_ERR;
8495 }
8496
developer7e4a2a62023-04-06 19:56:03 +08008497 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008498
developer7e4a2a62023-04-06 19:56:03 +08008499 if (strlen(buf)) {
8500 apIndex_str = strtok(buf, "\n");
developerd14dff12023-06-28 22:47:44 +08008501 if (apIndex_str == NULL) {
8502 wifi_debug(DEBUG_ERROR, "strtok fail\n");
8503 return RETURN_ERR;
8504 }
developerc14d83a2023-06-29 20:09:42 +08008505 if (hal_strtol(apIndex_str, 10, &tmp) < 0) {
8506 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08008507 }
developerc14d83a2023-06-29 20:09:42 +08008508 *output_int = tmp;
developer7e4a2a62023-04-06 19:56:03 +08008509 return RETURN_OK;
8510 }
developer72fb0bb2023-01-11 09:46:29 +08008511
developer7e4a2a62023-04-06 19:56:03 +08008512 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
8513 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
8514 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
8515 radio_idx = 2;
8516 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
8517 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
8518 radio_idx = 1;
8519 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
8520 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
8521 radio_idx = 0;
8522 } else {
8523 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
8524 __func__, inputSsidString, ap_idx);
developera3511852023-06-14 14:12:59 +08008525 *output_int = -1;
8526 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08008527 }
8528
8529 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
8530
8531 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
8532 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
8533 __func__, inputSsidString, ap_idx);
8534 *output_int = ap_idx;
8535 return RETURN_OK;
8536 }
8537
8538 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008539}
8540
8541INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
8542{
developera3511852023-06-14 14:12:59 +08008543 return wifi_getIndexFromName(inputSsidString, output_int);
developer72fb0bb2023-01-11 09:46:29 +08008544}
8545
8546// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
8547INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
8548{
developera3511852023-06-14 14:12:59 +08008549 char buf[MAX_BUF_SIZE] = {0};
8550 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08008551 int res;
developer72fb0bb2023-01-11 09:46:29 +08008552
developera3511852023-06-14 14:12:59 +08008553 if(NULL == output_string)
8554 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008555
developer32f2a182023-06-27 19:50:41 +08008556 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
8557 if (os_snprintf_error(sizeof(config_file), res)) {
8558 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8559 return RETURN_ERR;
8560 }
developera3511852023-06-14 14:12:59 +08008561 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
8562 if((strcmp(buf,"3")==0))
developere40952c2023-06-15 18:46:43 +08008563 res = snprintf(output_string, 32, "WPAand11i");
developera3511852023-06-14 14:12:59 +08008564 else if((strcmp(buf,"2")==0))
developere40952c2023-06-15 18:46:43 +08008565 res = snprintf(output_string, 32, "11i");
developera3511852023-06-14 14:12:59 +08008566 else if((strcmp(buf,"1")==0))
developere40952c2023-06-15 18:46:43 +08008567 res = snprintf(output_string, 32, "WPA");
developera3511852023-06-14 14:12:59 +08008568 else
developere40952c2023-06-15 18:46:43 +08008569 res = snprintf(output_string, 32, "None");
8570 if (os_snprintf_error(32, res)) {
8571 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8572 return RETURN_ERR;
8573 }
developer72fb0bb2023-01-11 09:46:29 +08008574
developera3511852023-06-14 14:12:59 +08008575 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008576}
8577
8578// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
8579INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
8580{
developera3511852023-06-14 14:12:59 +08008581 char config_file[MAX_BUF_SIZE] = {0};
8582 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008583 int res;
developer72fb0bb2023-01-11 09:46:29 +08008584
developera3511852023-06-14 14:12:59 +08008585 if (NULL == beaconTypeString)
8586 return RETURN_ERR;
8587 list.name = "wpa";
8588 list.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08008589
developera3511852023-06-14 14:12:59 +08008590 if((strcmp(beaconTypeString,"WPAand11i")==0))
8591 list.value="3";
8592 else if((strcmp(beaconTypeString,"11i")==0))
8593 list.value="2";
8594 else if((strcmp(beaconTypeString,"WPA")==0))
8595 list.value="1";
developer72fb0bb2023-01-11 09:46:29 +08008596
developer75bd10c2023-06-27 11:34:08 +08008597 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8598 if (os_snprintf_error(sizeof(config_file), res)) {
8599 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8600 return RETURN_ERR;
8601 }
developera3511852023-06-14 14:12:59 +08008602 wifi_hostapdWrite(config_file, &list, 1);
8603 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8604 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8605 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008606}
8607
8608// sets the beacon interval on the hardware for this AP
8609INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
8610{
developera3511852023-06-14 14:12:59 +08008611 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8612 struct params params={'\0'};
8613 char buf[MAX_BUF_SIZE] = {'\0'};
8614 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08008615 int res;
developer72fb0bb2023-01-11 09:46:29 +08008616
developera3511852023-06-14 14:12:59 +08008617 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08008618 res = snprintf(buf, sizeof(buf), "%u", beaconInterval);
8619 if (os_snprintf_error(sizeof(buf), res)) {
8620 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8621 return RETURN_ERR;
8622 }
developera3511852023-06-14 14:12:59 +08008623 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08008624
developer75bd10c2023-06-27 11:34:08 +08008625 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8626 if (os_snprintf_error(sizeof(config_file), res)) {
8627 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8628 return RETURN_ERR;
8629 }
developera3511852023-06-14 14:12:59 +08008630 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08008631
developera3511852023-06-14 14:12:59 +08008632 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8633 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8634 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008635}
8636
8637INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
8638{
developera3511852023-06-14 14:12:59 +08008639 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
8640 return RETURN_ERR;
8641 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008642}
8643
8644// Get the packet size threshold supported.
8645INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
8646{
developera3511852023-06-14 14:12:59 +08008647 //save config and apply instantly
8648 if (NULL == output_bool)
8649 return RETURN_ERR;
8650 *output_bool = TRUE;
8651 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008652}
8653
8654// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
8655INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
8656{
developera3511852023-06-14 14:12:59 +08008657 char buf[16] = {0};
8658 char config_file[128] = {0};
8659 struct params param = {0};
developere40952c2023-06-15 18:46:43 +08008660 int res;
developer72fb0bb2023-01-11 09:46:29 +08008661
developera3511852023-06-14 14:12:59 +08008662 if (threshold > 65535) {
developer75bd10c2023-06-27 11:34:08 +08008663 wifi_debug(DEBUG_ERROR, "rts threshold %u is too big.\n", threshold);
developera3511852023-06-14 14:12:59 +08008664 return RETURN_ERR;
8665 }
developer72fb0bb2023-01-11 09:46:29 +08008666
developere40952c2023-06-15 18:46:43 +08008667 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8668 if (os_snprintf_error(sizeof(config_file), res)) {
8669 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8670 return RETURN_ERR;
8671 }
8672
8673 res = snprintf(buf, sizeof(buf), "%u", threshold);
8674 if (os_snprintf_error(sizeof(buf), res)) {
8675 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8676 return RETURN_ERR;
8677 }
developera3511852023-06-14 14:12:59 +08008678 param.name = "rts_threshold";
8679 param.value = buf;
8680 wifi_hostapdWrite(config_file, &param, 1);
8681 wifi_hostapdProcessUpdate(apIndex, &param, 1);
8682 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008683
developera3511852023-06-14 14:12:59 +08008684 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008685}
8686
8687// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8688INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
8689{
developere40952c2023-06-15 18:46:43 +08008690 int res;
8691
developera3511852023-06-14 14:12:59 +08008692 if (NULL == output_string)
8693 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008694 res = snprintf(output_string, 32, "TKIPandAESEncryption");
8695 if (os_snprintf_error(32, res)) {
8696 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8697 return RETURN_ERR;
8698 }
developera3511852023-06-14 14:12:59 +08008699 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008700
8701}
8702
8703// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8704INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
8705{
developera3511852023-06-14 14:12:59 +08008706 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8707 char *param_name = NULL;
8708 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
developerc79e9172023-06-06 19:48:03 +08008709 unsigned int len;
developere40952c2023-06-15 18:46:43 +08008710 int res;
developer72fb0bb2023-01-11 09:46:29 +08008711
developera3511852023-06-14 14:12:59 +08008712 if(NULL == output_string)
8713 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008714
developer75bd10c2023-06-27 11:34:08 +08008715 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8716 if (os_snprintf_error(sizeof(config_file), res)) {
8717 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8718 return RETURN_ERR;
8719 }
8720
developera3511852023-06-14 14:12:59 +08008721 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008722
developera3511852023-06-14 14:12:59 +08008723 if(strcmp(buf,"0")==0)
8724 {
8725 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
developere40952c2023-06-15 18:46:43 +08008726 res = snprintf(output_string, 32, "None");
8727 if (os_snprintf_error(32, res)) {
8728 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8729 return RETURN_ERR;
8730 }
developera3511852023-06-14 14:12:59 +08008731 return RETURN_OK;
8732 }
8733 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
8734 param_name = "rsn_pairwise";
8735 else if((strcmp(buf,"1")==0))
8736 param_name = "wpa_pairwise";
8737 else
8738 return RETURN_ERR;
8739 memset(output_string,'\0',32);
8740 wifi_hostapdRead(config_file,param_name,output_string,32);
8741 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
8742 param_name = "wpa_pairwise";
8743 memset(output_string, '\0', 32);
8744 wifi_hostapdRead(config_file, param_name, output_string, 32);
8745 }
8746 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
developer72fb0bb2023-01-11 09:46:29 +08008747
developera3511852023-06-14 14:12:59 +08008748 if(strcmp(output_string,"TKIP CCMP") == 0) {
developerc79e9172023-06-06 19:48:03 +08008749 len = strlen("TKIPandAESEncryption");
8750 memcpy(output_string,"TKIPandAESEncryption", len);
8751 output_string[len] = '\0';
8752 } else if(strcmp(output_string,"TKIP") == 0) {
8753 len = strlen("TKIPEncryption");
8754 memcpy(output_string,"TKIPEncryption", len);
8755 output_string[len] = '\0';
8756 } else if(strcmp(output_string,"CCMP") == 0) {
8757 len = strlen("AESEncryption");
8758 memcpy(output_string,"AESEncryption", len);
8759 output_string[len] = '\0';
8760 }
developer72fb0bb2023-01-11 09:46:29 +08008761
developera3511852023-06-14 14:12:59 +08008762 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8763 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008764}
8765
8766// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8767INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
8768{
developera3511852023-06-14 14:12:59 +08008769 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8770 struct params params={'\0'};
8771 char output_string[32];
8772 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008773 int res;
developer72fb0bb2023-01-11 09:46:29 +08008774
developera3511852023-06-14 14:12:59 +08008775 memset(output_string,'\0',32);
8776 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08008777
developera3511852023-06-14 14:12:59 +08008778 if(strcmp(encMode, "TKIPEncryption") == 0)
8779 params.value = "TKIP";
8780 else if(strcmp(encMode,"AESEncryption") == 0)
8781 params.value = "CCMP";
8782 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
8783 params.value = "TKIP CCMP";
developer72fb0bb2023-01-11 09:46:29 +08008784
developera3511852023-06-14 14:12:59 +08008785 if((strcmp(output_string,"WPAand11i")==0))
8786 {
8787 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008788 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8789 if (os_snprintf_error(sizeof(config_file), res)) {
8790 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8791 return RETURN_ERR;
8792 }
developera3511852023-06-14 14:12:59 +08008793 wifi_hostapdWrite(config_file, &params, 1);
8794 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08008795
developera3511852023-06-14 14:12:59 +08008796 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008797 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8798 if (os_snprintf_error(sizeof(config_file), res)) {
8799 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8800 return RETURN_ERR;
8801 }
developera3511852023-06-14 14:12:59 +08008802 wifi_hostapdWrite(config_file, &params, 1);
8803 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08008804
developera3511852023-06-14 14:12:59 +08008805 return RETURN_OK;
8806 }
8807 else if((strcmp(output_string,"11i")==0))
8808 {
8809 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008810 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8811 if (os_snprintf_error(sizeof(config_file), res)) {
8812 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8813 return RETURN_ERR;
8814 }
developera3511852023-06-14 14:12:59 +08008815 wifi_hostapdWrite(config_file, &params, 1);
8816 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8817 return RETURN_OK;
8818 }
8819 else if((strcmp(output_string,"WPA")==0))
8820 {
8821 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008822 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8823 if (os_snprintf_error(sizeof(config_file), res)) {
8824 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8825 return RETURN_ERR;
8826 }
developera3511852023-06-14 14:12:59 +08008827 wifi_hostapdWrite(config_file, &params, 1);
8828 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8829 return RETURN_OK;
8830 }
developer72fb0bb2023-01-11 09:46:29 +08008831
developera3511852023-06-14 14:12:59 +08008832 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8833 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008834}
8835
8836// deletes internal security varable settings for this ap
8837INT wifi_removeApSecVaribles(INT apIndex)
8838{
developer0155a502023-06-19 20:33:57 +08008839 char config_file[MAX_BUF_SIZE] = {0};
8840 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008841 int res;
developer0155a502023-06-19 20:33:57 +08008842
8843 list.name = "wpa";
8844 list.value = "0";
8845
developer75bd10c2023-06-27 11:34:08 +08008846 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8847 if (os_snprintf_error(sizeof(config_file), res)) {
8848 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8849 return RETURN_ERR;
8850 }
developer0155a502023-06-19 20:33:57 +08008851 wifi_hostapdWrite(config_file, &list, 1);
8852
8853 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008854}
8855
8856// changes the hardware settings to disable encryption on this ap
8857INT wifi_disableApEncryption(INT apIndex)
8858{
developer0155a502023-06-19 20:33:57 +08008859 char config_file[MAX_BUF_SIZE] = {0};
8860 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008861 int res;
developer0155a502023-06-19 20:33:57 +08008862
8863 list.name = "wpa";
8864 list.value = "0";
8865
developer75bd10c2023-06-27 11:34:08 +08008866 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8867 if (os_snprintf_error(sizeof(config_file), res)) {
8868 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8869 return RETURN_ERR;
8870 }
developer0155a502023-06-19 20:33:57 +08008871 wifi_hostapdWrite(config_file, &list, 1);
8872 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8873 wifi_reloadAp(apIndex);
8874
8875 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008876}
8877
8878// set the authorization mode on this ap
8879// mode mapping as: 1: open, 2: shared, 4:auto
8880INT wifi_setApAuthMode(INT apIndex, INT mode)
8881{
developera3511852023-06-14 14:12:59 +08008882 struct params params={0};
8883 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +08008884 int res;
developer72fb0bb2023-01-11 09:46:29 +08008885
developera3511852023-06-14 14:12:59 +08008886 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008887
developera3511852023-06-14 14:12:59 +08008888 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
8889 params.name = "auth_algs";
developer72fb0bb2023-01-11 09:46:29 +08008890
developere5750452023-05-15 16:46:42 +08008891 if ((mode & 1 && mode & 2) || mode & 4)
developera3511852023-06-14 14:12:59 +08008892 params.value = "3";
8893 else if (mode & 2)
8894 params.value = "2";
8895 else if (mode & 1)
8896 params.value = "1";
8897 else
8898 params.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08008899
developer75bd10c2023-06-27 11:34:08 +08008900 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8901 if (os_snprintf_error(sizeof(config_file), res)) {
8902 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8903 return RETURN_ERR;
8904 }
developera3511852023-06-14 14:12:59 +08008905 wifi_hostapdWrite(config_file, &params, 1);
8906 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008907 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +08008908 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008909
developera3511852023-06-14 14:12:59 +08008910 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008911}
8912
8913// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
8914INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
8915{
developera3511852023-06-14 14:12:59 +08008916 //save to wifi config, and wait for wifi restart to apply
8917 struct params params={'\0'};
8918 char config_file[MAX_BUF_SIZE] = {0};
8919 int ret;
developer72fb0bb2023-01-11 09:46:29 +08008920
developera3511852023-06-14 14:12:59 +08008921 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8922 if(authMode == NULL)
8923 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008924
developera3511852023-06-14 14:12:59 +08008925 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
8926 params.name = "wpa_key_mgmt";
developer72fb0bb2023-01-11 09:46:29 +08008927
developera3511852023-06-14 14:12:59 +08008928 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
8929 params.value = "WPA-PSK";
8930 else if(strcmp(authMode,"EAPAuthentication") == 0)
8931 params.value = "WPA-EAP";
8932 else if (strcmp(authMode, "SAEAuthentication") == 0)
8933 params.value = "SAE";
8934 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
8935 params.value = "WPA-EAP-SUITE-B-192";
8936 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
8937 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
8938 else if (strcmp(authMode, "Enhanced_Open") == 0)
8939 params.value = "OWE";
8940 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
8941 return RETURN_OK; //This is taken careof in beaconType
developer72fb0bb2023-01-11 09:46:29 +08008942
developer32f2a182023-06-27 19:50:41 +08008943 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
8944 if (os_snprintf_error(sizeof(config_file), ret)) {
8945 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8946 return RETURN_ERR;
8947 }
developera3511852023-06-14 14:12:59 +08008948 ret=wifi_hostapdWrite(config_file,&params,1);
8949 if(!ret)
8950 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
8951 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008952
developera3511852023-06-14 14:12:59 +08008953 return ret;
developer72fb0bb2023-01-11 09:46:29 +08008954}
8955
8956// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
8957INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
8958{
developera3511852023-06-14 14:12:59 +08008959 //save to wifi config, and wait for wifi restart to apply
8960 char BeaconType[50] = {0};
8961 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008962 int res;
developer32f2a182023-06-27 19:50:41 +08008963 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08008964
developera3511852023-06-14 14:12:59 +08008965 *authMode = 0;
8966 wifi_getApBeaconType(apIndex,BeaconType);
8967 printf("%s____%s \n",__FUNCTION__,BeaconType);
developer72fb0bb2023-01-11 09:46:29 +08008968
developer32f2a182023-06-27 19:50:41 +08008969 if(strcmp(BeaconType,"None") == 0) {
8970 memcpy(authMode, "None", 4);
8971 authMode[4] = '\0';
8972 } else {
8973 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
developer75bd10c2023-06-27 11:34:08 +08008974 if (os_snprintf_error(sizeof(config_file), res)) {
8975 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8976 return RETURN_ERR;
8977 }
developera3511852023-06-14 14:12:59 +08008978 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
8979 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
developer32f2a182023-06-27 19:50:41 +08008980 if(strcmp(authMode,"WPA-PSK") == 0) {
8981 len = strlen("SharedAuthentication");
8982 memcpy(authMode, "SharedAuthentication", len);
8983 authMode[len] = '\0';
8984 } else if(strcmp(authMode,"WPA-EAP") == 0) {
8985 len = strlen("EAPAuthentication");
8986 memcpy(authMode, "EAPAuthentication", len);
8987 authMode[len] = '\0';
8988 }
developera3511852023-06-14 14:12:59 +08008989 }
developer72fb0bb2023-01-11 09:46:29 +08008990
developera3511852023-06-14 14:12:59 +08008991 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008992}
8993
8994// Outputs the number of stations associated per AP
8995INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
8996{
developera3511852023-06-14 14:12:59 +08008997 char interface_name[16] = {0};
8998 char cmd[128]={0};
8999 char buf[128]={0};
9000 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +08009001 int res;
developer72fb0bb2023-01-11 09:46:29 +08009002
developera3511852023-06-14 14:12:59 +08009003 if(apIndex > MAX_APS)
9004 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009005
developera3511852023-06-14 14:12:59 +08009006 wifi_getApEnable(apIndex,&status);
9007 if (!status)
9008 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009009
developera3511852023-06-14 14:12:59 +08009010 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
9011 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9012 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08009013 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta | wc -l", interface_name);
9014 if (os_snprintf_error(sizeof(cmd), res)) {
9015 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9016 return RETURN_ERR;
9017 }
developera3511852023-06-14 14:12:59 +08009018 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08009019 if (sscanf(buf,"%lu", output_ulong) != 1) {
9020 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
9021 return RETURN_ERR;
9022 }
developer72fb0bb2023-01-11 09:46:29 +08009023
developera3511852023-06-14 14:12:59 +08009024 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009025}
9026
9027// manually removes any active wi-fi association with the device specified on this ap
9028INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
9029{
developera3511852023-06-14 14:12:59 +08009030 char inf_name[16] = {0};
9031 char cmd[MAX_CMD_SIZE] = {0};
9032 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08009033 int res;
developer72fb0bb2023-01-11 09:46:29 +08009034
developera3511852023-06-14 14:12:59 +08009035 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9036 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009037
9038 res = snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
9039 if (os_snprintf_error(sizeof(cmd), res)) {
9040 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9041 return RETURN_ERR;
9042 }
developer7e4a2a62023-04-06 19:56:03 +08009043
developera3511852023-06-14 14:12:59 +08009044 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009045
developera3511852023-06-14 14:12:59 +08009046 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009047}
9048
9049// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
9050INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
9051{
developer7e4a2a62023-04-06 19:56:03 +08009052 int max_radio_num = 0;
9053
9054 if(NULL == output_int)
9055 return RETURN_ERR;
9056
9057 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08009058 if(max_radio_num == 0){
9059 return RETURN_ERR;
9060 }
developer7e4a2a62023-04-06 19:56:03 +08009061 *output_int = apIndex % max_radio_num;
9062
9063 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009064}
9065
9066// sets the radio index for the specific ap
9067INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
9068{
developera3511852023-06-14 14:12:59 +08009069 //set to config only and wait for wifi reset to apply settings
9070 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009071}
9072
developer0155a502023-06-19 20:33:57 +08009073int mtk_get_ap_metrics(struct nl_msg *msg, void *cb)
9074{
9075 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9076 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX + 1];
developerc14d83a2023-06-29 20:09:42 +08009077 struct genlmsghdr *gnlh;
developer0155a502023-06-19 20:33:57 +08009078 wdev_ap_metric ap_metric;
9079 wdev_ap_metric *p_ap_metric = &ap_metric;
9080 int err = 0;
9081 struct mtk_nl80211_cb_data *cb_data = cb;
9082
9083 if (!msg || !cb_data) {
developerc14d83a2023-06-29 20:09:42 +08009084 wifi_debug(DEBUG_ERROR, "msgor cb_data is null,error.\n");
developer0155a502023-06-19 20:33:57 +08009085 return NL_SKIP;
9086 }
developerc14d83a2023-06-29 20:09:42 +08009087 gnlh = nlmsg_data(nlmsg_hdr(msg));
developer0155a502023-06-19 20:33:57 +08009088
9089 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9090 genlmsg_attrlen(gnlh, 0), NULL);
9091 if (err < 0) {
9092 wifi_debug(DEBUG_ERROR, "nla_parse ap_metrics nl80211 msg fails,error.\n");
9093 return err;
9094 }
9095
9096 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9097 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX,
9098 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9099 if (err < 0) {
9100 wifi_debug(DEBUG_ERROR, "GET_STATISTIC_MAX fails,error.\n");
9101 return err;
9102 }
9103
9104 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]) {
9105 p_ap_metric = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]);
9106 if (p_ap_metric) {
9107 memcpy(cb_data->out_buf , &p_ap_metric->cu, sizeof(unsigned char));
9108 }
9109 }
9110 }
9111
9112 return NL_OK;
9113}
9114
developer121a8e72023-05-22 09:19:39 +08009115
9116#define MAX_ACL_DUMP_LEN 4096
9117int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
9118{
9119 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9120 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
developerc14d83a2023-06-29 20:09:42 +08009121 struct genlmsghdr *gnlh;
developer121a8e72023-05-22 09:19:39 +08009122 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08009123 int err = 0;
developer121a8e72023-05-22 09:19:39 +08009124 unsigned short acl_result_len = 0;
9125 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08009126 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08009127 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08009128 return NL_SKIP;
9129 }
developerc14d83a2023-06-29 20:09:42 +08009130
9131 gnlh = nlmsg_data(nlmsg_hdr(msg));
developer121a8e72023-05-22 09:19:39 +08009132 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9133 genlmsg_attrlen(gnlh, 0), NULL);
9134 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08009135 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08009136 return NL_SKIP;
9137 }
developer121a8e72023-05-22 09:19:39 +08009138 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9139 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
9140 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9141 if (err < 0)
9142 return NL_SKIP;
9143 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
9144 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
9145 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
9146 if (acl_result_len > MAX_ACL_DUMP_LEN) {
9147 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
9148 return NL_SKIP;
9149 } else if (*(show_str + acl_result_len - 1) != '\0') {
9150 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
9151 *(show_str + acl_result_len - 1) = '\0';
9152 }
9153 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08009154
9155 if (cb_data->out_len >= acl_result_len) {
9156 memset(cb_data->out_buf, 0, cb_data->out_len);
9157 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
9158 memmove(cb_data->out_buf, show_str, acl_result_len);
9159 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
9160 } else {
9161 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08009162 }
developer121a8e72023-05-22 09:19:39 +08009163 } else
9164 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
9165 } else
9166 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
9167 return NL_OK;
9168}
developer72fb0bb2023-01-11 09:46:29 +08009169// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08009170INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08009171{
developer7e4a2a62023-04-06 19:56:03 +08009172 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08009173 unsigned int if_idx = 0;
9174 int ret = -1;
9175 struct unl unl_ins;
9176 struct nl_msg *msg = NULL;
9177 struct nlattr * msg_data = NULL;
9178 struct mtk_nl80211_param param;
9179 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08009180 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9181 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08009182 if_idx = if_nametoindex(inf_name);
9183 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08009184 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08009185 return RETURN_ERR;
9186 }
9187 /*init mtk nl80211 vendor cmd*/
9188 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9189 param.if_type = NL80211_ATTR_IFINDEX;
9190 param.if_idx = if_idx;
9191
9192 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9193 if (ret) {
9194 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9195 return RETURN_ERR;
9196 }
developer121a8e72023-05-22 09:19:39 +08009197 /*add mtk vendor cmd data*/
9198 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08009199 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08009200 nlmsg_free(msg);
9201 goto err;
9202 }
developer72fb0bb2023-01-11 09:46:29 +08009203
developer121a8e72023-05-22 09:19:39 +08009204 /*send mtk nl80211 vendor msg*/
9205 cb_data.out_buf = macArray;
9206 cb_data.out_len = buf_size;
9207
9208 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
9209 if (ret) {
9210 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9211 goto err;
9212 }
9213 /*deinit mtk nl80211 vendor msg*/
9214 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08009215 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developera3511852023-06-14 14:12:59 +08009216 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08009217err:
9218 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08009219 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08009220 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009221}
9222
developer2edaf012023-05-24 14:24:53 +08009223INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
9224{
9225 char *mac_arry_buf = NULL;
9226
9227 mac_arry_buf = malloc(buf_size);
9228 if (!mac_arry_buf) {
9229 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
9230 return RETURN_ERR;
9231 }
9232 memset(mac_arry_buf, 0, buf_size);
9233 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
9234 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
9235 free(mac_arry_buf);
9236 mac_arry_buf = NULL;
9237 return RETURN_ERR;
9238 }
9239 /*
9240 mtk format to wifi hal format:
9241 "policy=1
9242 00:11:22:33:44:55
9243 00:11:22:33:44:66
9244 "
9245 -->
9246 "00:11:22:33:44:55
9247 00:11:22:33:44:66
9248 "
9249 */
9250 memset(macArray, 0, buf_size);
9251 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
9252 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
9253 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
9254 }
9255 free(mac_arry_buf);
9256 mac_arry_buf = NULL;
9257 return RETURN_OK;
9258}
9259
developer72fb0bb2023-01-11 09:46:29 +08009260INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
9261{
developer72fb0bb2023-01-11 09:46:29 +08009262
developer7e4a2a62023-04-06 19:56:03 +08009263 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08009264
developera3511852023-06-14 14:12:59 +08009265 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009266}
9267
9268
9269// Get the list of stations associated per AP
9270INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
9271{
developer7e4a2a62023-04-06 19:56:03 +08009272 char interface_name[IF_NAME_SIZE] = {0};
9273 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08009274 int res;
developer72fb0bb2023-01-11 09:46:29 +08009275
developer7e4a2a62023-04-06 19:56:03 +08009276 if(apIndex > 3) //Currently supporting apIndex upto 3
developera3511852023-06-14 14:12:59 +08009277 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009278
developer7e4a2a62023-04-06 19:56:03 +08009279 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08009280 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08009281
developere40952c2023-06-15 18:46:43 +08009282 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
9283 if (os_snprintf_error(sizeof(cmd), res)) {
9284 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9285 return RETURN_ERR;
9286 }
developer7e4a2a62023-04-06 19:56:03 +08009287 _syscmd(cmd, macArray, buf_size);
9288 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009289}
9290
developer8dd72532023-05-17 19:58:35 +08009291int hex2num(char c)
9292{
9293 if (c >= '0' && c <= '9')
9294 return c - '0';
9295 if (c >= 'a' && c <= 'f')
9296 return c - 'a' + 10;
9297 if (c >= 'A' && c <= 'F')
9298 return c - 'A' + 10;
9299 return -1;
9300}
9301
9302/**
9303 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
9304 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
9305 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
9306 * Returns: Characters used (> 0) on success, -1 on failure
9307 */
9308int hwaddr_aton2(const char *txt, unsigned char *addr)
9309{
9310 int i;
9311 const char *pos = txt;
9312
9313 for (i = 0; i < 6; i++) {
9314 int a, b;
9315
9316 while (*pos == ':' || *pos == '.' || *pos == '-')
9317 pos++;
9318
9319 a = hex2num(*pos++);
9320 if (a < 0)
9321 return -1;
9322 b = hex2num(*pos++);
9323 if (b < 0)
9324 return -1;
9325 *addr++ = (a << 4) | b;
9326 }
9327
9328 return pos - txt;
9329}
9330
developer72fb0bb2023-01-11 09:46:29 +08009331// adds the mac address to the filter list
9332//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
9333INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
9334{
developer7e4a2a62023-04-06 19:56:03 +08009335 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08009336 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08009337 struct nl_msg *msg = NULL;
9338 struct nlattr * msg_data = NULL;
9339 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08009340 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
9341 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08009342 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9343 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08009344 if (!DeviceMacAddress)
9345 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08009346 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08009347 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08009348 return RETURN_ERR;
9349 }
developer8dd72532023-05-17 19:58:35 +08009350 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08009351 if (!if_idx) {
9352 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9353 return RETURN_ERR;
9354 }
developer49b17232023-05-19 16:35:19 +08009355 /*init mtk nl80211 vendor cmd*/
9356 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9357 param.if_type = NL80211_ATTR_IFINDEX;
9358 param.if_idx = if_idx;
9359 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9360 if (ret) {
9361 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08009362 return RETURN_ERR;
9363 }
developer49b17232023-05-19 16:35:19 +08009364 /*add mtk vendor cmd data*/
9365 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08009366 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08009367 nlmsg_free(msg);
9368 goto err;
9369 }
developer49b17232023-05-19 16:35:19 +08009370 /*send mtk nl80211 vendor msg*/
9371 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9372 if (ret) {
9373 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08009374 goto err;
9375 }
developer49b17232023-05-19 16:35:19 +08009376 /*deinit mtk nl80211 vendor msg*/
9377 mtk_nl80211_deint(&unl_ins);
9378 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08009379 return RETURN_OK;
9380err:
developer49b17232023-05-19 16:35:19 +08009381 mtk_nl80211_deint(&unl_ins);
9382 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08009383 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009384}
9385
9386// deletes the mac address from the filter list
9387//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
9388INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
9389{
developer2edaf012023-05-24 14:24:53 +08009390 struct unl unl_ins;
9391 int if_idx = 0, ret = 0;
9392 struct nl_msg *msg = NULL;
9393 struct nlattr * msg_data = NULL;
9394 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08009395 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08009396 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009397
developer7e4a2a62023-04-06 19:56:03 +08009398 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9399 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009400
developer7e4a2a62023-04-06 19:56:03 +08009401 if (!DeviceMacAddress)
9402 return RETURN_ERR;
9403
developer2edaf012023-05-24 14:24:53 +08009404 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
9405 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
9406 return RETURN_ERR;
9407 }
developer72fb0bb2023-01-11 09:46:29 +08009408
developer2edaf012023-05-24 14:24:53 +08009409 if_idx = if_nametoindex(inf_name);
9410 if (!if_idx) {
9411 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9412 return RETURN_ERR;
9413 }
9414 /*init mtk nl80211 vendor cmd*/
9415 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9416 param.if_type = NL80211_ATTR_IFINDEX;
9417 param.if_idx = if_idx;
9418 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9419 if (ret) {
9420 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9421 return RETURN_ERR;
9422 }
9423 /*add mtk vendor cmd data*/
9424 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
9425 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9426 nlmsg_free(msg);
9427 goto err;
9428 }
9429 /*send mtk nl80211 vendor msg*/
9430 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9431 if (ret) {
9432 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9433 goto err;
9434 }
9435 /*deinit mtk nl80211 vendor msg*/
9436 mtk_nl80211_deint(&unl_ins);
9437 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
9438 return RETURN_OK;
9439err:
9440 mtk_nl80211_deint(&unl_ins);
9441 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9442 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009443}
9444
9445// outputs the number of devices in the filter list
9446INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
9447{
developer2edaf012023-05-24 14:24:53 +08009448 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
9449 UINT buf_size = 1024;
9450 UINT sta_num = 0;
9451 unsigned char mac[ETH_ALEN] = {0};
developera3511852023-06-14 14:12:59 +08009452 if(output_uint == NULL)
developerdaf24792023-06-06 11:40:04 +08009453 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009454
developer2edaf012023-05-24 14:24:53 +08009455 mac_arry = (char *)malloc(buf_size);
9456 if (mac_arry == NULL) {
9457 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08009458 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08009459 }
developerdaf24792023-06-06 11:40:04 +08009460 memset(mac_arry, 0, buf_size);
developer2edaf012023-05-24 14:24:53 +08009461 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
9462 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
9463 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
developer9ce44382023-06-28 11:09:37 +08009464 free(mac_arry);
developer2edaf012023-05-24 14:24:53 +08009465 return RETURN_ERR;
9466 }
9467 /*count the acl str nums:*/
9468 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08009469
developer2edaf012023-05-24 14:24:53 +08009470 /*mac addr string format:
9471 exp1: 00:11:22:33:44:55\0
9472 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
9473 */
9474 ptr = mac_arry;
9475 while (sscanf(ptr, "%17s", mac_str) == 1) {
9476 if (hwaddr_aton2(mac_str, mac) >= 0)
9477 sta_num++;
9478 ptr = strstr(ptr, mac_str) + strlen(mac_str);
9479 }
9480 *output_uint = sta_num;
9481 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
9482 free(mac_arry);
9483 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08009484 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009485}
9486
9487INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
9488{
developera3511852023-06-14 14:12:59 +08009489 char buf[128]={'\0'};
developer75bd10c2023-06-27 11:34:08 +08009490 int res;
developer72fb0bb2023-01-11 09:46:29 +08009491
developera3511852023-06-14 14:12:59 +08009492 if(strcmp(action,"DENY")==0)
9493 {
developer32f2a182023-06-27 19:50:41 +08009494 res = snprintf(buf, sizeof(buf),
9495 "iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",
9496 apIndex, interface, client_mac);
developer75bd10c2023-06-27 11:34:08 +08009497 if (os_snprintf_error(sizeof(buf), res)) {
9498 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9499 return RETURN_ERR;
9500 }
developera3511852023-06-14 14:12:59 +08009501 system(buf);
9502 return RETURN_OK;
9503 }
developer72fb0bb2023-01-11 09:46:29 +08009504
developera3511852023-06-14 14:12:59 +08009505 if(strcmp(action,"ALLOW")==0)
9506 {
developer32f2a182023-06-27 19:50:41 +08009507 res = snprintf(buf, sizeof(buf),
9508 "iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",
9509 apIndex, interface, client_mac);
developer75bd10c2023-06-27 11:34:08 +08009510 if (os_snprintf_error(sizeof(buf), res)) {
9511 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9512 return RETURN_ERR;
9513 }
developera3511852023-06-14 14:12:59 +08009514 system(buf);
9515 return RETURN_OK;
9516 }
developer72fb0bb2023-01-11 09:46:29 +08009517
developera3511852023-06-14 14:12:59 +08009518 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009519
9520}
9521
9522// enable kick for devices on acl black list
9523INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
9524{
developera3511852023-06-14 14:12:59 +08009525 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
9526 char assocArray[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009527
developera3511852023-06-14 14:12:59 +08009528 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
9529 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
developer72fb0bb2023-01-11 09:46:29 +08009530
developera3511852023-06-14 14:12:59 +08009531 /* if there are no devices connected there is nothing to do */
9532 if (strlen(assocArray) < 17)
9533 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009534
developera3511852023-06-14 14:12:59 +08009535 if (enable == TRUE) {
9536 /* kick off the MAC which is in ACL array (deny list) */
9537 acl = strtok(aclArray, "\n");
9538 while (acl != NULL) {
9539 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
9540 wifi_kickApAssociatedDevice(apIndex, acl);
developer72fb0bb2023-01-11 09:46:29 +08009541
developera3511852023-06-14 14:12:59 +08009542 acl = strtok(NULL, "\n");
9543 }
developer72fb0bb2023-01-11 09:46:29 +08009544 wifi_setApMacAddressControlMode(apIndex, 2);
developera3511852023-06-14 14:12:59 +08009545 } else
developer72fb0bb2023-01-11 09:46:29 +08009546 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08009547
developera3511852023-06-14 14:12:59 +08009548 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009549}
9550
9551INT wifi_setPreferPrivateConnection(BOOL enable)
9552{
developera3511852023-06-14 14:12:59 +08009553 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009554}
9555
9556// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
9557INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
9558{
developer2edaf012023-05-24 14:24:53 +08009559 int if_idx = 0, ret = 0;
9560 struct unl unl_ins;
9561 struct nl_msg *msg = NULL;
9562 struct nlattr * msg_data = NULL;
9563 struct mtk_nl80211_param param;
9564 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08009565 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009566
developer7e4a2a62023-04-06 19:56:03 +08009567 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9568 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08009569 if_idx = if_nametoindex(inf_name);
9570 if (!if_idx) {
9571 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9572 return RETURN_ERR;
9573 }
9574 /*init mtk nl80211 vendor cmd*/
9575 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9576 param.if_type = NL80211_ATTR_IFINDEX;
9577 param.if_idx = if_idx;
9578 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9579 if (ret) {
9580 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9581 return RETURN_ERR;
9582 }
9583 /*add mtk vendor cmd data*/
9584 if (filterMode == 0) {
9585 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
9586 } else if (filterMode == 1) {
9587 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
9588 } else if (filterMode == 2) {
9589 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
9590 } else {
9591 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
9592 nlmsg_free(msg);
9593 goto err;
9594 }
9595 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
9596 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9597 nlmsg_free(msg);
9598 goto err;
9599 }
9600 /*send mtk nl80211 vendor msg*/
9601 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9602 if (ret) {
9603 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9604 goto err;
9605 }
9606 /*deinit mtk nl80211 vendor msg*/
9607 mtk_nl80211_deint(&unl_ins);
9608 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08009609 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08009610err:
9611 mtk_nl80211_deint(&unl_ins);
9612 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9613 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009614}
9615
9616// 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.
9617INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
9618{
developera3511852023-06-14 14:12:59 +08009619 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009620}
9621
9622// gets the vlan ID for this ap from an internal enviornment variable
9623INT wifi_getApVlanID(INT apIndex, INT *output_int)
9624{
developera3511852023-06-14 14:12:59 +08009625 if(apIndex==0)
9626 {
9627 *output_int=100;
9628 return RETURN_OK;
9629 }
developer72fb0bb2023-01-11 09:46:29 +08009630
developera3511852023-06-14 14:12:59 +08009631 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009632}
9633
9634// sets the vlan ID for this ap to an internal enviornment variable
9635INT wifi_setApVlanID(INT apIndex, INT vlanId)
9636{
developera3511852023-06-14 14:12:59 +08009637 //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)
developer82533be2023-06-28 17:21:01 +08009638 char interface_name[16] = {0};
9639 int if_idx, ret = 0;
9640 struct nl_msg *msg = NULL;
9641 struct nlattr * msg_data = NULL;
9642 struct mtk_nl80211_param param;
9643 struct unl unl_ins;
9644
9645 if (apIndex > MAX_APS) {
9646 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9647 return RETURN_ERR;
9648 }
9649 if (vlanId > 4095 || vlanId < 1) {
9650 wifi_debug(DEBUG_ERROR, "Invalid vlanId %d\n", vlanId);
9651 return RETURN_ERR;
9652 }
9653 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9654 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9655 return RETURN_ERR;
9656 /*step 1. mwctl dev %s set vlan_tag 0*/
9657 if_idx = if_nametoindex(interface_name);
9658 /*init mtk nl80211 vendor cmd*/
9659 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
9660 param.if_type = NL80211_ATTR_IFINDEX;
9661 param.if_idx = if_idx;
9662 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9663 if (ret) {
9664 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9665 return RETURN_ERR;
9666 }
9667 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, vlanId)) {
9668 printf("Nla put attribute error\n");
9669 nlmsg_free(msg);
9670 goto err;
9671 }
9672 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9673 if (ret) {
9674 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9675 goto err;
9676 }
9677 mtk_nl80211_deint(&unl_ins);
9678 //wifi_debug(DEBUG_NOTICE, "set vlanId cmd success.\n", vlanId);
9679 printf("set vlanId=%d cmd success.\n", vlanId);
9680 return RETURN_OK;
9681err:
9682 mtk_nl80211_deint(&unl_ins);
9683 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08009684 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009685}
9686
developercc5cbfb2023-06-13 18:29:52 +08009687char br_name[IFNAMSIZ] = "brlan0";
9688
developer72fb0bb2023-01-11 09:46:29 +08009689// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
9690INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
9691{
developercc5cbfb2023-06-13 18:29:52 +08009692 int sock = socket(AF_INET, SOCK_DGRAM, 0);
9693 struct ifreq ifr;
9694 struct sockaddr_in *sin;
9695
9696 memcpy(bridgeName, br_name, strlen(br_name));
9697
9698 if (sock == -1) {
9699 wifi_debug(DEBUG_ERROR, "socket failed");
9700 return RETURN_ERR;
9701 }
9702
developerd14dff12023-06-28 22:47:44 +08009703 strncpy(ifr.ifr_name, br_name, strlen(br_name));
developercc5cbfb2023-06-13 18:29:52 +08009704 ifr.ifr_addr.sa_family = AF_INET;
9705 if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
9706 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFADDR) failed, %s, bridge_name=%s\n",
9707 strerror(errno), br_name);
developer9ce44382023-06-28 11:09:37 +08009708 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009709 return RETURN_ERR;
9710 }
9711
9712 sin = (struct sockaddr_in *)&ifr.ifr_addr;
9713 wifi_debug(DEBUG_ERROR, "Bridge device %s has IP address: %s\n", br_name, inet_ntoa(sin->sin_addr));
9714 memcpy(IP, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
9715
9716 if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0) {
9717 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFNETMASK) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009718 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009719 return RETURN_ERR;
9720 }
9721
9722 wifi_debug(DEBUG_ERROR, "Bridge device %s has subnet mask: %s\n", br_name, inet_ntoa(sin->sin_addr));
9723 memcpy(subnet, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
9724 close(sock);
developer72fb0bb2023-01-11 09:46:29 +08009725
developera3511852023-06-14 14:12:59 +08009726 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009727}
9728
9729//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
9730INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
9731{
developera3511852023-06-14 14:12:59 +08009732 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
developercc5cbfb2023-06-13 18:29:52 +08009733 struct ifreq ifr;
9734 struct sockaddr_in sin;
9735 int sock = socket(AF_INET, SOCK_DGRAM, 0);
9736
developerc14d83a2023-06-29 20:09:42 +08009737 if(sock < 0) {
9738 wifi_debug(DEBUG_ERROR, "sock init fail\n");
9739 return RETURN_ERR;
9740 }
9741
developercc5cbfb2023-06-13 18:29:52 +08009742 if (strlen(bridgeName) >= IFNAMSIZ) {
9743 wifi_debug(DEBUG_ERROR, "invalide bridgeName length=%ld\n", strlen(bridgeName));
developer9ce44382023-06-28 11:09:37 +08009744 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009745 return RETURN_ERR;
9746 }
9747
9748 if (strlen(br_name) >= IFNAMSIZ) {
9749 wifi_debug(DEBUG_ERROR, "invalide br_name length=%ld in strorage\n", strlen(br_name));
developer9ce44382023-06-28 11:09:37 +08009750 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009751 return RETURN_ERR;
9752 }
9753
9754 if (sock == -1) {
developera3511852023-06-14 14:12:59 +08009755 wifi_debug(DEBUG_ERROR, "socket failed");
developercc5cbfb2023-06-13 18:29:52 +08009756 return RETURN_ERR;
9757 }
9758
9759 memset(&ifr, 0, sizeof(ifr));
9760 strncpy(ifr.ifr_name, br_name, strlen(br_name));
9761 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
9762 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009763 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009764 return RETURN_ERR;
9765 }
9766
9767 ifr.ifr_flags = (short)(ifr.ifr_flags & ~IFF_UP);
9768 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
9769 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009770 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009771 return RETURN_ERR;
9772 }
9773
9774 memset(&ifr, 0, sizeof(ifr));
9775 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
developerd14dff12023-06-28 22:47:44 +08009776 strncpy(ifr.ifr_newname, bridgeName, strlen(bridgeName));
developercc5cbfb2023-06-13 18:29:52 +08009777 if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
9778 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNAME) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009779 close(sock);
developera3511852023-06-14 14:12:59 +08009780 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009781 }
9782
9783 memset(br_name, 0, sizeof(br_name));
9784 memcpy(br_name, bridgeName, strlen(bridgeName));
9785
9786 memset(&ifr, 0, sizeof(ifr));
9787 strncpy(ifr.ifr_name, bridgeName, IFNAMSIZ);
9788 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
9789 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009790 close(sock);
developera3511852023-06-14 14:12:59 +08009791 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009792 }
9793 ifr.ifr_flags = (short)(ifr.ifr_flags | IFF_UP);
9794 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
9795 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009796 close(sock);
developera3511852023-06-14 14:12:59 +08009797 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009798 }
9799
9800 memset(&ifr, 0, sizeof(ifr));
9801 memcpy(ifr.ifr_name, bridgeName, strlen(bridgeName));
9802
9803 memset(&sin, 0, sizeof(struct sockaddr_in));
9804 sin.sin_family = AF_INET;
9805 if (inet_aton(IP, &(sin.sin_addr)) == 0) {
9806 wifi_debug(DEBUG_ERROR, "inet_aton failed");
developer9ce44382023-06-28 11:09:37 +08009807 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009808 return RETURN_ERR;
9809 }
9810 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in));
9811 if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
9812 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFADDR) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009813 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009814 return RETURN_ERR;
9815 }
9816
9817 if (inet_aton(subnet, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr) == 0) {
9818 wifi_debug(DEBUG_ERROR, "inet_aton failed");
developerc14d83a2023-06-29 20:09:42 +08009819 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009820 return RETURN_ERR;
9821 }
9822 if (ioctl(sock, SIOCSIFNETMASK, &ifr) < -1) {
9823 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNETMASK) failed, %s", strerror(errno));
developerc14d83a2023-06-29 20:09:42 +08009824 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009825 return RETURN_ERR;
9826 }
9827
9828 close(sock);
developera3511852023-06-14 14:12:59 +08009829 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009830}
9831
9832// reset the vlan configuration for this ap
9833INT wifi_resetApVlanCfg(INT apIndex)
9834{
developera1255e42023-05-13 17:45:02 +08009835 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08009836 int if_idx, ret = 0;
9837 struct nl_msg *msg = NULL;
9838 struct nlattr * msg_data = NULL;
9839 struct mtk_nl80211_param param;
9840 struct unl unl_ins;
9841 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08009842
developer2202b332023-05-24 16:23:22 +08009843 if (apIndex > MAX_APS) {
9844 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9845 return RETURN_ERR;
9846 }
developer72fb0bb2023-01-11 09:46:29 +08009847
developer2202b332023-05-24 16:23:22 +08009848 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9849 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9850 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009851
developer2202b332023-05-24 16:23:22 +08009852 /*step 1. mwctl dev %s set vlan_tag 0*/
9853 if_idx = if_nametoindex(interface_name);
9854 /*init mtk nl80211 vendor cmd*/
9855 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
9856 param.if_type = NL80211_ATTR_IFINDEX;
9857 param.if_idx = if_idx;
9858 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08009859
developer2202b332023-05-24 16:23:22 +08009860 if (ret) {
9861 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9862 return RETURN_ERR;
9863 }
developer72fb0bb2023-01-11 09:46:29 +08009864
developer2202b332023-05-24 16:23:22 +08009865 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
9866 printf("Nla put attribute error\n");
9867 nlmsg_free(msg);
9868 goto err;
9869 }
developer72fb0bb2023-01-11 09:46:29 +08009870
developer2202b332023-05-24 16:23:22 +08009871 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9872 if (ret) {
9873 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9874 goto err;
9875 }
9876 mtk_nl80211_deint(&unl_ins);
9877 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08009878
developer2202b332023-05-24 16:23:22 +08009879 /*step 2. mwctl dev %s set vlan_priority 0*/
9880 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9881 if (ret) {
9882 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9883 return RETURN_ERR;
9884 }
developer72fb0bb2023-01-11 09:46:29 +08009885
developer2202b332023-05-24 16:23:22 +08009886 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
9887 printf("Nla put attribute error\n");
9888 nlmsg_free(msg);
9889 goto err;
9890 }
developer72fb0bb2023-01-11 09:46:29 +08009891
developer2202b332023-05-24 16:23:22 +08009892 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9893 if (ret) {
9894 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9895 goto err;
9896 }
9897 mtk_nl80211_deint(&unl_ins);
9898 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
9899
9900 /*step 3. mwctl dev %s set vlan_id 0*/
9901 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9902 if (ret) {
9903 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08009904 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08009905 }
developer72fb0bb2023-01-11 09:46:29 +08009906
developer2202b332023-05-24 16:23:22 +08009907 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
9908 printf("Nla put attribute error\n");
9909 nlmsg_free(msg);
9910 goto err;
9911 }
9912
9913 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9914 if (ret) {
9915 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9916 goto err;
9917 }
9918 mtk_nl80211_deint(&unl_ins);
9919 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
9920
9921 /*step 4. mwctl dev %s set vlan_en 0*/
9922 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9923 if (ret) {
9924 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9925 return RETURN_ERR;
9926 }
9927
9928 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
9929 printf("Nla put attribute error\n");
9930 nlmsg_free(msg);
9931 goto err;
9932 }
9933
9934 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9935 if (ret) {
9936 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9937 goto err;
9938 }
9939 mtk_nl80211_deint(&unl_ins);
9940 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
9941
9942 /*step 5. mwctl dev %s set vlan_policy 0:4*/
9943 vlan_param.direction = 0;
9944 vlan_param.policy = 4;
9945 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9946 if (ret) {
9947 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9948 return RETURN_ERR;
9949 }
9950 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
9951 printf("Nla put attribute error\n");
9952 nlmsg_free(msg);
9953 goto err;
9954 }
9955
9956 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9957 if (ret) {
9958 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9959 goto err;
9960 }
9961 mtk_nl80211_deint(&unl_ins);
9962 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
9963
9964 /*step 6. mwctl dev %s set vlan_policy 1:0*/
9965 vlan_param.direction = 1;
9966 vlan_param.policy = 0;
9967 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9968 if (ret) {
9969 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9970 return RETURN_ERR;
9971 }
9972
9973 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
9974 printf("Nla put attribute error\n");
9975 nlmsg_free(msg);
9976 goto err;
9977 }
9978
9979 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9980 if (ret) {
9981 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9982 goto err;
9983 }
9984 /*deinit mtk nl80211 vendor msg*/
9985 mtk_nl80211_deint(&unl_ins);
9986 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
9987
9988 /*TODO need to modify VLAN config in dat file*/
9989 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9990
9991 return RETURN_OK;
9992err:
9993 mtk_nl80211_deint(&unl_ins);
9994 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9995 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009996}
9997
9998// 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.
9999INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
10000{
developera3511852023-06-14 14:12:59 +080010001 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010002}
10003
10004// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
10005INT wifi_startHostApd()
10006{
developera3511852023-06-14 14:12:59 +080010007 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10008 system("systemctl start hostapd.service");
10009 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10010 return RETURN_OK;
10011 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
developer72fb0bb2023-01-11 09:46:29 +080010012}
10013
10014// stops hostapd
developer69b61b02023-03-07 17:17:44 +080010015INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +080010016{
developera3511852023-06-14 14:12:59 +080010017 char cmd[128] = {0};
10018 char buf[128] = {0};
developer75bd10c2023-06-27 11:34:08 +080010019 int res;
developer72fb0bb2023-01-11 09:46:29 +080010020
developer75bd10c2023-06-27 11:34:08 +080010021 res = snprintf(cmd, sizeof(cmd), "systemctl stop hostapd");
10022 if (os_snprintf_error(sizeof(cmd), res)) {
10023 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10024 return RETURN_ERR;
10025 }
developera3511852023-06-14 14:12:59 +080010026 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010027
developera3511852023-06-14 14:12:59 +080010028 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010029}
10030
10031// restart hostapd dummy function
10032INT wifi_restartHostApd()
10033{
developera3511852023-06-14 14:12:59 +080010034 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10035 system("systemctl restart hostapd-global");
10036 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010037
developera3511852023-06-14 14:12:59 +080010038 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010039}
10040
10041// sets the AP enable status variable for the specified ap.
10042INT wifi_setApEnable(INT apIndex, BOOL enable)
10043{
developer7e4a2a62023-04-06 19:56:03 +080010044 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080010045 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +080010046 char cmd[MAX_CMD_SIZE] = {0};
10047 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +080010048 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +080010049 int max_radio_num = 0;
10050 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080010051 int res;
developer72fb0bb2023-01-11 09:46:29 +080010052
developer7e4a2a62023-04-06 19:56:03 +080010053 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +080010054
developer7e4a2a62023-04-06 19:56:03 +080010055 wifi_getMaxRadioNumber(&max_radio_num);
10056 if (enable == status)
10057 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010058
developer7e4a2a62023-04-06 19:56:03 +080010059 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10060 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010061
developer7e4a2a62023-04-06 19:56:03 +080010062 if (enable == TRUE) {
10063 int radioIndex = apIndex % max_radio_num;
10064 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +080010065 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
10066 if (os_snprintf_error(sizeof(cmd), res)) {
10067 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10068 return RETURN_ERR;
10069 }
developerf3c7d292023-05-29 17:57:16 +080010070 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +080010071
developere40952c2023-06-15 18:46:43 +080010072 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
10073 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
10074 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10075 return RETURN_ERR;
10076 }
10077 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
10078 if (os_snprintf_error(sizeof(cmd), res)) {
10079 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10080 return RETURN_ERR;
10081 }
developer7e4a2a62023-04-06 19:56:03 +080010082 _syscmd(cmd, buf, sizeof(buf));
10083 } else {
developere40952c2023-06-15 18:46:43 +080010084 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
10085 if (os_snprintf_error(sizeof(cmd), res)) {
10086 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10087 return RETURN_ERR;
10088 }
developer7e4a2a62023-04-06 19:56:03 +080010089 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +080010090 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
10091 if (os_snprintf_error(sizeof(cmd), res)) {
10092 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10093 return RETURN_ERR;
10094 }
developerf3c7d292023-05-29 17:57:16 +080010095 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +080010096 }
developere40952c2023-06-15 18:46:43 +080010097 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer7e4a2a62023-04-06 19:56:03 +080010098 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +080010099 if (os_snprintf_error(sizeof(cmd), res)) {
10100 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10101 return RETURN_ERR;
10102 }
developer7e4a2a62023-04-06 19:56:03 +080010103 _syscmd(cmd, buf, sizeof(buf));
10104 //Wait for wifi up/down to apply
10105 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010106}
10107
10108// Outputs the setting of the internal variable that is set by wifi_setApEnable().
10109INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
10110{
developer7e4a2a62023-04-06 19:56:03 +080010111 char interface_name[IF_NAME_SIZE] = {0};
10112 char cmd[MAX_CMD_SIZE] = {0};
developerc1aa6532023-06-09 09:37:01 +080010113 char buf[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080010114 int res;
developer72fb0bb2023-01-11 09:46:29 +080010115
developer7e4a2a62023-04-06 19:56:03 +080010116 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
10117 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010118
developer7e4a2a62023-04-06 19:56:03 +080010119 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +080010120
developer7e4a2a62023-04-06 19:56:03 +080010121 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
10122 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
10123 *output_bool = FALSE;
10124 return RETURN_OK;
10125 }
developerc1aa6532023-06-09 09:37:01 +080010126
developer75bd10c2023-06-27 11:34:08 +080010127 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
10128 if (os_snprintf_error(sizeof(cmd), res)) {
10129 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10130 return RETURN_ERR;
10131 }
developerc1aa6532023-06-09 09:37:01 +080010132 _syscmd(cmd, buf, sizeof(buf));
10133
10134 if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 ||
10135 strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) {
10136 *output_bool = TRUE;
10137 }
developer7e4a2a62023-04-06 19:56:03 +080010138 }
developer72fb0bb2023-01-11 09:46:29 +080010139
developer7e4a2a62023-04-06 19:56:03 +080010140 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010141}
10142
developer69b61b02023-03-07 17:17:44 +080010143// Outputs the AP "Enabled" "Disabled" status from driver
10144INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +080010145{
developer9ce44382023-06-28 11:09:37 +080010146 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +080010147 int res;
developer72fb0bb2023-01-11 09:46:29 +080010148
developer7e4a2a62023-04-06 19:56:03 +080010149 if (!output_string) {
10150 printf("%s: null pointer!", __func__);
10151 return RETURN_ERR;
10152 }
developer72fb0bb2023-01-11 09:46:29 +080010153
developer7e4a2a62023-04-06 19:56:03 +080010154 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +080010155
developer7e4a2a62023-04-06 19:56:03 +080010156 if(output_bool == 1)
developere40952c2023-06-15 18:46:43 +080010157 res = snprintf(output_string, 32, "Up");
developer7e4a2a62023-04-06 19:56:03 +080010158 else
developere40952c2023-06-15 18:46:43 +080010159 res = snprintf(output_string, 32, "Disable");
10160 if (os_snprintf_error(32, res)) {
10161 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10162 return RETURN_ERR;
10163 }
developer7e4a2a62023-04-06 19:56:03 +080010164
10165 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010166}
10167
10168//Indicates whether or not beacons include the SSID name.
10169// outputs a 1 if SSID on the AP is enabled, else outputs 0
10170INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
10171{
developera3511852023-06-14 14:12:59 +080010172 //get the running status
10173 char config_file[MAX_BUF_SIZE] = {0};
10174 char buf[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080010175 int res;
developer72fb0bb2023-01-11 09:46:29 +080010176
developera3511852023-06-14 14:12:59 +080010177 if (!output)
10178 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010179
developer32f2a182023-06-27 19:50:41 +080010180 res = snprintf(config_file, sizeof(config_file),
10181 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010182 if (os_snprintf_error(sizeof(config_file), res)) {
10183 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10184 return RETURN_ERR;
10185 }
developera3511852023-06-14 14:12:59 +080010186 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
10187 // default is enable
10188 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
10189 *output = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080010190
developera3511852023-06-14 14:12:59 +080010191 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010192}
10193
10194// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
10195INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
10196{
developera3511852023-06-14 14:12:59 +080010197 //store the config, apply instantly
10198 char config_file[MAX_BUF_SIZE] = {0};
10199 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010200 int res;
developer72fb0bb2023-01-11 09:46:29 +080010201
developera3511852023-06-14 14:12:59 +080010202 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10203 list.name = "ignore_broadcast_ssid";
10204 list.value = enable?"0":"1";
developer72fb0bb2023-01-11 09:46:29 +080010205
developer32f2a182023-06-27 19:50:41 +080010206 res = snprintf(config_file, sizeof(config_file),
10207 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010208 if (os_snprintf_error(sizeof(config_file), res)) {
10209 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10210 return RETURN_ERR;
10211 }
developera3511852023-06-14 14:12:59 +080010212 wifi_hostapdWrite(config_file, &list, 1);
10213 wifi_hostapdProcessUpdate(apIndex, &list, 1);
10214 //TODO: call hostapd_cli for dynamic_config_control
10215 wifi_reloadAp(apIndex);
10216 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010217
developera3511852023-06-14 14:12:59 +080010218 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010219}
10220
10221//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
10222INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
10223{
developer47cc27a2023-05-17 23:09:58 +080010224 /* get the running status */
10225 if(!output_uint)
developera3511852023-06-14 14:12:59 +080010226 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +080010227
10228 *output_uint = 15;
10229 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010230}
10231
developer47cc27a2023-05-17 23:09:58 +080010232/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +080010233INT wifi_setApRetryLimit(INT apIndex, UINT number)
10234{
developer47cc27a2023-05-17 23:09:58 +080010235 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010236}
10237
developer95c045d2023-05-24 19:26:28 +080010238int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
10239{
10240 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10241 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
10242 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developer2f79c922023-06-02 17:33:42 +080010243 unsigned char *status = (unsigned char *)data;
developer95c045d2023-05-24 19:26:28 +080010244 int err = 0;
developer95c045d2023-05-24 19:26:28 +080010245
10246 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10247 genlmsg_attrlen(gnlh, 0), NULL);
10248 if (err < 0)
10249 return err;
10250
10251 if (tb[NL80211_ATTR_VENDOR_DATA]) {
10252 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
10253 tb[NL80211_ATTR_VENDOR_DATA], NULL);
10254 if (err < 0)
10255 return err;
10256
10257 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
developer95c045d2023-05-24 19:26:28 +080010258 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
10259 }
10260 }
10261
10262 return 0;
10263}
10264
developer72fb0bb2023-01-11 09:46:29 +080010265//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
10266INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
10267{
developer95c045d2023-05-24 19:26:28 +080010268 int if_idx, ret = 0;
developera3511852023-06-14 14:12:59 +080010269 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080010270 unsigned char status = 0;
10271 struct nl_msg *msg = NULL;
10272 struct nlattr * msg_data = NULL;
10273 struct mtk_nl80211_param param;
10274 struct unl unl_ins;
developer8e6583c2023-05-23 13:36:06 +080010275
developera3511852023-06-14 14:12:59 +080010276 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10277 if(!output)
developerdaf24792023-06-06 11:40:04 +080010278 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080010279
developer95c045d2023-05-24 19:26:28 +080010280 if (apIndex > MAX_APS) {
10281 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
10282 return RETURN_ERR;
10283 }
10284
developera3511852023-06-14 14:12:59 +080010285 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developerdaf24792023-06-06 11:40:04 +080010286 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +080010287
10288 if_idx = if_nametoindex(interface_name);
10289 /*init mtk nl80211 vendor cmd*/
10290 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
10291 param.if_type = NL80211_ATTR_IFINDEX;
10292 param.if_idx = if_idx;
10293 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10294
10295 if (ret) {
10296 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10297 return RETURN_ERR;
10298 }
10299
10300 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
10301 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
10302 nlmsg_free(msg);
10303 goto err;
10304 }
10305
10306 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
10307 (void *)&status);
10308 if (ret) {
10309 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
10310 goto err;
10311 }
10312 mtk_nl80211_deint(&unl_ins);
10313
10314 *output = status == 0 ? FALSE : TRUE;
10315 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +080010316
developera3511852023-06-14 14:12:59 +080010317 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10318 return RETURN_OK;
10319err:
developer95c045d2023-05-24 19:26:28 +080010320 mtk_nl80211_deint(&unl_ins);
10321 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
10322 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010323}
10324
10325//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
10326INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
10327{
developera3511852023-06-14 14:12:59 +080010328 //get the running status from driver
10329 char cmd[128] = {0};
10330 char buf[128] = {0};
10331 int max_radio_num = 0, radioIndex = 0;
10332 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080010333 int res;
developer72fb0bb2023-01-11 09:46:29 +080010334
developera3511852023-06-14 14:12:59 +080010335 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010336
developera3511852023-06-14 14:12:59 +080010337 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080010338 if(max_radio_num == 0){
10339 return RETURN_ERR;
10340 }
developera3511852023-06-14 14:12:59 +080010341 radioIndex = apIndex % max_radio_num;
10342 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +080010343 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
10344 if (os_snprintf_error(sizeof(cmd), res)) {
10345 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10346 return RETURN_ERR;
10347 }
developera3511852023-06-14 14:12:59 +080010348 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010349
developera3511852023-06-14 14:12:59 +080010350 if (strlen(buf) > 0)
10351 *output = true;
developer72fb0bb2023-01-11 09:46:29 +080010352
developera3511852023-06-14 14:12:59 +080010353 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010354
developera3511852023-06-14 14:12:59 +080010355 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010356}
10357
10358//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
10359INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
10360{
developera3511852023-06-14 14:12:59 +080010361 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +080010362}
10363
10364// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
10365INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
10366{
developer95c045d2023-05-24 19:26:28 +080010367 int if_idx, ret = 0;
10368 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080010369 struct nl_msg *msg = NULL;
10370 struct nlattr * msg_data = NULL;
10371 struct mtk_nl80211_param param;
10372 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +080010373
developer95c045d2023-05-24 19:26:28 +080010374 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010375
developer95c045d2023-05-24 19:26:28 +080010376 if (apIndex > MAX_APS) {
10377 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
10378 return RETURN_ERR;
10379 }
developer72fb0bb2023-01-11 09:46:29 +080010380
developer95c045d2023-05-24 19:26:28 +080010381 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10382 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080010383
developer95c045d2023-05-24 19:26:28 +080010384 if_idx = if_nametoindex(interface_name);
10385 /*init mtk nl80211 vendor cmd*/
10386 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
10387 param.if_type = NL80211_ATTR_IFINDEX;
10388 param.if_idx = if_idx;
10389 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10390
10391 if (ret) {
10392 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10393 return RETURN_ERR;
10394 }
10395
10396 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
10397 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
10398 nlmsg_free(msg);
10399 goto err;
10400 }
10401
10402 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
10403 if (ret) {
10404 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
10405 goto err;
10406 }
10407 mtk_nl80211_deint(&unl_ins);
10408
10409 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10410 return RETURN_OK;
10411err:
10412 mtk_nl80211_deint(&unl_ins);
10413 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
10414 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010415}
10416
developer95c045d2023-05-24 19:26:28 +080010417
developer72fb0bb2023-01-11 09:46:29 +080010418//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.
10419INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
10420{
developer75bd10c2023-06-27 11:34:08 +080010421 int res;
10422
developera3511852023-06-14 14:12:59 +080010423 //get the running status from driver
10424 if(!output)
10425 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010426
developera3511852023-06-14 14:12:59 +080010427 char config_file[128] = {0};
10428 char buf[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010429
developer75bd10c2023-06-27 11:34:08 +080010430 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10431 if (os_snprintf_error(sizeof(config_file), res)) {
10432 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10433 return RETURN_ERR;
10434 }
developera3511852023-06-14 14:12:59 +080010435 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
10436 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
10437 *output = TRUE;
10438 else
10439 *output = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010440
developera3511852023-06-14 14:12:59 +080010441 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010442}
10443
10444// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
10445INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
10446{
developera3511852023-06-14 14:12:59 +080010447 //save config and apply instantly.
10448 char config_file[MAX_BUF_SIZE] = {0};
10449 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010450 int res;
developer72fb0bb2023-01-11 09:46:29 +080010451
developera3511852023-06-14 14:12:59 +080010452 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10453 list.name = "uapsd_advertisement_enabled";
10454 list.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080010455
developer75bd10c2023-06-27 11:34:08 +080010456 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10457 if (os_snprintf_error(sizeof(config_file), res)) {
10458 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10459 return RETURN_ERR;
10460 }
developera3511852023-06-14 14:12:59 +080010461 wifi_hostapdWrite(config_file, &list, 1);
10462 wifi_hostapdProcessUpdate(apIndex, &list, 1);
10463 wifi_quick_reload_ap(apIndex);
10464 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010465
developera3511852023-06-14 14:12:59 +080010466 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010467}
10468
10469// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
10470INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
10471{
developera3511852023-06-14 14:12:59 +080010472 char interface_name[16] = {0};
10473 // assume class 0->BE, 1->BK, 2->VI, 3->VO
10474 char cmd[MAX_CMD_SIZE] = {0};
10475 char buf[128] = {0};
10476 char ack_filepath[128] = {0};
10477 uint16_t bitmap = 0;
10478 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
10479 FILE *f = NULL;
developere40952c2023-06-15 18:46:43 +080010480 int res;
developerc14d83a2023-06-29 20:09:42 +080010481 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080010482
developera3511852023-06-14 14:12:59 +080010483 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010484
developera3511852023-06-14 14:12:59 +080010485 // Get current setting
developere40952c2023-06-15 18:46:43 +080010486 res = snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
10487 if (os_snprintf_error(sizeof(ack_filepath), res)) {
10488 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10489 return RETURN_ERR;
10490 }
10491 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
10492 if (os_snprintf_error(sizeof(cmd), res)) {
10493 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10494 return RETURN_ERR;
10495 }
developera3511852023-06-14 14:12:59 +080010496 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +080010497 if (strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +080010498 if (hal_strtoul(buf, 10, &tmp) < 0) {
10499 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080010500 }
developerc14d83a2023-06-29 20:09:42 +080010501 bitmap = tmp;
developerd14dff12023-06-28 22:47:44 +080010502 }
developer72fb0bb2023-01-11 09:46:29 +080010503
developera3511852023-06-14 14:12:59 +080010504 if (ackPolicy == TRUE) { // True, unset this class
10505 bitmap &= ~class_map[class];
10506 } else { // False, set this class
10507 bitmap |= class_map[class];
10508 }
developer72fb0bb2023-01-11 09:46:29 +080010509
developera3511852023-06-14 14:12:59 +080010510 f = fopen(ack_filepath, "w");
10511 if (f == NULL) {
developer37646972023-06-29 10:58:43 +080010512 if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
10513 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +080010514 return RETURN_ERR;
10515 }
developer37646972023-06-29 10:58:43 +080010516 if (fprintf(f, "%hu", bitmap) < 0)
10517 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
10518
10519 if (fclose(f) == EOF) {
10520 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
10521 return RETURN_ERR;
10522 }
developer72fb0bb2023-01-11 09:46:29 +080010523
developera3511852023-06-14 14:12:59 +080010524 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10525 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010526 res = snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
10527 if (os_snprintf_error(sizeof(cmd), res)) {
10528 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10529 return RETURN_ERR;
10530 }
developera3511852023-06-14 14:12:59 +080010531 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010532
developera3511852023-06-14 14:12:59 +080010533 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10534 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010535}
10536
10537//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.
10538INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
10539{
developer75bd10c2023-06-27 11:34:08 +080010540 int res;
10541
developera3511852023-06-14 14:12:59 +080010542 //get the running status from driver
10543 if(!output_uint)
10544 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010545
developera3511852023-06-14 14:12:59 +080010546 char output[16]={'\0'};
10547 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010548
developer75bd10c2023-06-27 11:34:08 +080010549 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10550 if (os_snprintf_error(sizeof(config_file), res)) {
10551 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10552 return RETURN_ERR;
10553 }
developera3511852023-06-14 14:12:59 +080010554 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
10555 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
10556 else {
10557 int device_num = atoi(output);
10558 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
10559 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
10560 return RETURN_ERR;
10561 }
10562 else {
10563 *output_uint = device_num;
10564 }
10565 }
developer72fb0bb2023-01-11 09:46:29 +080010566
developera3511852023-06-14 14:12:59 +080010567 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010568}
10569
10570INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
10571{
developera3511852023-06-14 14:12:59 +080010572 //store to wifi config, apply instantly
10573 char str[MAX_BUF_SIZE]={'\0'};
10574 struct params params;
10575 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080010576 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080010577
developera3511852023-06-14 14:12:59 +080010578 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10579 if (number > MAX_ASSOCIATED_STA_NUM) {
10580 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
10581 return RETURN_ERR;
10582 }
developer75bd10c2023-06-27 11:34:08 +080010583 res = snprintf(str, sizeof(str), "%d", number);
10584 if (os_snprintf_error(sizeof(str), res)) {
10585 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10586 return RETURN_ERR;
10587 }
developera3511852023-06-14 14:12:59 +080010588 params.name = "max_num_sta";
10589 params.value = str;
developer72fb0bb2023-01-11 09:46:29 +080010590
developer32f2a182023-06-27 19:50:41 +080010591 res = snprintf(config_file,
10592 sizeof(config_file), "%s%d.conf",CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010593 if (os_snprintf_error(sizeof(config_file), res)) {
10594 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10595 return RETURN_ERR;
10596 }
developer32f2a182023-06-27 19:50:41 +080010597 ret = wifi_hostapdWrite(config_file, &params, 1);
developera3511852023-06-14 14:12:59 +080010598 if (ret) {
10599 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
10600 ,__func__, ret);
10601 }
developer72fb0bb2023-01-11 09:46:29 +080010602
developera3511852023-06-14 14:12:59 +080010603 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
10604 if (ret) {
10605 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
10606 ,__func__, ret);
10607 }
10608 wifi_reloadAp(apIndex);
10609 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010610
developera3511852023-06-14 14:12:59 +080010611 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010612}
10613
10614//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.
10615INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
10616{
developera3511852023-06-14 14:12:59 +080010617 //get the current threshold
10618 if(!output_uint)
10619 return RETURN_ERR;
10620 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
10621 if (*output_uint == 0)
10622 *output_uint = 50;
10623 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010624}
10625
10626INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
10627{
developera3511852023-06-14 14:12:59 +080010628 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
10629 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
10630 return RETURN_OK;
10631 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010632}
10633
10634//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.
10635INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
10636{
developera3511852023-06-14 14:12:59 +080010637 if(!output_uint)
10638 return RETURN_ERR;
10639 *output_uint = 3;
10640 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010641}
10642
10643//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
10644INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
10645{
developera3511852023-06-14 14:12:59 +080010646 if(!output_uint)
10647 return RETURN_ERR;
10648 *output_uint = 3;
10649 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010650}
10651
10652//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.
10653INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
10654{
developera3511852023-06-14 14:12:59 +080010655 if(!output_in_seconds)
10656 return RETURN_ERR;
10657 *output_in_seconds = 0;
10658 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010659}
10660
10661//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
10662INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
10663{
developere40952c2023-06-15 18:46:43 +080010664 int res;
10665
developera3511852023-06-14 14:12:59 +080010666 if(!output || apIndex>=MAX_APS)
10667 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010668 //res = snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
10669 res = snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
10670 if (os_snprintf_error(128, res)) {
10671 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10672 return RETURN_ERR;
10673 }
developera3511852023-06-14 14:12:59 +080010674 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080010675}
developer72fb0bb2023-01-11 09:46:29 +080010676
10677//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
10678INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
10679{
developera3511852023-06-14 14:12:59 +080010680 char config_file[128] = {0};
10681 char wpa[16] = {0};
10682 char key_mgmt[64] = {0};
developer9ce44382023-06-28 11:09:37 +080010683 int res = -1;
developere40952c2023-06-15 18:46:43 +080010684
developera3511852023-06-14 14:12:59 +080010685 if (!output)
10686 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010687
developer75bd10c2023-06-27 11:34:08 +080010688 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10689 if (os_snprintf_error(sizeof(config_file), res)) {
10690 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10691 return RETURN_ERR;
10692 }
developera3511852023-06-14 14:12:59 +080010693 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
developer72fb0bb2023-01-11 09:46:29 +080010694
developer32f2a182023-06-27 19:50:41 +080010695 memcpy(output, "None", 4);//Copying "None" to output string for default case
10696 output[4] = '\0';
developera3511852023-06-14 14:12:59 +080010697 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
10698 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
10699 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080010700 res = snprintf(output, 32, "WPA-Personal");
developera3511852023-06-14 14:12:59 +080010701 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080010702 res = snprintf(output, 32, "WPA2-Personal");
developera3511852023-06-14 14:12:59 +080010703 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080010704 res = snprintf(output, 32, "WPA-WPA2-Personal");
developer72fb0bb2023-01-11 09:46:29 +080010705
developera3511852023-06-14 14:12:59 +080010706 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
developere40952c2023-06-15 18:46:43 +080010707 res = snprintf(output, 32, "WPA3-Enterprise");
developera3511852023-06-14 14:12:59 +080010708 } else if (strstr(key_mgmt, "WPA-EAP")) {
10709 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080010710 res = snprintf(output, 32, "WPA-Enterprise");
developera3511852023-06-14 14:12:59 +080010711 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080010712 res = snprintf(output, 32, "WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080010713 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080010714 res = snprintf(output, 32, "WPA-WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080010715 } else if (strstr(key_mgmt, "SAE")) {
10716 if (strstr(key_mgmt, "WPA-PSK") == NULL)
developere40952c2023-06-15 18:46:43 +080010717 res = snprintf(output, 32, "WPA3-Personal");
developera3511852023-06-14 14:12:59 +080010718 else
developere40952c2023-06-15 18:46:43 +080010719 res = snprintf(output, 32, "WPA3-Personal-Transition");
10720 }
10721 if (os_snprintf_error(32, res)) {
10722 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10723 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080010724 }
developer72fb0bb2023-01-11 09:46:29 +080010725
developera3511852023-06-14 14:12:59 +080010726 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
10727 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010728}
developer69b61b02023-03-07 17:17:44 +080010729
developer72fb0bb2023-01-11 09:46:29 +080010730INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
10731{
developer32f2a182023-06-27 19:50:41 +080010732 char securityType[32] = {0};
10733 char authMode[32] = {0};
10734 unsigned long len_sec, len_auth;
developera3511852023-06-14 14:12:59 +080010735 //store settings and wait for wifi up to apply
10736 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10737 if(!encMode)
10738 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010739
developera3511852023-06-14 14:12:59 +080010740 if (strcmp(encMode, "None")==0)
10741 {
developer32f2a182023-06-27 19:50:41 +080010742 len_sec = strlen("None");
10743 len_auth = strlen("None");
10744 memcpy(securityType, "None", len_sec);
10745 memcpy(authMode, "None", len_auth);
10746 } else if (strcmp(encMode, "WPA-WPA2-Personal")==0) {
10747 len_sec = strlen("WPAand11i");
10748 memcpy(securityType, "WPAand11i", len_sec);
10749 len_auth = strlen("PSKAuthentication");
10750 memcpy(authMode, "PSKAuthentication", len_auth);
10751 } else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) {
10752 len_sec = strlen("WPAand11i");
10753 memcpy(securityType, "WPAand11i", len_sec);
10754 len_auth = strlen("EAPAuthentication");
10755 memcpy(authMode, "EAPAuthentication", len_auth);
10756 } else if (strcmp(encMode, "WPA-Personal")==0) {
10757 len_sec = strlen("WPA");
10758 memcpy(securityType, "WPA", len_sec);
10759 len_auth = strlen("PSKAuthentication");
10760 memcpy(authMode, "PSKAuthentication", len_auth);
10761 } else if (strcmp(encMode, "WPA-Enterprise")==0) {
10762 len_sec = strlen("WPA");
10763 memcpy(securityType, "WPA", len_sec);
10764 len_auth = strlen("EAPAuthentication");
10765 memcpy(authMode, "EAPAuthentication", len_auth);
10766 } else if (strcmp(encMode, "WPA2-Personal")==0) {
10767 len_sec = strlen("11i");
10768 memcpy(securityType, "11i", len_sec);
10769 len_auth = strlen("PSKAuthentication");
10770 memcpy(authMode, "PSKAuthentication", len_auth);
10771 } else if (strcmp(encMode, "WPA2-Enterprise")==0) {
10772 len_sec = strlen("11i");
10773 memcpy(securityType, "11i", len_sec);
10774 len_auth = strlen("EAPAuthentication");
10775 memcpy(authMode, "EAPAuthentication", len_auth);
10776 } else if (strcmp(encMode, "WPA3-Personal") == 0) {
10777 len_sec = strlen("11i");
10778 memcpy(securityType, "11i", len_sec);
10779 len_auth = strlen("SAEAuthentication");
10780 memcpy(authMode, "SAEAuthentication", len_auth);
10781 } else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) {
10782 len_sec = strlen("11i");
10783 memcpy(securityType, "11i", len_sec);
10784 len_auth = strlen("PSK-SAEAuthentication");
10785 memcpy(authMode, "PSK-SAEAuthentication", len_auth);
10786 } else if (strcmp(encMode, "WPA3-Enterprise") == 0) {
10787 len_sec = strlen("11i");
10788 memcpy(securityType, "11i", len_sec);
10789 len_auth = strlen("EAP_192-bit_Authentication");
10790 memcpy(authMode, "EAP_192-bit_Authentication", len_auth);
10791 } else if (strcmp(encMode, "OWE") == 0) {
10792 len_sec = strlen("11i");
10793 memcpy(securityType, "11i", len_sec);
10794 len_auth = strlen("Enhanced_Open");
10795 memcpy(authMode, "Enhanced_Open", len_auth);
10796 } else {
10797 len_sec = strlen("None");
10798 memcpy(securityType, "None", len_sec);
10799 len_auth = strlen("None");
10800 memcpy(authMode, "None", len_auth);
developera3511852023-06-14 14:12:59 +080010801 }
developer32f2a182023-06-27 19:50:41 +080010802 securityType[len_sec] = '\0';
10803 authMode[len_auth] = '\0';
developera3511852023-06-14 14:12:59 +080010804 wifi_setApBeaconType(apIndex, securityType);
10805 wifi_setApBasicAuthenticationMode(apIndex, authMode);
10806 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010807
developera3511852023-06-14 14:12:59 +080010808 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080010809}
developer72fb0bb2023-01-11 09:46:29 +080010810
10811
10812//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
10813// output_string must be pre-allocated as 64 character string by caller
10814// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
10815INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
10816{
developera3511852023-06-14 14:12:59 +080010817 char buf[16] = {0};
10818 char config_file[MAX_BUF_SIZE] = {0};
10819 int res;
developer72fb0bb2023-01-11 09:46:29 +080010820
developera3511852023-06-14 14:12:59 +080010821 if(output_string==NULL)
10822 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010823
developera3511852023-06-14 14:12:59 +080010824 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10825 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010826 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10827 return RETURN_ERR;
10828 }
developera3511852023-06-14 14:12:59 +080010829 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010830
developera3511852023-06-14 14:12:59 +080010831 if(strcmp(buf,"0")==0)
10832 {
10833 printf("wpa_mode is %s ......... \n",buf);
10834 return RETURN_ERR;
10835 }
developer72fb0bb2023-01-11 09:46:29 +080010836
developera3511852023-06-14 14:12:59 +080010837 wifi_dbg_printf("\nFunc=%s\n",__func__);
10838 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10839 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010840 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10841 return RETURN_ERR;
10842 }
developere5750452023-05-15 16:46:42 +080010843 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developera3511852023-06-14 14:12:59 +080010844 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080010845
developera3511852023-06-14 14:12:59 +080010846 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010847}
10848
10849// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
10850// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
10851INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
10852{
developera3511852023-06-14 14:12:59 +080010853 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
10854 struct params params={'\0'};
developer32f2a182023-06-27 19:50:41 +080010855 int ret;
developera3511852023-06-14 14:12:59 +080010856 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010857
developera3511852023-06-14 14:12:59 +080010858 if(NULL == preSharedKey)
10859 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010860
developera3511852023-06-14 14:12:59 +080010861 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +080010862
developera3511852023-06-14 14:12:59 +080010863 if(strlen(preSharedKey) != 64)
10864 {
10865 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
10866 return RETURN_ERR;
10867 }
10868 params.value = preSharedKey;
developer32f2a182023-06-27 19:50:41 +080010869 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10870 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080010871 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10872 return RETURN_ERR;
10873 }
developera3511852023-06-14 14:12:59 +080010874 ret = wifi_hostapdWrite(config_file, &params, 1);
10875 if(!ret) {
10876 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
10877 wifi_reloadAp(apIndex);
10878 }
10879 return ret;
10880 //TODO: call hostapd_cli for dynamic_config_control
developer72fb0bb2023-01-11 09:46:29 +080010881}
10882
10883//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
10884// outputs the passphrase, maximum 63 characters
10885INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
10886{
developera3511852023-06-14 14:12:59 +080010887 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
developer75bd10c2023-06-27 11:34:08 +080010888 int res;
developer72fb0bb2023-01-11 09:46:29 +080010889
developera3511852023-06-14 14:12:59 +080010890 wifi_dbg_printf("\nFunc=%s\n",__func__);
10891 if (NULL == output_string)
10892 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010893
developer75bd10c2023-06-27 11:34:08 +080010894 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10895 if (os_snprintf_error(sizeof(config_file), res)) {
10896 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10897 return RETURN_ERR;
10898 }
10899
developera3511852023-06-14 14:12:59 +080010900 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
10901 if(strcmp(buf,"0")==0)
10902 {
10903 printf("wpa_mode is %s ......... \n",buf);
10904 return RETURN_ERR;
10905 }
developer72fb0bb2023-01-11 09:46:29 +080010906
developera3511852023-06-14 14:12:59 +080010907 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
10908 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080010909
developera3511852023-06-14 14:12:59 +080010910 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010911}
10912
10913// sets the passphrase enviornment variable, max 63 characters
10914INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
10915{
developera3511852023-06-14 14:12:59 +080010916 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
10917 struct params params={'\0'};
10918 char config_file[MAX_BUF_SIZE] = {0};
10919 int ret;
developer72fb0bb2023-01-11 09:46:29 +080010920
developera3511852023-06-14 14:12:59 +080010921 if(NULL == passPhrase)
10922 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010923
developera3511852023-06-14 14:12:59 +080010924 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
10925 {
10926 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
10927 return RETURN_ERR;
10928 }
10929 params.name = "wpa_passphrase";
10930 params.value = passPhrase;
developer32f2a182023-06-27 19:50:41 +080010931 ret = snprintf(config_file, sizeof(config_file),
10932 "%s%d.conf", CONFIG_PREFIX, apIndex);
10933 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080010934 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10935 return RETURN_ERR;
10936 }
developera3511852023-06-14 14:12:59 +080010937 ret=wifi_hostapdWrite(config_file,&params,1);
10938 if(!ret) {
10939 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +080010940 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +080010941 }
developer72fb0bb2023-01-11 09:46:29 +080010942
developera3511852023-06-14 14:12:59 +080010943 return ret;
developer72fb0bb2023-01-11 09:46:29 +080010944}
10945
10946//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.
10947INT wifi_setApSecurityReset(INT apIndex)
10948{
developera3511852023-06-14 14:12:59 +080010949 char original_config_file[64] = {0};
10950 char current_config_file[64] = {0};
10951 char buf[64] = {0};
10952 char cmd[64] = {0};
10953 char wpa[4] = {0};
10954 char wpa_psk[64] = {0};
10955 char wpa_passphrase[64] = {0};
10956 char wpa_psk_file[128] = {0};
10957 char wpa_key_mgmt[64] = {0};
10958 char wpa_pairwise[32] = {0};
10959 wifi_band band;
10960 struct params list[6];
developere40952c2023-06-15 18:46:43 +080010961 int res;
developer72fb0bb2023-01-11 09:46:29 +080010962
developera3511852023-06-14 14:12:59 +080010963 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010964
developera3511852023-06-14 14:12:59 +080010965 band = wifi_index_to_band(apIndex);
developer37646972023-06-29 10:58:43 +080010966 if (band == band_2_4) {
10967 res = snprintf(original_config_file, sizeof(original_config_file),
10968 "/etc/hostapd-2G.conf");
10969 if (os_snprintf_error(sizeof(original_config_file), res)) {
10970 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10971 return RETURN_ERR;
10972 }
10973 } else if (band == band_5) {
10974 res = snprintf(original_config_file, sizeof(original_config_file),
10975 "/etc/hostapd-5G.conf");
10976 if (os_snprintf_error(sizeof(original_config_file), res)) {
10977 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10978 return RETURN_ERR;
10979 }
10980 } else if (band == band_6) {
10981 res = snprintf(original_config_file, sizeof(original_config_file),
10982 "/etc/hostapd-6G.conf");
10983 if (os_snprintf_error(sizeof(original_config_file), res)) {
10984 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10985 return RETURN_ERR;
10986 }
10987 } else
developera3511852023-06-14 14:12:59 +080010988 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010989
developera3511852023-06-14 14:12:59 +080010990 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
10991 list[0].name = "wpa";
10992 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +080010993
developera3511852023-06-14 14:12:59 +080010994 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
10995 list[1].name = "wpa_psk";
10996 list[1].value = wpa_psk;
developer72fb0bb2023-01-11 09:46:29 +080010997
developera3511852023-06-14 14:12:59 +080010998 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
10999 list[2].name = "wpa_passphrase";
11000 list[2].value = wpa_passphrase;
developer72fb0bb2023-01-11 09:46:29 +080011001
developera3511852023-06-14 14:12:59 +080011002 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
developer72fb0bb2023-01-11 09:46:29 +080011003
developera3511852023-06-14 14:12:59 +080011004 if (strlen(wpa_psk_file) == 0)
developer32f2a182023-06-27 19:50:41 +080011005 memcpy(wpa_psk_file, PSK_FILE, strlen(PSK_FILE));
developer72fb0bb2023-01-11 09:46:29 +080011006
developera3511852023-06-14 14:12:59 +080011007 if (access(wpa_psk_file, F_OK) != 0) {
developerd14dff12023-06-28 22:47:44 +080011008 res = snprintf(cmd, sizeof(cmd), "touch %s", wpa_psk_file);
developere40952c2023-06-15 18:46:43 +080011009 if (os_snprintf_error(sizeof(cmd), res)) {
11010 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11011 return RETURN_ERR;
11012 }
developera3511852023-06-14 14:12:59 +080011013 _syscmd(cmd, buf, sizeof(buf));
11014 }
11015 list[3].name = "wpa_psk_file";
11016 list[3].value = wpa_psk_file;
developer72fb0bb2023-01-11 09:46:29 +080011017
developera3511852023-06-14 14:12:59 +080011018 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
11019 list[4].name = "wpa_key_mgmt";
11020 list[4].value = wpa_key_mgmt;
developer72fb0bb2023-01-11 09:46:29 +080011021
developera3511852023-06-14 14:12:59 +080011022 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
11023 list[5].name = "wpa_pairwise";
11024 list[5].value = wpa_pairwise;
developer72fb0bb2023-01-11 09:46:29 +080011025
developer32f2a182023-06-27 19:50:41 +080011026 res = snprintf(current_config_file, sizeof(current_config_file),
11027 "%s%d.conf", CONFIG_PREFIX, apIndex);
11028 if (os_snprintf_error(sizeof(current_config_file), res)) {
11029 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11030 return RETURN_ERR;
11031 }
developera3511852023-06-14 14:12:59 +080011032 wifi_hostapdWrite(current_config_file, list, 6);
developer72fb0bb2023-01-11 09:46:29 +080011033
developera3511852023-06-14 14:12:59 +080011034 wifi_setApEnable(apIndex, FALSE);
11035 wifi_setApEnable(apIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +080011036
developera3511852023-06-14 14:12:59 +080011037 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11038 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011039}
11040
11041//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).
11042INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
11043{
developera3511852023-06-14 14:12:59 +080011044 char config_file[64] = {0};
11045 char buf[64] = {0};
11046 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +080011047 int res;
developer72fb0bb2023-01-11 09:46:29 +080011048
developera3511852023-06-14 14:12:59 +080011049 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011050
developera3511852023-06-14 14:12:59 +080011051 if(!IP_output || !Port_output || !RadiusSecret_output)
11052 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011053
developera3511852023-06-14 14:12:59 +080011054 // Read the first matched config
developere40952c2023-06-15 18:46:43 +080011055 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11056 if (os_snprintf_error(sizeof(config_file), res)) {
11057 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11058 return RETURN_ERR;
11059 }
developer32f2a182023-06-27 19:50:41 +080011060 res = snprintf(cmd, sizeof(cmd),
11061 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
developer75bd10c2023-06-27 11:34:08 +080011062 if (os_snprintf_error(sizeof(cmd), res)) {
11063 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11064 return RETURN_ERR;
11065 }
developera3511852023-06-14 14:12:59 +080011066 _syscmd(cmd, buf, sizeof(buf));
11067 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011068
developera3511852023-06-14 14:12:59 +080011069 memset(buf, 0, sizeof(buf));
developer75bd10c2023-06-27 11:34:08 +080011070 res = snprintf(cmd, sizeof(cmd), "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
11071 if (os_snprintf_error(sizeof(cmd), res)) {
11072 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11073 return RETURN_ERR;
11074 }
developera3511852023-06-14 14:12:59 +080011075 _syscmd(cmd, buf, sizeof(buf));
11076 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011077
developera3511852023-06-14 14:12:59 +080011078 memset(buf, 0, sizeof(buf));
developer75bd10c2023-06-27 11:34:08 +080011079 res = snprintf(cmd, sizeof(cmd), "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
11080 if (os_snprintf_error(sizeof(cmd), res)) {
11081 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11082 return RETURN_ERR;
11083 }
developera3511852023-06-14 14:12:59 +080011084 _syscmd(cmd, buf, sizeof(buf));
11085 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011086
developera3511852023-06-14 14:12:59 +080011087 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11088 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011089}
11090
11091INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
11092{
developera3511852023-06-14 14:12:59 +080011093 char config_file[64] = {0};
11094 char port_str[8] = {0};
11095 char cmd[256] = {0};
11096 char buf[128] = {0};
11097 int res;
developer72fb0bb2023-01-11 09:46:29 +080011098
developera3511852023-06-14 14:12:59 +080011099 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011100
developere5750452023-05-15 16:46:42 +080011101 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080011102 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011103
developera3511852023-06-14 14:12:59 +080011104 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
11105 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011106
developera3511852023-06-14 14:12:59 +080011107 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11108 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080011109 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11110 return RETURN_ERR;
11111 }
developer72fb0bb2023-01-11 09:46:29 +080011112
developera3511852023-06-14 14:12:59 +080011113 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
11114 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011115 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11116 return RETURN_ERR;
11117 }
developera3511852023-06-14 14:12:59 +080011118 _syscmd(cmd, buf, sizeof(buf));
11119 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080011120
developere40952c2023-06-15 18:46:43 +080011121 res = snprintf(port_str, sizeof(port_str), "%d", port);
developer37646972023-06-29 10:58:43 +080011122 if (os_snprintf_error(sizeof(port_str), res)) {
11123 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11124 return RETURN_ERR;
11125 }
developera3511852023-06-14 14:12:59 +080011126 if (strlen(buf) == 0) {
11127 // Append
11128 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
11129 "auth_server_addr=%s\\n"
11130 "auth_server_port=%s\\n"
11131 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
11132 if (os_snprintf_error(sizeof(cmd), res)) {
11133 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11134 return RETURN_ERR;
11135 }
11136 } else {
11137 // Delete the three lines setting after the "# radius 1" comment
11138 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
11139 if (os_snprintf_error(sizeof(cmd), res)) {
11140 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11141 return RETURN_ERR;
11142 }
11143 _syscmd(cmd, buf, sizeof(buf));
11144 memset(cmd, 0, sizeof(cmd));
11145 // Use "# radius 1" comment to find the location to insert the radius setting
11146 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
11147 "# radius 1\\n"
11148 "auth_server_addr=%s\\n"
11149 "auth_server_port=%s\\n"
11150 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
11151 if (os_snprintf_error(sizeof(cmd), res)) {
11152 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11153 return RETURN_ERR;
11154 }
11155 }
11156 if(_syscmd(cmd, buf, sizeof(buf))) {
11157 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
11158 return RETURN_ERR;
11159 }
developer72fb0bb2023-01-11 09:46:29 +080011160
developera3511852023-06-14 14:12:59 +080011161 wifi_reloadAp(apIndex);
11162 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11163 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011164}
11165
11166INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
11167{
developera3511852023-06-14 14:12:59 +080011168 char config_file[64] = {0};
11169 char buf[64] = {0};
11170 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +080011171 int res;
developer72fb0bb2023-01-11 09:46:29 +080011172
developera3511852023-06-14 14:12:59 +080011173 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011174
developera3511852023-06-14 14:12:59 +080011175 if(!IP_output || !Port_output || !RadiusSecret_output)
11176 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011177
developera3511852023-06-14 14:12:59 +080011178 // Read the second matched config
developere40952c2023-06-15 18:46:43 +080011179 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11180 if (os_snprintf_error(sizeof(config_file), res)) {
11181 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11182 return RETURN_ERR;
11183 }
11184
developer32f2a182023-06-27 19:50:41 +080011185 res = snprintf(cmd, sizeof(cmd),
11186 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
11187 config_file);
developer75bd10c2023-06-27 11:34:08 +080011188 if (os_snprintf_error(sizeof(cmd), res)) {
11189 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11190 return RETURN_ERR;
11191 }
developera3511852023-06-14 14:12:59 +080011192 _syscmd(cmd, buf, sizeof(buf));
11193 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011194
developera3511852023-06-14 14:12:59 +080011195 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080011196 res = snprintf(cmd, sizeof(cmd),
11197 "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
11198 config_file);
developer75bd10c2023-06-27 11:34:08 +080011199 if (os_snprintf_error(sizeof(cmd), res)) {
11200 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11201 return RETURN_ERR;
11202 }
developera3511852023-06-14 14:12:59 +080011203 _syscmd(cmd, buf, sizeof(buf));
11204 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011205
developera3511852023-06-14 14:12:59 +080011206 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080011207 res = snprintf(cmd, sizeof(cmd),
11208 "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
11209 config_file);
developer75bd10c2023-06-27 11:34:08 +080011210 if (os_snprintf_error(sizeof(cmd), res)) {
11211 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11212 return RETURN_ERR;
11213 }
11214
developera3511852023-06-14 14:12:59 +080011215 _syscmd(cmd, buf, sizeof(buf));
11216 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011217
developera3511852023-06-14 14:12:59 +080011218 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11219 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011220}
11221
11222INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
11223{
developera3511852023-06-14 14:12:59 +080011224 char config_file[64] = {0};
11225 char port_str[8] = {0};
11226 char cmd[256] = {0};
11227 char buf[128] = {0};
11228 int res;
developer72fb0bb2023-01-11 09:46:29 +080011229
developera3511852023-06-14 14:12:59 +080011230 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011231
developere5750452023-05-15 16:46:42 +080011232 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080011233 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011234
developera3511852023-06-14 14:12:59 +080011235 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
11236 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011237
developera3511852023-06-14 14:12:59 +080011238 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11239 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080011240 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11241 return RETURN_ERR;
11242 }
developer72fb0bb2023-01-11 09:46:29 +080011243
developera3511852023-06-14 14:12:59 +080011244 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
11245 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011246 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11247 return RETURN_ERR;
11248 }
developera3511852023-06-14 14:12:59 +080011249 _syscmd(cmd, buf, sizeof(buf));
11250 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080011251
developera3511852023-06-14 14:12:59 +080011252 res = snprintf(port_str, sizeof(port_str), "%d", port);
11253 if (os_snprintf_error(sizeof(port_str), res)) {
developer46506162023-06-12 10:09:39 +080011254 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11255 return RETURN_ERR;
11256 }
developera3511852023-06-14 14:12:59 +080011257 if (strlen(buf) == 0) {
11258 // Append
11259 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
11260 "auth_server_addr=%s\\n"
11261 "auth_server_port=%s\\n"
11262 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
11263 if (os_snprintf_error(sizeof(cmd), res)) {
11264 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11265 return RETURN_ERR;
11266 }
11267 } else {
11268 // Delete the three lines setting after the "# radius 2" comment
11269 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
11270 if (os_snprintf_error(sizeof(cmd), res)) {
11271 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11272 return RETURN_ERR;
11273 }
11274 _syscmd(cmd, buf, sizeof(buf));
11275 memset(cmd, 0, sizeof(cmd));
11276 // Use "# radius 2" comment to find the location to insert the radius setting
11277 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
11278 "# radius 2\\n"
11279 "auth_server_addr=%s\\n"
11280 "auth_server_port=%s\\n"
11281 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
11282 if (os_snprintf_error(sizeof(cmd), res)) {
11283 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11284 return RETURN_ERR;
11285 }
11286 }
11287 if(_syscmd(cmd, buf, sizeof(buf))) {
11288 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
11289 return RETURN_ERR;
11290 }
developer72fb0bb2023-01-11 09:46:29 +080011291
developera3511852023-06-14 14:12:59 +080011292 wifi_reloadAp(apIndex);
11293 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11294 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011295}
11296
11297//RadiusSettings
11298INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
11299{
developera3511852023-06-14 14:12:59 +080011300 if(!output)
11301 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011302
developera3511852023-06-14 14:12:59 +080011303 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
11304 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
11305 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
11306 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
11307 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
11308 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.
11309 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
11310 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
11311 output->QuietPeriodAfterFailedAuthentication = 5; //The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it.
developere40952c2023-06-15 18:46:43 +080011312 //res = 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.
developer72fb0bb2023-01-11 09:46:29 +080011313
developera3511852023-06-14 14:12:59 +080011314 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011315}
11316
11317INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
11318{
developera3511852023-06-14 14:12:59 +080011319 //store the paramters, and apply instantly
11320 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011321}
11322
11323//Device.WiFi.AccessPoint.{i}.WPS.Enable
11324//Enables or disables WPS functionality for this access point.
11325// outputs the WPS enable state of this ap in output_bool
11326INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
11327{
developera3511852023-06-14 14:12:59 +080011328 char interface_name[16] = {0};
11329 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080011330 int res;
11331
developera3511852023-06-14 14:12:59 +080011332 if(!output_bool)
11333 return RETURN_ERR;
11334 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11335 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080011336 res = snprintf(cmd, sizeof(cmd),
11337 "hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2",
11338 interface_name);
developer75bd10c2023-06-27 11:34:08 +080011339 if (os_snprintf_error(sizeof(cmd), res)) {
11340 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11341 return RETURN_ERR;
11342 }
developera3511852023-06-14 14:12:59 +080011343 _syscmd(cmd, buf, sizeof(buf));
11344 if(strstr(buf, "configured"))
11345 *output_bool=TRUE;
11346 else
11347 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +080011348
developera3511852023-06-14 14:12:59 +080011349 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080011350}
developer72fb0bb2023-01-11 09:46:29 +080011351
11352//Device.WiFi.AccessPoint.{i}.WPS.Enable
11353// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
11354INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
11355{
developera3511852023-06-14 14:12:59 +080011356 char config_file[MAX_BUF_SIZE] = {0};
11357 char buf[128] = {0};
11358 struct params params;
developere40952c2023-06-15 18:46:43 +080011359 int res;
developer72fb0bb2023-01-11 09:46:29 +080011360
developera3511852023-06-14 14:12:59 +080011361 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11362 //store the paramters, and wait for wifi up to apply
11363 params.name = "wps_state";
11364 if (enable == TRUE) {
11365 wifi_getApBeaconType(apIndex, buf);
11366 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
11367 params.value = "1";
11368 else // If ap set encryption
11369 params.value = "2";
11370 } else {
11371 params.value = "0";
11372 }
developer72fb0bb2023-01-11 09:46:29 +080011373
developere40952c2023-06-15 18:46:43 +080011374 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11375 if (os_snprintf_error(sizeof(config_file), res)) {
11376 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11377 return RETURN_ERR;
11378 }
developera3511852023-06-14 14:12:59 +080011379 wifi_hostapdWrite(config_file, &params, 1);
11380 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11381 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080011382
developera3511852023-06-14 14:12:59 +080011383 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11384 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011385}
11386
11387//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
11388INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
11389{
developere40952c2023-06-15 18:46:43 +080011390 int res;
developera3511852023-06-14 14:12:59 +080011391 if(!output)
11392 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011393 res = snprintf(output, 128, "PushButton,PIN");
11394 if (os_snprintf_error(128, res)) {
11395 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11396 return RETURN_ERR;
11397 }
11398
developera3511852023-06-14 14:12:59 +080011399 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011400}
11401
11402//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
11403//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.
11404// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
11405INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
11406{
developere40952c2023-06-15 18:46:43 +080011407 int res;
developera3511852023-06-14 14:12:59 +080011408 if(!output)
11409 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011410 res = snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
11411 if (os_snprintf_error(64, res)) {
11412 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11413 return RETURN_ERR;
11414 }
developer72fb0bb2023-01-11 09:46:29 +080011415
developera3511852023-06-14 14:12:59 +080011416 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011417}
11418
11419//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
11420// 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
11421INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
11422{
developera3511852023-06-14 14:12:59 +080011423 //apply instantly. No setting need to be stored.
11424 char methods[MAX_BUF_SIZE], *token, *next_token;
11425 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
11426 struct params params;
developere40952c2023-06-15 18:46:43 +080011427 int res;
developer72fb0bb2023-01-11 09:46:29 +080011428
developera3511852023-06-14 14:12:59 +080011429 if(!methodString)
11430 return RETURN_ERR;
11431 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11432 //store the paramters, and wait for wifi up to apply
developer72fb0bb2023-01-11 09:46:29 +080011433
developere40952c2023-06-15 18:46:43 +080011434 res = snprintf(methods, sizeof(methods), "%s", methodString);
11435 if (os_snprintf_error(sizeof(methods), res)) {
11436 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11437 return RETURN_ERR;
11438 }
developera3511852023-06-14 14:12:59 +080011439 for(token=methods; *token; token=next_token) {
11440 strtok_r(token, ",", &next_token);
11441 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
developere40952c2023-06-15 18:46:43 +080011442 res = snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
developera3511852023-06-14 14:12:59 +080011443 else if(*token=='E')
11444 {
11445 if(!strcmp(methods, "Ethernet"))
developere40952c2023-06-15 18:46:43 +080011446 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
developera3511852023-06-14 14:12:59 +080011447 else if(!strcmp(methods, "ExternalNFCToken"))
developere40952c2023-06-15 18:46:43 +080011448 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
developera3511852023-06-14 14:12:59 +080011449 else
11450 printf("%s: Unknown WpsConfigMethod\n", __func__);
11451 }
11452 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
developere40952c2023-06-15 18:46:43 +080011453 res = snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
developera3511852023-06-14 14:12:59 +080011454 else if(*token=='N' && !strcmp(token, "NFCInterface"))
developere40952c2023-06-15 18:46:43 +080011455 res = snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
developera3511852023-06-14 14:12:59 +080011456 else if(*token=='P' )
11457 {
11458 if(!strcmp(token, "PushButton"))
developere40952c2023-06-15 18:46:43 +080011459 res = snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developera3511852023-06-14 14:12:59 +080011460 else if(!strcmp(token, "PIN"))
developere40952c2023-06-15 18:46:43 +080011461 res = snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
developera3511852023-06-14 14:12:59 +080011462 else
11463 printf("%s: Unknown WpsConfigMethod\n", __func__);
11464 }
11465 else
11466 printf("%s: Unknown WpsConfigMethod\n", __func__);
developere40952c2023-06-15 18:46:43 +080011467
developer37646972023-06-29 10:58:43 +080011468 if (os_snprintf_error(sizeof(config_methods), res)) {
11469 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11470 return RETURN_ERR;
11471 }
11472 }
developera3511852023-06-14 14:12:59 +080011473 params.name = "config_methods";
11474 params.value = config_methods;
developere40952c2023-06-15 18:46:43 +080011475 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11476 if (os_snprintf_error(sizeof(config_file), res)) {
11477 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11478 return RETURN_ERR;
11479 }
developera3511852023-06-14 14:12:59 +080011480 wifi_hostapdWrite(config_file, &params, 1);
11481 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11482 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011483
developera3511852023-06-14 14:12:59 +080011484 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011485}
11486
11487// outputs the pin value, ulong_pin must be allocated by the caller
11488INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
11489{
developera3511852023-06-14 14:12:59 +080011490 char buf[MAX_BUF_SIZE] = {0};
11491 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011492 int res;
developer72fb0bb2023-01-11 09:46:29 +080011493
developera3511852023-06-14 14:12:59 +080011494 if(!output_ulong)
11495 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011496 res = snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
11497 if (os_snprintf_error(sizeof(cmd), res)) {
11498 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11499 return RETURN_ERR;
11500 }
developera3511852023-06-14 14:12:59 +080011501 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +080011502 if(strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +080011503 if (hal_strtoul(buf, 10, output_ulong) < 0) {
11504 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080011505 }
11506 }
developer72fb0bb2023-01-11 09:46:29 +080011507
developera3511852023-06-14 14:12:59 +080011508 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011509}
11510
11511// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
11512INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
11513{
developera3511852023-06-14 14:12:59 +080011514 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
11515 char ap_pin[16] = {0};
11516 char config_file[MAX_BUF_SIZE] = {0};
11517 struct params params;
developere40952c2023-06-15 18:46:43 +080011518 int res;
developer72fb0bb2023-01-11 09:46:29 +080011519
developera3511852023-06-14 14:12:59 +080011520 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080011521 res = snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
11522 if (os_snprintf_error(sizeof(ap_pin), res)) {
11523 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11524 return RETURN_ERR;
11525 }
developera3511852023-06-14 14:12:59 +080011526 params.name = "ap_pin";
11527 params.value = ap_pin;
developere40952c2023-06-15 18:46:43 +080011528 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11529 if (os_snprintf_error(sizeof(config_file), res)) {
11530 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11531 return RETURN_ERR;
11532 }
developera3511852023-06-14 14:12:59 +080011533 wifi_hostapdWrite(config_file, &params, 1);
11534 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11535 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011536
developera3511852023-06-14 14:12:59 +080011537 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011538}
11539
11540// Output string is either Not configured or Configured, max 32 characters
11541INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
11542{
developera3511852023-06-14 14:12:59 +080011543 char interface_name[16] = {0};
11544 char cmd[MAX_CMD_SIZE];
11545 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080011546 int res;
developer72fb0bb2023-01-11 09:46:29 +080011547
developera3511852023-06-14 14:12:59 +080011548 if(!output_string)
11549 return RETURN_ERR;
11550 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080011551 res = snprintf(output_string, 32, "Not configured");
11552 if (os_snprintf_error(32, res)) {
11553 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11554 return RETURN_ERR;
11555 }
developera3511852023-06-14 14:12:59 +080011556 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11557 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011558 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
11559 if (os_snprintf_error(sizeof(cmd), res)) {
11560 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11561 return RETURN_ERR;
11562 }
developera3511852023-06-14 14:12:59 +080011563 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011564
developerc14d83a2023-06-29 20:09:42 +080011565 if(!strncmp(buf, "configured", 10)) {
developere40952c2023-06-15 18:46:43 +080011566 res = snprintf(output_string, 32, "Configured");
developerc14d83a2023-06-29 20:09:42 +080011567 if (os_snprintf_error(32, res)) {
11568 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11569 return RETURN_ERR;
11570 }
11571 }
developera3511852023-06-14 14:12:59 +080011572 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011573
developera3511852023-06-14 14:12:59 +080011574 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011575}
11576
11577// sets the WPS pin for this AP
11578INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
11579{
developera3511852023-06-14 14:12:59 +080011580 char interface_name[16] = {0};
11581 char cmd[MAX_CMD_SIZE];
11582 char buf[MAX_BUF_SIZE]={0};
developer9ce44382023-06-28 11:09:37 +080011583 BOOL enable = 0;
developere40952c2023-06-15 18:46:43 +080011584 int res;
developer72fb0bb2023-01-11 09:46:29 +080011585
developera3511852023-06-14 14:12:59 +080011586 wifi_getApEnable(apIndex, &enable);
11587 if (!enable)
11588 return RETURN_ERR;
11589 wifi_getApWpsEnable(apIndex, &enable);
11590 if (!enable)
11591 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011592
developera3511852023-06-14 14:12:59 +080011593 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11594 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011595 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
11596 if (os_snprintf_error(sizeof(cmd), res)) {
11597 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11598 return RETURN_ERR;
11599 }
developera3511852023-06-14 14:12:59 +080011600 _syscmd(cmd, buf, sizeof(buf));
11601 if((strstr(buf, "OK"))!=NULL)
11602 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011603
developera3511852023-06-14 14:12:59 +080011604 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011605}
11606
11607// This function is called when the WPS push button has been pressed for this AP
11608INT wifi_setApWpsButtonPush(INT apIndex)
11609{
developera3511852023-06-14 14:12:59 +080011610 char cmd[MAX_CMD_SIZE];
11611 char buf[MAX_BUF_SIZE]={0};
11612 char interface_name[16] = {0};
11613 BOOL enable=FALSE;
developere40952c2023-06-15 18:46:43 +080011614 int res;
developer72fb0bb2023-01-11 09:46:29 +080011615
developera3511852023-06-14 14:12:59 +080011616 wifi_getApEnable(apIndex, &enable);
11617 if (!enable)
11618 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011619
developera3511852023-06-14 14:12:59 +080011620 wifi_getApWpsEnable(apIndex, &enable);
11621 if (!enable)
11622 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011623
developera3511852023-06-14 14:12:59 +080011624 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11625 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011626
developere40952c2023-06-15 18:46:43 +080011627 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
11628 if (os_snprintf_error(sizeof(cmd), res)) {
11629 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11630 return RETURN_ERR;
11631 }
developera3511852023-06-14 14:12:59 +080011632 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011633
developera3511852023-06-14 14:12:59 +080011634 if((strstr(buf, "OK"))!=NULL)
11635 return RETURN_OK;
11636 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011637}
11638
11639// cancels WPS mode for this AP
11640INT wifi_cancelApWPS(INT apIndex)
11641{
developera3511852023-06-14 14:12:59 +080011642 char interface_name[16] = {0};
11643 char cmd[MAX_CMD_SIZE];
11644 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080011645 int res;
developer72fb0bb2023-01-11 09:46:29 +080011646
developera3511852023-06-14 14:12:59 +080011647 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11648 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011649 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
11650 if (os_snprintf_error(sizeof(cmd), res)) {
11651 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11652 return RETURN_ERR;
11653 }
developera3511852023-06-14 14:12:59 +080011654 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011655
developera3511852023-06-14 14:12:59 +080011656 if((strstr(buf, "OK"))!=NULL)
11657 return RETURN_OK;
11658 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011659}
11660
11661//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
11662//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
11663INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
11664{
developera3511852023-06-14 14:12:59 +080011665 char interface_name[16] = {0};
11666 FILE *f = NULL;
11667 int read_flag=0, auth_temp=0, mac_temp=0;
11668 char cmd[256] = {0}, buf[2048] = {0};
11669 char *param = NULL, *value = NULL, *line=NULL;
11670 size_t len = 0;
11671 wifi_associated_dev_t *dev=NULL;
11672 int res;
developer72fb0bb2023-01-11 09:46:29 +080011673
developera3511852023-06-14 14:12:59 +080011674 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11675 *associated_dev_array = NULL;
11676 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11677 return RETURN_ERR;
11678 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
11679 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011680 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11681 return RETURN_ERR;
11682 }
developera3511852023-06-14 14:12:59 +080011683 _syscmd(cmd,buf,sizeof(buf));
11684 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011685
developera3511852023-06-14 14:12:59 +080011686 if (*output_array_size <= 0)
11687 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011688
developera3511852023-06-14 14:12:59 +080011689 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
developere75ba632023-06-29 16:03:33 +080011690 if (!dev) {
11691 wifi_debug(DEBUG_ERROR, "Unexpected calloc fail\n");
11692 return RETURN_ERR;
11693 }
developera3511852023-06-14 14:12:59 +080011694 *associated_dev_array = dev;
11695 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
11696 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011697 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11698 return RETURN_ERR;
11699 }
developera3511852023-06-14 14:12:59 +080011700 _syscmd(cmd,buf,sizeof(buf));
11701 f = fopen("/tmp/connected_devices.txt", "r");
11702 if (f==NULL)
11703 {
11704 *output_array_size=0;
11705 return RETURN_ERR;
11706 }
11707 while ((getline(&line, &len, f)) != -1)
11708 {
11709 param = strtok(line,"=");
developere75ba632023-06-29 16:03:33 +080011710 if (!param)
11711 continue;
developera3511852023-06-14 14:12:59 +080011712 value = strtok(NULL,"=");
developere75ba632023-06-29 16:03:33 +080011713 if (!value)
11714 continue;
developer72fb0bb2023-01-11 09:46:29 +080011715
developera3511852023-06-14 14:12:59 +080011716 if( strcmp("flags",param) == 0 )
11717 {
11718 value[strlen(value)-1]='\0';
11719 if(strstr (value,"AUTHORIZED") != NULL )
11720 {
11721 dev[auth_temp].cli_AuthenticationState = 1;
11722 dev[auth_temp].cli_Active = 1;
11723 auth_temp++;
11724 read_flag=1;
11725 }
11726 }
11727 if(read_flag==1)
11728 {
11729 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
11730 {
11731 value[strlen(value)-1]='\0';
developere75ba632023-06-29 16:03:33 +080011732 if (sscanf(value, "%x:%x:%x:%x:%x:%x",
developera3511852023-06-14 14:12:59 +080011733 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
11734 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
11735 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
11736 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
11737 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
developere75ba632023-06-29 16:03:33 +080011738 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] ) == EOF)
11739 continue;
developera3511852023-06-14 14:12:59 +080011740 mac_temp++;
11741 read_flag=0;
11742 }
11743 }
11744 }
11745 *output_array_size = auth_temp;
11746 auth_temp=0;
11747 mac_temp=0;
11748 free(line);
developere75ba632023-06-29 16:03:33 +080011749 if (fclose(f) == EOF) {
11750 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
11751 return RETURN_ERR;
11752 }
developera3511852023-06-14 14:12:59 +080011753 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11754 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011755}
11756
11757#define MACADDRESS_SIZE 6
11758
11759INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
11760{
developera3511852023-06-14 14:12:59 +080011761 FILE *fp = NULL;
11762 char str[MAX_BUF_SIZE] = {0};
11763 int wificlientindex = 0 ;
11764 int count = 0;
11765 int signalstrength = 0;
11766 int arr[MACADDRESS_SIZE] = {0};
11767 unsigned char mac[MACADDRESS_SIZE] = {0};
11768 UINT wifi_count = 0;
11769 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011770 int res;
developerc14d83a2023-06-29 20:09:42 +080011771 wifi_associated_dev3_t* temp = NULL;
developer72fb0bb2023-01-11 09:46:29 +080011772
developera3511852023-06-14 14:12:59 +080011773 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11774 *output_array_size = 0;
11775 *associated_dev_array = NULL;
developer72fb0bb2023-01-11 09:46:29 +080011776
developer32f2a182023-06-27 19:50:41 +080011777 res = snprintf(pipeCmd, sizeof(pipeCmd),
11778 "iw dev %s station dump | grep %s | wc -l", interface_name,
11779 interface_name);
developer75bd10c2023-06-27 11:34:08 +080011780 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11781 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11782 return RETURN_ERR;
11783 }
developera3511852023-06-14 14:12:59 +080011784 fp = popen(pipeCmd, "r");
11785 if (fp == NULL)
11786 {
11787 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11788 return RETURN_ERR;
11789 }
developer72fb0bb2023-01-11 09:46:29 +080011790
developera3511852023-06-14 14:12:59 +080011791 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080011792 if (fgets(str, sizeof(str)-1, fp) == NULL) {
11793 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11794 pclose(fp);
11795 return RETURN_ERR;
11796 }
developera3511852023-06-14 14:12:59 +080011797 wifi_count = (unsigned int) atoi ( str );
11798 *output_array_size = wifi_count;
11799 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11800 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080011801
developera3511852023-06-14 14:12:59 +080011802 if(wifi_count == 0)
11803 {
11804 return RETURN_OK;
11805 }
11806 else
11807 {
developer9ce44382023-06-28 11:09:37 +080011808 if(wifi_count <= 0 || wifi_count > MAX_ASSOCIATED_STA_NUM){
11809 return RETURN_ERR;
11810 }
developera3511852023-06-14 14:12:59 +080011811 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
11812 if(temp == NULL)
11813 {
11814 printf("Error Statement. Insufficient memory \n");
11815 return RETURN_ERR;
11816 }
developer72fb0bb2023-01-11 09:46:29 +080011817
developere40952c2023-06-15 18:46:43 +080011818 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11819 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11820 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080011821 free(temp);
developere40952c2023-06-15 18:46:43 +080011822 return RETURN_ERR;
11823 }
developera3511852023-06-14 14:12:59 +080011824 system(pipeCmd);
11825 memset(pipeCmd,0,sizeof(pipeCmd));
11826 if(apIndex == 0)
developere40952c2023-06-15 18:46:43 +080011827 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
developera3511852023-06-14 14:12:59 +080011828 else if(apIndex == 1)
developere40952c2023-06-15 18:46:43 +080011829 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
11830 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11831 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080011832 free(temp);
developere40952c2023-06-15 18:46:43 +080011833 return RETURN_ERR;
11834 }
developera3511852023-06-14 14:12:59 +080011835 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080011836
developera3511852023-06-14 14:12:59 +080011837 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11838 if(fp == NULL)
11839 {
11840 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11841 free(temp);
11842 return RETURN_ERR;
11843 }
developere75ba632023-06-29 16:03:33 +080011844 if (fclose(fp) == EOF) {
11845 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developerc14d83a2023-06-29 20:09:42 +080011846 free(temp);
developere75ba632023-06-29 16:03:33 +080011847 return RETURN_ERR;
11848 }
developer72fb0bb2023-01-11 09:46:29 +080011849
developer86035662023-06-28 19:21:12 +080011850 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11851 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11852 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080011853 free(temp);
developer86035662023-06-28 19:21:12 +080011854 return RETURN_ERR;
11855 }
11856
developera3511852023-06-14 14:12:59 +080011857 fp = popen(pipeCmd, "r");
11858 if(fp)
11859 {
11860 for(count =0 ; count < wifi_count; count++)
11861 {
developer86035662023-06-28 19:21:12 +080011862 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11863 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080011864 goto err;
developer86035662023-06-28 19:21:12 +080011865 }
developera3511852023-06-14 14:12:59 +080011866 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11867 {
11868 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11869 {
11870 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080011871
developera3511852023-06-14 14:12:59 +080011872 }
11873 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11874 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]);
11875 }
11876 temp[count].cli_AuthenticationState = 1; //TODO
11877 temp[count].cli_Active = 1; //TODO
11878 }
11879 pclose(fp);
11880 }
developer72fb0bb2023-01-11 09:46:29 +080011881
developer86035662023-06-28 19:21:12 +080011882 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11883 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11884 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080011885 goto err;
developer86035662023-06-28 19:21:12 +080011886 }
11887
developera3511852023-06-14 14:12:59 +080011888 fp = popen(pipeCmd, "r");
11889 if(fp)
11890 {
11891 pclose(fp);
11892 }
11893 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11894 if(fp)
11895 {
11896 for(count =0 ; count < wifi_count ;count++)
11897 {
developer86035662023-06-28 19:21:12 +080011898 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11899 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080011900 goto err;
developer86035662023-06-28 19:21:12 +080011901 }
developera3511852023-06-14 14:12:59 +080011902 signalstrength = atoi(str);
11903 temp[count].cli_SignalStrength = signalstrength;
11904 temp[count].cli_RSSI = signalstrength;
11905 temp[count].cli_SNR = signalstrength + 95;
11906 }
11907 pclose(fp);
11908 }
developer72fb0bb2023-01-11 09:46:29 +080011909
11910
developera3511852023-06-14 14:12:59 +080011911 if((apIndex == 0) || (apIndex == 4))
11912 {
11913 for(count =0 ; count < wifi_count ;count++)
11914 {
developer32f2a182023-06-27 19:50:41 +080011915 memcpy(temp[count].cli_OperatingStandard,"g", 1);
11916 temp[count].cli_OperatingStandard[1] = '\0';
11917 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
11918 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080011919 }
developer72fb0bb2023-01-11 09:46:29 +080011920
developera3511852023-06-14 14:12:59 +080011921 //BytesSent
developer86035662023-06-28 19:21:12 +080011922 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
11923 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11924 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080011925 free(temp);
developer86035662023-06-28 19:21:12 +080011926 return RETURN_ERR;
11927 }
11928
developera3511852023-06-14 14:12:59 +080011929 fp = popen(pipeCmd, "r");
11930 if(fp)
11931 {
11932 pclose(fp);
11933 }
11934 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
11935 if(fp)
11936 {
11937 for (count = 0; count < wifi_count; count++)
11938 {
developer86035662023-06-28 19:21:12 +080011939 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11940 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11941 pclose(fp);
developerc14d83a2023-06-29 20:09:42 +080011942 free(temp);
developer86035662023-06-28 19:21:12 +080011943 return RETURN_ERR;
developerc14d83a2023-06-29 20:09:42 +080011944 }
11945 if (hal_strtoul(str, 10, &(temp[count].cli_BytesSent)) < 0) {
11946 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080011947 }
developera3511852023-06-14 14:12:59 +080011948 }
11949 pclose(fp);
11950 }
developer72fb0bb2023-01-11 09:46:29 +080011951
developera3511852023-06-14 14:12:59 +080011952 //BytesReceived
developer86035662023-06-28 19:21:12 +080011953 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
11954 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11955 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080011956 free(temp);
developer86035662023-06-28 19:21:12 +080011957 return RETURN_ERR;
11958 }
11959
developera3511852023-06-14 14:12:59 +080011960 fp = popen(pipeCmd, "r");
11961 if (fp)
11962 {
11963 pclose(fp);
11964 }
11965 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
11966 if (fp)
11967 {
11968 for (count = 0; count < wifi_count; count++)
11969 {
developer86035662023-06-28 19:21:12 +080011970 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11971 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080011972 goto err;
11973 }
11974 if (hal_strtoul(str, 10, &(temp[count].cli_BytesReceived)) < 0) {
11975 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080011976 }
developera3511852023-06-14 14:12:59 +080011977 }
11978 pclose(fp);
11979 }
developer72fb0bb2023-01-11 09:46:29 +080011980
developera3511852023-06-14 14:12:59 +080011981 //PacketsSent
developer86035662023-06-28 19:21:12 +080011982 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
11983 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11984 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080011985 free(temp);
developer86035662023-06-28 19:21:12 +080011986 return RETURN_ERR;
11987 }
11988
developera3511852023-06-14 14:12:59 +080011989 fp = popen(pipeCmd, "r");
11990 if (fp)
11991 {
11992 pclose(fp);
11993 }
developer72fb0bb2023-01-11 09:46:29 +080011994
developera3511852023-06-14 14:12:59 +080011995 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
11996 if (fp)
11997 {
11998 for (count = 0; count < wifi_count; count++)
11999 {
developer86035662023-06-28 19:21:12 +080012000 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12001 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080012002 goto err;
12003 }
12004 if (hal_strtoul(str, 10, &(temp[count].cli_PacketsSent)) < 0) {
12005 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080012006 }
developera3511852023-06-14 14:12:59 +080012007 }
12008 pclose(fp);
12009 }
developer72fb0bb2023-01-11 09:46:29 +080012010
developera3511852023-06-14 14:12:59 +080012011 //PacketsReceived
developer86035662023-06-28 19:21:12 +080012012 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
12013 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12014 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080012015 free(temp);
developer86035662023-06-28 19:21:12 +080012016 return RETURN_ERR;
12017 }
12018
developera3511852023-06-14 14:12:59 +080012019 fp = popen(pipeCmd, "r");
12020 if (fp)
12021 {
12022 pclose(fp);
12023 }
12024 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
12025 if (fp)
12026 {
12027 for (count = 0; count < wifi_count; count++)
12028 {
developer86035662023-06-28 19:21:12 +080012029 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12030 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080012031 goto err;
12032 }
12033 if (hal_strtoul(str, 10, &(temp[count].cli_PacketsReceived)) < 0) {
12034 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080012035 }
developera3511852023-06-14 14:12:59 +080012036 }
12037 pclose(fp);
12038 }
developer72fb0bb2023-01-11 09:46:29 +080012039
developera3511852023-06-14 14:12:59 +080012040 //ErrorsSent
developer86035662023-06-28 19:21:12 +080012041 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
12042 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12043 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080012044 free(temp);
developer86035662023-06-28 19:21:12 +080012045 return RETURN_ERR;
12046 }
12047
developera3511852023-06-14 14:12:59 +080012048 fp = popen(pipeCmd, "r");
12049 if (fp)
12050 {
12051 pclose(fp);
12052 }
12053 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
12054 if (fp)
12055 {
12056 for (count = 0; count < wifi_count; count++)
12057 {
developer86035662023-06-28 19:21:12 +080012058 if (fgets(str, MAX_BUF_SIZE, fp) == NULL){
12059 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080012060 goto err;
12061 }
12062 if (hal_strtoul(str, 10, &(temp[count].cli_ErrorsSent)) < 0) {
12063 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080012064 }
developera3511852023-06-14 14:12:59 +080012065 }
12066 pclose(fp);
12067 }
developer72fb0bb2023-01-11 09:46:29 +080012068
developera3511852023-06-14 14:12:59 +080012069 //ErrorsSent
developer86035662023-06-28 19:21:12 +080012070 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
12071 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12072 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080012073 free(temp);
developer86035662023-06-28 19:21:12 +080012074 return RETURN_ERR;
12075 }
12076
developera3511852023-06-14 14:12:59 +080012077 fp = popen(pipeCmd, "r");
12078 if (fp)
12079 {
12080 pclose(fp);
12081 }
12082 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
12083 if (fp)
12084 {
12085 for (count = 0; count < wifi_count; count++)
12086 {
developer86035662023-06-28 19:21:12 +080012087 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12088 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080012089 goto err;
12090 }
12091 if (hal_strtoul(str, 10, &(temp[count].cli_ErrorsSent)) < 0) {
12092 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080012093 }
developera3511852023-06-14 14:12:59 +080012094 }
12095 pclose(fp);
12096 }
developer72fb0bb2023-01-11 09:46:29 +080012097
developera3511852023-06-14 14:12:59 +080012098 //LastDataDownlinkRate
developer86035662023-06-28 19:21:12 +080012099 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
12100 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12101 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080012102 free(temp);
developer86035662023-06-28 19:21:12 +080012103 return RETURN_ERR;
12104 }
12105
developera3511852023-06-14 14:12:59 +080012106 fp = popen(pipeCmd, "r");
12107 if (fp)
12108 {
12109 pclose(fp);
12110 }
12111 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
12112 if (fp)
developerc14d83a2023-06-29 20:09:42 +080012113 {
12114 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080012115 for (count = 0; count < wifi_count; count++)
12116 {
developer86035662023-06-28 19:21:12 +080012117 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12118 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080012119 goto err;
12120 }
12121
12122 if (hal_strtoul(str, 10, &tmp_u) < 0) {
12123 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080012124 }
developerc14d83a2023-06-29 20:09:42 +080012125 temp[count].cli_LastDataDownlinkRate = tmp_u;
developera3511852023-06-14 14:12:59 +080012126 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
12127 }
12128 pclose(fp);
12129 }
developer72fb0bb2023-01-11 09:46:29 +080012130
developera3511852023-06-14 14:12:59 +080012131 //LastDataUplinkRate
developer86035662023-06-28 19:21:12 +080012132 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
12133 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12134 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080012135 free(temp);
developer86035662023-06-28 19:21:12 +080012136 return RETURN_ERR;
12137 }
12138
developera3511852023-06-14 14:12:59 +080012139 fp = popen(pipeCmd, "r");
12140 if (fp)
12141 {
12142 pclose(fp);
12143 }
12144 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
12145 if (fp)
12146 {
developerc14d83a2023-06-29 20:09:42 +080012147 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080012148 for (count = 0; count < wifi_count; count++)
12149 {
developer86035662023-06-28 19:21:12 +080012150 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12151 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080012152 goto err;
12153 }
12154 if (hal_strtoul(str, 10, &tmp_u) < 0) {
12155 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080012156 }
developerc14d83a2023-06-29 20:09:42 +080012157 temp[count].cli_LastDataUplinkRate = tmp_u;
12158
developera3511852023-06-14 14:12:59 +080012159 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
12160 }
12161 pclose(fp);
12162 }
developer72fb0bb2023-01-11 09:46:29 +080012163
developera3511852023-06-14 14:12:59 +080012164 }
12165 else if ((apIndex == 1) || (apIndex == 5))
12166 {
12167 for (count = 0; count < wifi_count; count++)
12168 {
developer32f2a182023-06-27 19:50:41 +080012169 memcpy(temp[count].cli_OperatingStandard, "a", 1);
12170 temp[count].cli_OperatingStandard[1] = '\0';
12171 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
12172 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080012173 temp[count].cli_BytesSent = 0;
12174 temp[count].cli_BytesReceived = 0;
12175 temp[count].cli_LastDataUplinkRate = 0;
12176 temp[count].cli_LastDataDownlinkRate = 0;
12177 temp[count].cli_PacketsSent = 0;
12178 temp[count].cli_PacketsReceived = 0;
12179 temp[count].cli_ErrorsSent = 0;
12180 }
12181 }
developer72fb0bb2023-01-11 09:46:29 +080012182
developera3511852023-06-14 14:12:59 +080012183 for (count = 0; count < wifi_count; count++)
12184 {
12185 temp[count].cli_Retransmissions = 0;
12186 temp[count].cli_DataFramesSentAck = 0;
12187 temp[count].cli_DataFramesSentNoAck = 0;
12188 temp[count].cli_MinRSSI = 0;
12189 temp[count].cli_MaxRSSI = 0;
12190 strncpy(temp[count].cli_InterferenceSources, "", 64);
12191 memset(temp[count].cli_IPAddress, 0, 64);
12192 temp[count].cli_RetransCount = 0;
12193 temp[count].cli_FailedRetransCount = 0;
12194 temp[count].cli_RetryCount = 0;
12195 temp[count].cli_MultipleRetryCount = 0;
12196 }
12197 *associated_dev_array = temp;
12198 }
12199 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12200 return RETURN_OK;
developerc14d83a2023-06-29 20:09:42 +080012201err:
12202 if (temp)
12203 free(temp);
12204 fclose(fp);
12205 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012206}
12207
developer7e4a2a62023-04-06 19:56:03 +080012208int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +080012209{
developera3511852023-06-14 14:12:59 +080012210 char cmd[MAX_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +080012211 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080012212 int res;
developer32f2a182023-06-27 19:50:41 +080012213 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080012214
developera3511852023-06-14 14:12:59 +080012215 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080012216
developere40952c2023-06-15 18:46:43 +080012217 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +080012218 interface_name);
developere40952c2023-06-15 18:46:43 +080012219 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
12220 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12221 return RETURN_ERR;
12222 }
12223
developera3511852023-06-14 14:12:59 +080012224 _syscmd(cmd, buf, MAX_BUF_SIZE);
developer7e4a2a62023-04-06 19:56:03 +080012225
developer32f2a182023-06-27 19:50:41 +080012226 len = strlen(buf);
12227 if (len >= sizeof(buf)) {
12228 wifi_debug(DEBUG_ERROR, "Unexpected buf size\n");
12229 return RETURN_ERR;
12230 }
12231 strncpy(wifi_status, buf, len); /* TBD: check wifi_status mem lenth and replace with strcpy later */
12232 wifi_status[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012233
developera3511852023-06-14 14:12:59 +080012234 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
12235 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012236}
12237
developer72fb0bb2023-01-11 09:46:29 +080012238static const char *get_line_from_str_buf(const char *buf, char *line)
12239{
developera3511852023-06-14 14:12:59 +080012240 int i;
12241 int n = strlen(buf);
developer72fb0bb2023-01-11 09:46:29 +080012242
developera3511852023-06-14 14:12:59 +080012243 for (i = 0; i < n; i++) {
12244 line[i] = buf[i];
12245 if (buf[i] == '\n') {
12246 line[i] = '\0';
12247 return &buf[i + 1];
12248 }
12249 }
developer72fb0bb2023-01-11 09:46:29 +080012250
developera3511852023-06-14 14:12:59 +080012251 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080012252}
12253
12254INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
12255{
developera3511852023-06-14 14:12:59 +080012256 char interface_name[16] = {0};
12257 FILE *f = NULL;
12258 int auth_temp= -1;
12259 char cmd[256] = {0}, buf[2048] = {0};
12260 char *param = NULL, *value = NULL, *line=NULL;
12261 size_t len = 0;
12262 wifi_associated_dev3_t *dev=NULL;
developer75bd10c2023-06-27 11:34:08 +080012263 int res;
developer72fb0bb2023-01-11 09:46:29 +080012264
developera3511852023-06-14 14:12:59 +080012265 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12266 *associated_dev_array = NULL;
12267 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12268 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080012269
12270 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
12271 if (os_snprintf_error(sizeof(cmd), res)) {
12272 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12273 return RETURN_ERR;
12274 }
12275
developera3511852023-06-14 14:12:59 +080012276 _syscmd(cmd, buf, sizeof(buf));
12277 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080012278
developera3511852023-06-14 14:12:59 +080012279 if (*output_array_size <= 0)
12280 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012281
developera3511852023-06-14 14:12:59 +080012282 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
developer86035662023-06-28 19:21:12 +080012283
12284 if (dev == NULL) {
12285 wifi_debug(DEBUG_ERROR, "calloc fail\n");
12286 return RETURN_ERR;
12287 }
developera3511852023-06-14 14:12:59 +080012288 *associated_dev_array = dev;
developer32f2a182023-06-27 19:50:41 +080012289 res = snprintf(cmd, sizeof(cmd),
12290 "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
developer75bd10c2023-06-27 11:34:08 +080012291 if (os_snprintf_error(sizeof(cmd), res)) {
12292 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12293 return RETURN_ERR;
12294 }
12295
developera3511852023-06-14 14:12:59 +080012296 _syscmd(cmd,buf,sizeof(buf));
12297 f = fopen("/tmp/diagnostic3_devices.txt", "r");
12298 if (f == NULL)
12299 {
12300 *output_array_size=0;
12301 return RETURN_ERR;
12302 }
12303 while ((getline(&line, &len, f)) != -1)
12304 {
12305 param = strtok(line, "=");
developere75ba632023-06-29 16:03:33 +080012306 if (!param)
12307 continue;
developera3511852023-06-14 14:12:59 +080012308 value = strtok(NULL, "=");
developere75ba632023-06-29 16:03:33 +080012309 if (!value)
12310 continue;
developer72fb0bb2023-01-11 09:46:29 +080012311
developera3511852023-06-14 14:12:59 +080012312 if( strcmp("flags",param) == 0 )
12313 {
12314 value[strlen(value)-1]='\0';
12315 if(strstr (value,"AUTHORIZED") != NULL )
12316 {
12317 auth_temp++;
12318 dev[auth_temp].cli_AuthenticationState = 1;
12319 dev[auth_temp].cli_Active = 1;
12320 }
12321 } else if (auth_temp < 0) {
12322 continue;
12323 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
12324 {
12325 value[strlen(value)-1]='\0';
developere75ba632023-06-29 16:03:33 +080012326 if (sscanf(value, "%x:%x:%x:%x:%x:%x",
12327 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
12328 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
12329 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
12330 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
12331 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
12332 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]) == EOF)
12333 continue;
developera3511852023-06-14 14:12:59 +080012334 } else if (strcmp("signal", param) == 0) {
12335 value[strlen(value)-1]='\0';
developere75ba632023-06-29 16:03:33 +080012336 if (sscanf(value, "%d", &dev[auth_temp].cli_RSSI) == EOF)
12337 continue;
developera3511852023-06-14 14:12:59 +080012338 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
12339 }
12340 }
developer0d26f2c2023-05-25 19:46:36 +080012341 if (line)
developera3511852023-06-14 14:12:59 +080012342 free(line);
developerc14d83a2023-06-29 20:09:42 +080012343
12344 if (fclose(f) != 0) {
12345 wifi_debug(DEBUG_ERROR, "fclose fail\n");
12346 }
12347
developera3511852023-06-14 14:12:59 +080012348 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12349 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012350}
developer72fb0bb2023-01-11 09:46:29 +080012351
12352/* getIPAddress function */
12353/**
12354* @description Returning IpAddress of the Matched String
12355*
developer69b61b02023-03-07 17:17:44 +080012356* @param
developer72fb0bb2023-01-11 09:46:29 +080012357* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080012358* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080012359* @return The status of the operation
12360* @retval RETURN_OK if successful
12361* @retval RETURN_ERR if any error is detected
12362*
12363*/
12364
12365INT getIPAddress(char *str,char *ipaddr)
12366{
developera3511852023-06-14 14:12:59 +080012367 FILE *fp = NULL;
12368 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
12369 int LeaseTime = 0,ret = 0;
developer32f2a182023-06-27 19:50:41 +080012370 unsigned long len;
12371
developera3511852023-06-14 14:12:59 +080012372 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
12373 {
12374 return RETURN_ERR;
12375 }
developer72fb0bb2023-01-11 09:46:29 +080012376
developera3511852023-06-14 14:12:59 +080012377 while ( fgets(buf, sizeof(buf), fp)!= NULL )
12378 {
12379 /*
12380 Sample:sss
12381 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
12382 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
12383 */
12384 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
12385 &(LeaseTime),
12386 phyAddr,
12387 ipAddr,
12388 hostName
12389 );
12390 if(ret != 4)
12391 continue;
developer32f2a182023-06-27 19:50:41 +080012392 if (strcmp(str,phyAddr) == 0) {
12393 len = strlen(ipAddr);
12394 strncpy(ipaddr, ipAddr, len);
12395 ipaddr[len] = '\0';
12396 }
developera3511852023-06-14 14:12:59 +080012397 }
developer37646972023-06-29 10:58:43 +080012398 if (fclose(fp) == EOF) {
12399 wifi_debug(DEBUG_ERROR, "fclose fail\n");
12400 return RETURN_ERR;
12401 }
developera3511852023-06-14 14:12:59 +080012402 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012403}
12404
12405/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
12406/**
12407* @description Returning Inactive wireless connected clients informations
12408*
developer69b61b02023-03-07 17:17:44 +080012409* @param
developer72fb0bb2023-01-11 09:46:29 +080012410* @filename Holding private_wifi 2g/5g content files
12411* @associated_dev_array Having inactiv wireless clients informations
12412* @output_array_size Returning Inactive wireless counts
12413* @return The status of the operation
12414* @retval RETURN_OK if successful
12415* @retval RETURN_ERR if any error is detected
12416*
12417*/
12418
12419INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
12420{
developera3511852023-06-14 14:12:59 +080012421 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12422 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
12423 FILE *fp = NULL;
12424 int arr[MACADDRESS_SIZE] = {0};
12425 unsigned char mac[MACADDRESS_SIZE] = {0};
12426 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
developer86035662023-06-28 19:21:12 +080012427 int res;
12428
12429 res = snprintf(buf, sizeof(buf), "cat %s | grep Station | sort | uniq | wc -l",filename);
12430 if (os_snprintf_error(sizeof(buf), res)) {
12431 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12432 return RETURN_ERR;
12433 }
developera3511852023-06-14 14:12:59 +080012434 fp = popen(buf,"r");
12435 if(fp == NULL)
12436 return RETURN_ERR;
12437 else
12438 {
developerd14dff12023-06-28 22:47:44 +080012439 if (fgets(path,sizeof(path),fp) == NULL) {
12440 wifi_debug(DEBUG_ERROR, "fgets fail\n");
12441 pclose(fp);
12442 return RETURN_ERR;
12443 }
developera3511852023-06-14 14:12:59 +080012444 maccount = atoi(path);
12445 }
12446 pclose(fp);
12447 *output_array_size = maccount;
12448 wifi_associated_dev3_t* temp = NULL;
developer9ce44382023-06-28 11:09:37 +080012449 if(*output_array_size > 0 && *output_array_size < MAX_ASSOCIATED_STA_NUM){
12450 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
12451 } else {
12452 return RETURN_ERR;
12453 }
developer37646972023-06-29 10:58:43 +080012454
developera3511852023-06-14 14:12:59 +080012455 *associated_dev_array = temp;
12456 if(temp == NULL)
12457 {
12458 printf("Error Statement. Insufficient memory \n");
12459 return RETURN_ERR;
12460 }
12461 memset(buf,0,sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080012462 res = snprintf(buf, sizeof(buf),
12463 "cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
12464 if (os_snprintf_error(sizeof(buf), res)) {
12465 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12466 return RETURN_ERR;
12467 }
developera3511852023-06-14 14:12:59 +080012468 fp = popen(buf,"r");
12469 if (fp == NULL) {
developer37646972023-06-29 10:58:43 +080012470 res = fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
12471 if (res < 0) {
12472 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
12473 }
developera3511852023-06-14 14:12:59 +080012474 return RETURN_ERR;
12475 }
12476 for(count = 0; count < maccount ; count++)
12477 {
developer37646972023-06-29 10:58:43 +080012478 if (fgets(path,sizeof(path),fp) == NULL)
12479 continue;
developera3511852023-06-14 14:12:59 +080012480 for(i = 0; path[i]!='\n';i++)
12481 str[i]=path[i];
12482 str[i]='\0';
12483 getIPAddress(str,ipaddr);
12484 memset(buf,0,sizeof(buf));
12485 if(strlen(ipaddr) > 0)
12486 {
developer32f2a182023-06-27 19:50:41 +080012487 res = snprintf(buf, sizeof(buf), "ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1", ipaddr);
12488 if (os_snprintf_error(sizeof(buf), res)) {
12489 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer37646972023-06-29 10:58:43 +080012490 break;
developer32f2a182023-06-27 19:50:41 +080012491 }
developera3511852023-06-14 14:12:59 +080012492 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
12493 {
12494 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12495 {
12496 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12497 {
12498 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012499
developera3511852023-06-14 14:12:59 +080012500 }
12501 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
developer37646972023-06-29 10:58:43 +080012502 if (fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],
12503 temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2],
12504 temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4],
12505 temp[count].cli_MACAddress[5]) < 0) {
12506 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
12507 break;
12508 }
developera3511852023-06-14 14:12:59 +080012509 }
12510 temp[count].cli_AuthenticationState = 0; //TODO
12511 temp[count].cli_Active = 0; //TODO
12512 temp[count].cli_SignalStrength = 0;
12513 }
12514 else //Active wireless clients info
12515 {
12516 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12517 {
12518 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12519 {
12520 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012521
developera3511852023-06-14 14:12:59 +080012522 }
12523 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
12524 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]);
12525 }
12526 temp[count].cli_Active = 1;
12527 }
12528 }
12529 memset(ipaddr,0,sizeof(ipaddr));
12530 }
12531 pclose(fp);
12532 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12533 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012534}
12535//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
12536//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
12537//To get Band Steering Capability
12538INT wifi_getBandSteeringCapability(BOOL *support)
12539{
developera3511852023-06-14 14:12:59 +080012540 *support = FALSE;
12541 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012542}
12543
12544
12545//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
12546//To get Band Steering enable status
12547INT wifi_getBandSteeringEnable(BOOL *enable)
12548{
developera3511852023-06-14 14:12:59 +080012549 *enable = FALSE;
12550 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012551}
12552
12553//To turn on/off Band steering
12554INT wifi_setBandSteeringEnable(BOOL enable)
12555{
developera3511852023-06-14 14:12:59 +080012556 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012557}
12558
12559//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
12560//To get Band Steering AP group
12561INT wifi_getBandSteeringApGroup(char *output_ApGroup)
12562{
developera3511852023-06-14 14:12:59 +080012563 if (NULL == output_ApGroup)
12564 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012565
developer32f2a182023-06-27 19:50:41 +080012566 memcpy(output_ApGroup, "1,2", 3);
12567 output_ApGroup[3] = '\0';
developera3511852023-06-14 14:12:59 +080012568 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012569}
12570
12571//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
12572//to set and read the band steering BandUtilizationThreshold parameters
12573INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
12574{
developera3511852023-06-14 14:12:59 +080012575 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012576}
12577
12578INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
12579{
developera3511852023-06-14 14:12:59 +080012580 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012581}
12582
12583//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
12584//to set and read the band steering RSSIThreshold parameters
12585INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
12586{
developera3511852023-06-14 14:12:59 +080012587 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012588}
12589
12590INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
12591{
developera3511852023-06-14 14:12:59 +080012592 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012593}
12594
12595
12596//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
12597//to set and read the band steering physical modulation rate threshold parameters
12598INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
12599{
developera3511852023-06-14 14:12:59 +080012600 //If chip is not support, return -1
12601 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012602}
12603
12604INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
12605{
developera3511852023-06-14 14:12:59 +080012606 //If chip is not support, return -1
12607 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012608}
12609
12610//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
12611//to set and read the inactivity time (in seconds) for steering under overload condition
12612INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
12613{
developera3511852023-06-14 14:12:59 +080012614 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012615}
12616
12617INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
12618{
developera3511852023-06-14 14:12:59 +080012619 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012620}
12621
12622//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
12623//to set and read the inactivity time (in seconds) for steering under Idle condition
12624INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
12625{
developera3511852023-06-14 14:12:59 +080012626 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012627}
12628
12629INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
12630{
developera3511852023-06-14 14:12:59 +080012631 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012632}
12633
12634//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
12635//pClientMAC[64]
12636//pSourceSSIDIndex[64]
12637//pDestSSIDIndex[64]
12638//pSteeringReason[256]
12639INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
12640{
developera3511852023-06-14 14:12:59 +080012641 //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
12642 *pSteeringTime=time(NULL);
12643 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
12644 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012645}
12646
12647INT wifi_ifConfigDown(INT apIndex)
12648{
developera3511852023-06-14 14:12:59 +080012649 INT status = RETURN_OK;
12650 char cmd[64];
developere40952c2023-06-15 18:46:43 +080012651 int res;
developer72fb0bb2023-01-11 09:46:29 +080012652
developere40952c2023-06-15 18:46:43 +080012653 res = snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
12654 if (os_snprintf_error(sizeof(cmd), res)) {
12655 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12656 return RETURN_ERR;
12657 }
developera3511852023-06-14 14:12:59 +080012658 printf("%s: %s\n", __func__, cmd);
12659 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080012660
developera3511852023-06-14 14:12:59 +080012661 return status;
developer72fb0bb2023-01-11 09:46:29 +080012662}
12663
12664INT wifi_ifConfigUp(INT apIndex)
12665{
developera3511852023-06-14 14:12:59 +080012666 char interface_name[16] = {0};
12667 char cmd[128];
12668 char buf[1024];
developere40952c2023-06-15 18:46:43 +080012669 int res;
developer72fb0bb2023-01-11 09:46:29 +080012670
developera3511852023-06-14 14:12:59 +080012671 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12672 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012673 res = snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
12674 if (os_snprintf_error(sizeof(cmd), res)) {
12675 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12676 return RETURN_ERR;
12677 }
developera3511852023-06-14 14:12:59 +080012678 _syscmd(cmd, buf, sizeof(buf));
12679 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012680}
12681
12682//>> Deprecated. Replace with wifi_applyRadioSettings
12683INT wifi_pushBridgeInfo(INT apIndex)
12684{
developerb2977562023-05-24 17:54:12 +080012685 char ip[32] = {0};
12686 char subnet[32] = {0};
12687 char bridge[32] = {0};
12688 char cmd[128] = {0};
12689 char buf[1024] = {0};
developere40952c2023-06-15 18:46:43 +080012690 int res;
developer72fb0bb2023-01-11 09:46:29 +080012691
developerb2977562023-05-24 17:54:12 +080012692 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080012693
developere40952c2023-06-15 18:46:43 +080012694 res = snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
12695 if (os_snprintf_error(sizeof(cmd), res)) {
12696 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12697 return RETURN_ERR;
12698 }
developerb2977562023-05-24 17:54:12 +080012699 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012700
developerb2977562023-05-24 17:54:12 +080012701 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012702}
12703
12704INT wifi_pushChannel(INT radioIndex, UINT channel)
12705{
developera3511852023-06-14 14:12:59 +080012706 char interface_name[16] = {0};
12707 char cmd[128];
12708 char buf[1024];
developere40952c2023-06-15 18:46:43 +080012709 int res;
developer72fb0bb2023-01-11 09:46:29 +080012710
developera3511852023-06-14 14:12:59 +080012711 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12712 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012713 res = snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
12714 if (os_snprintf_error(sizeof(cmd), res)) {
12715 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12716 return RETURN_ERR;
12717 }
developera3511852023-06-14 14:12:59 +080012718 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012719
developera3511852023-06-14 14:12:59 +080012720 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012721}
12722
12723INT wifi_pushChannelMode(INT radioIndex)
12724{
developera3511852023-06-14 14:12:59 +080012725 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
12726 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012727}
12728
12729INT wifi_pushDefaultValues(INT radioIndex)
12730{
developera3511852023-06-14 14:12:59 +080012731 //Apply Comcast specified default radio settings instantly
12732 //AMPDU=1
12733 //AMPDUFrames=32
12734 //AMPDULim=50000
12735 //txqueuelen=1000
developer72fb0bb2023-01-11 09:46:29 +080012736
developera3511852023-06-14 14:12:59 +080012737 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012738}
12739
12740INT wifi_pushTxChainMask(INT radioIndex)
12741{
developera3511852023-06-14 14:12:59 +080012742 //Apply default TxChainMask instantly
12743 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012744}
12745
12746INT wifi_pushRxChainMask(INT radioIndex)
12747{
developera3511852023-06-14 14:12:59 +080012748 //Apply default RxChainMask instantly
12749 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012750}
12751
12752INT wifi_pushSSID(INT apIndex, CHAR *ssid)
12753{
developer7e4a2a62023-04-06 19:56:03 +080012754 INT status;
developer72fb0bb2023-01-11 09:46:29 +080012755
developer7e4a2a62023-04-06 19:56:03 +080012756 status = wifi_setSSIDName(apIndex, ssid);
12757 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080012758
developer7e4a2a62023-04-06 19:56:03 +080012759 return status;
developer72fb0bb2023-01-11 09:46:29 +080012760}
12761
12762INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
12763{
developera3511852023-06-14 14:12:59 +080012764 int ret;
developerc1aa6532023-06-09 09:37:01 +080012765 ret = wifi_setApSsidAdvertisementEnable(apIndex, enable);
12766
12767 return ret;
developer72fb0bb2023-01-11 09:46:29 +080012768}
12769
12770INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
12771{
developera3511852023-06-14 14:12:59 +080012772 time_t now;
developere82c0ca2023-05-10 16:25:35 +080012773
developerd14dff12023-06-28 22:47:44 +080012774 now = time(NULL);
12775 if (now < 0) {
12776 wifi_debug(DEBUG_ERROR, "GET time fail\n");
12777 return RETURN_ERR;
12778 }
developere82c0ca2023-05-10 16:25:35 +080012779 if (now > radio_up_time[radioIndex])
12780 *output = now - radio_up_time[radioIndex];
12781 else {
12782 *output = 0;
12783 return RETURN_ERR;
12784 }
12785
developera3511852023-06-14 14:12:59 +080012786 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012787}
12788
12789INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
12790{
developera3511852023-06-14 14:12:59 +080012791 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012792}
12793
12794INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
12795{
developera3511852023-06-14 14:12:59 +080012796 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012797}
12798
12799//To-do
12800INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
12801{
developera3511852023-06-14 14:12:59 +080012802 char output[16]={'\0'};
12803 char config_file[MAX_BUF_SIZE] = {0};
12804 int res;
developer72fb0bb2023-01-11 09:46:29 +080012805
developera3511852023-06-14 14:12:59 +080012806 if (!output_string)
12807 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012808
developera3511852023-06-14 14:12:59 +080012809 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12810 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012811 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12812 return RETURN_ERR;
12813 }
developera3511852023-06-14 14:12:59 +080012814 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080012815
developera3511852023-06-14 14:12:59 +080012816 if (strlen(output) == 0)
developere40952c2023-06-15 18:46:43 +080012817 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080012818 else if (strncmp(output, "0", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012819 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080012820 else if (strncmp(output, "1", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012821 res = snprintf(output_string, 64, "Optional");
developera3511852023-06-14 14:12:59 +080012822 else if (strncmp(output, "2", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012823 res = snprintf(output_string, 64, "Required");
developera3511852023-06-14 14:12:59 +080012824 else {
12825 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
12826 return RETURN_ERR;
12827 }
developere40952c2023-06-15 18:46:43 +080012828 if (os_snprintf_error(64, res)) {
12829 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12830 return RETURN_ERR;
12831 }
developer72fb0bb2023-01-11 09:46:29 +080012832
developera3511852023-06-14 14:12:59 +080012833 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
12834 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012835}
12836INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
12837{
developera3511852023-06-14 14:12:59 +080012838 struct params params;
12839 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080012840 int res;
developer72fb0bb2023-01-11 09:46:29 +080012841
developera3511852023-06-14 14:12:59 +080012842 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12843 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
12844 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012845
developera3511852023-06-14 14:12:59 +080012846 params.name = "ieee80211w";
12847 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
12848 params.value = "0";
12849 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
12850 params.value = "1";
12851 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
12852 params.value = "2";
12853 else{
12854 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
12855 return RETURN_ERR;
12856 }
developer75bd10c2023-06-27 11:34:08 +080012857
12858 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12859 if (os_snprintf_error(sizeof(config_file), res)) {
12860 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12861 return RETURN_ERR;
12862 }
12863
developera3511852023-06-14 14:12:59 +080012864 wifi_hostapdWrite(config_file, &params, 1);
12865 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
12866 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012867}
12868INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
12869{
developera3511852023-06-14 14:12:59 +080012870 char output[16]={'\0'};
12871 char config_file[MAX_BUF_SIZE] = {0};
12872 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080012873 int res;
developer72fb0bb2023-01-11 09:46:29 +080012874
developera3511852023-06-14 14:12:59 +080012875 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12876 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080012877 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
12878 if (os_snprintf_error(sizeof(config_file), res)) {
12879 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12880 return RETURN_ERR;
12881 }
developera3511852023-06-14 14:12:59 +080012882 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080012883
developera3511852023-06-14 14:12:59 +080012884 if (strncmp(output, "0", 1) == 0)
12885 *output_bool = FALSE;
12886 else if (strncmp(output, "1", 1) == 0)
12887 *output_bool = TRUE;
12888 else if (strncmp(output, "2", 1) == 0)
12889 *output_bool = TRUE;
12890 else if (strncmp(output, "3", 1) == 0)
12891 *output_bool = TRUE;
12892 else
12893 *output_bool = FALSE;
12894 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012895
developera3511852023-06-14 14:12:59 +080012896 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012897}
12898
12899INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
12900{
developera3511852023-06-14 14:12:59 +080012901 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012902}
12903
12904INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
12905{
developera3511852023-06-14 14:12:59 +080012906 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012907}
12908
12909INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
12910{
developera3511852023-06-14 14:12:59 +080012911 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012912}
12913
12914INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
12915{
developera3511852023-06-14 14:12:59 +080012916 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12917 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080012918 char tmp_output[MAX_BUF_SIZE] = {0};
developera3511852023-06-14 14:12:59 +080012919 int res;
developer72fb0bb2023-01-11 09:46:29 +080012920
developera3511852023-06-14 14:12:59 +080012921 if (NULL == output)
12922 return RETURN_ERR;
12923 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12924 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012925 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12926 return RETURN_ERR;
12927 }
developera3511852023-06-14 14:12:59 +080012928 wifi_hostapdRead(config_file,"hw_mode",output,64);
developer72fb0bb2023-01-11 09:46:29 +080012929
developer32f2a182023-06-27 19:50:41 +080012930 if(strcmp(output,"b")==0) {
12931 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,11");
12932 if (os_snprintf_error(sizeof(tmp_output), res)) {
12933 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12934 return RETURN_ERR;
12935 }
12936 } else if (strcmp(output,"a")==0) {
12937 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "6,9,11,12,18,24,36,48,54");
12938 if (os_snprintf_error(sizeof(tmp_output), res)) {
12939 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12940 return RETURN_ERR;
12941 }
12942 } else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) {
12943 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
12944 if (os_snprintf_error(sizeof(tmp_output), res)) {
12945 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12946 return RETURN_ERR;
12947 }
developer75bd10c2023-06-27 11:34:08 +080012948 }
developer32f2a182023-06-27 19:50:41 +080012949 memcpy(output, tmp_output, strlen(tmp_output));
12950 output[strlen(tmp_output)] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012951
developera3511852023-06-14 14:12:59 +080012952 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12953 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012954}
12955
12956INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
12957{
developera3511852023-06-14 14:12:59 +080012958 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12959 char *temp;
developer32f2a182023-06-27 19:50:41 +080012960 char temp_output[128] = {0};
12961 char temp_TransmitRates[128] = {0};
developera3511852023-06-14 14:12:59 +080012962 char config_file[MAX_BUF_SIZE] = {0};
12963 int res;
developer32f2a182023-06-27 19:50:41 +080012964 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080012965
developera3511852023-06-14 14:12:59 +080012966 if (NULL == output)
12967 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012968
developera3511852023-06-14 14:12:59 +080012969 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12970 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012971 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12972 return RETURN_ERR;
12973 }
developera3511852023-06-14 14:12:59 +080012974 wifi_hostapdRead(config_file,"supported_rates",output,64);
developer72fb0bb2023-01-11 09:46:29 +080012975
developera3511852023-06-14 14:12:59 +080012976 if (strlen(output) == 0) {
12977 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
12978 return RETURN_OK;
12979 }
developer32f2a182023-06-27 19:50:41 +080012980 len = strlen(output);
12981 if (len >= sizeof(temp_TransmitRates)) {
12982 wifi_debug(DEBUG_ERROR, "Unexpected strlen(output)\n");
12983 return RETURN_ERR;
12984 }
12985 strncpy(temp_TransmitRates, output, len);
developera3511852023-06-14 14:12:59 +080012986 temp = strtok(temp_TransmitRates," ");
12987 while(temp!=NULL)
12988 {
12989 temp[strlen(temp)-1]=0;
12990 if((temp[0]=='5') && (temp[1]=='\0'))
12991 {
12992 temp="5.5";
12993 }
developer32f2a182023-06-27 19:50:41 +080012994 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp)) {
12995 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12996 return RETURN_ERR;
12997 }
12998 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012999 temp = strtok(NULL," ");
13000 if(temp!=NULL)
13001 {
developer32f2a182023-06-27 19:50:41 +080013002 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
13003 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
13004 return RETURN_ERR;
13005 }
13006 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080013007 }
13008 }
developer32f2a182023-06-27 19:50:41 +080013009 len = strlen(temp_output);
13010 strncpy(output, temp_output, len);
13011 output[len] = '\0';
developera3511852023-06-14 14:12:59 +080013012 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013013
developera3511852023-06-14 14:12:59 +080013014 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013015}
13016
13017INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
13018{
developera3511852023-06-14 14:12:59 +080013019 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013020}
13021
13022
13023INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
13024{
developera3511852023-06-14 14:12:59 +080013025 int i=0;
13026 char *temp;
13027 char temp1[128] = {0};
13028 char temp_output[128] = {0};
13029 char temp_TransmitRates[128] = {0};
13030 struct params params={'\0'};
13031 char config_file[MAX_BUF_SIZE] = {0};
13032 wifi_band band = wifi_index_to_band(wlanIndex);
developer32f2a182023-06-27 19:50:41 +080013033 unsigned long len;
13034 int res;
developer72fb0bb2023-01-11 09:46:29 +080013035
developera3511852023-06-14 14:12:59 +080013036 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13037 if(NULL == output)
13038 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080013039
13040 len = strlen(output);
13041 if (len >= sizeof(temp_TransmitRates)) {
13042 wifi_debug(DEBUG_ERROR, "not enough room in temp_TransmitRates\n");
13043 return RETURN_ERR;
13044 }
13045 strncpy(temp_TransmitRates, output, len);
13046 temp_TransmitRates[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080013047
developera3511852023-06-14 14:12:59 +080013048 for(i=0;i<strlen(temp_TransmitRates);i++)
13049 {
13050 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
13051 {
13052 continue;
13053 }
13054 else
13055 {
13056 return RETURN_ERR;
13057 }
13058 }
developera3511852023-06-14 14:12:59 +080013059 temp = strtok(temp_TransmitRates,",");
13060 while(temp!=NULL)
13061 {
developer32f2a182023-06-27 19:50:41 +080013062 len = strlen(temp);
13063 if (len >= sizeof(temp1)) {
13064 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
13065 return RETURN_ERR;
13066 }
13067 strncpy(temp1, temp, len);
13068 temp1[len] = '\0';
developera3511852023-06-14 14:12:59 +080013069 if(band == band_5)
13070 {
13071 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
13072 {
13073 return RETURN_ERR;
13074 }
13075 }
developer72fb0bb2023-01-11 09:46:29 +080013076
developer32f2a182023-06-27 19:50:41 +080013077 if(strcmp(temp,"5.5")==0) {
13078 strncpy(temp1, "55", 2);
13079 temp1[2] = '\0';
13080 } else {
13081 if ((sizeof(temp1) - strlen(temp1)) <= 1) {
13082 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
13083 return RETURN_ERR;
13084 }
13085 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +080013086 }
developer32f2a182023-06-27 19:50:41 +080013087
13088 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp1)) {
13089 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
13090 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080013091 }
developer32f2a182023-06-27 19:50:41 +080013092 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080013093 temp = strtok(NULL,",");
13094 if(temp!=NULL)
13095 {
developer32f2a182023-06-27 19:50:41 +080013096 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
13097 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
13098 return RETURN_ERR;
13099 }
13100 strncat(temp_output, " ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080013101 }
13102 }
developer32f2a182023-06-27 19:50:41 +080013103 len = strlen(temp_output);
13104 strncpy(output, temp_output, len);
13105 output[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080013106
developera3511852023-06-14 14:12:59 +080013107 params.name = "supported_rates";
13108 params.value = output;
developer72fb0bb2023-01-11 09:46:29 +080013109
developera3511852023-06-14 14:12:59 +080013110 wifi_dbg_printf("\n%s:",__func__);
13111 wifi_dbg_printf("params.value=%s\n",params.value);
developer32f2a182023-06-27 19:50:41 +080013112 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
13113 if (os_snprintf_error(sizeof(config_file), res)) {
13114 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13115 return RETURN_ERR;
13116 }
developera3511852023-06-14 14:12:59 +080013117 wifi_hostapdWrite(config_file,&params,1);
13118 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013119
developera3511852023-06-14 14:12:59 +080013120 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013121}
13122
13123
13124static char *sncopy(char *dst, int dst_sz, const char *src)
13125{
developera3511852023-06-14 14:12:59 +080013126 if (src && dst && dst_sz > 0) {
13127 strncpy(dst, src, dst_sz);
13128 dst[dst_sz - 1] = '\0';
13129 }
13130 return dst;
developer72fb0bb2023-01-11 09:46:29 +080013131}
13132
13133static int util_get_sec_chan_offset(int channel, const char* ht_mode)
13134{
developera3511852023-06-14 14:12:59 +080013135 if (0 == strcmp(ht_mode, "HT40") ||
13136 0 == strcmp(ht_mode, "HT80") ||
13137 0 == strcmp(ht_mode, "HT160")) {
13138 switch (channel) {
13139 case 1 ... 7:
13140 case 36:
13141 case 44:
13142 case 52:
13143 case 60:
13144 case 100:
13145 case 108:
13146 case 116:
13147 case 124:
13148 case 132:
13149 case 140:
13150 case 149:
13151 case 157:
13152 return 1;
13153 case 8 ... 13:
13154 case 40:
13155 case 48:
13156 case 56:
13157 case 64:
13158 case 104:
13159 case 112:
13160 case 120:
13161 case 128:
13162 case 136:
13163 case 144:
13164 case 153:
13165 case 161:
13166 return -1;
13167 default:
13168 return -EINVAL;
13169 }
13170 }
developer72fb0bb2023-01-11 09:46:29 +080013171
developera3511852023-06-14 14:12:59 +080013172 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080013173}
13174
13175static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
13176{
developera3511852023-06-14 14:12:59 +080013177 int idx = channel%8;
13178 if (0 == strcmp(ht_mode, "HT40") ||
13179 0 == strcmp(ht_mode, "HT80") ||
13180 0 == strcmp(ht_mode, "HT160")) {
13181 switch (idx) {
13182 case 1:
13183 return 1;
13184 case 5:
13185 return -1;
13186 default:
13187 return -EINVAL;
13188 }
13189 }
developer72fb0bb2023-01-11 09:46:29 +080013190
developera3511852023-06-14 14:12:59 +080013191 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080013192}
13193static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
13194{
developera3511852023-06-14 14:12:59 +080013195 if (NULL == hw_mode) return;
developer72fb0bb2023-01-11 09:46:29 +080013196
developera3511852023-06-14 14:12:59 +080013197 if (0 == strcmp(hw_mode, "ac"))
13198 sncopy(bw_mode, bw_mode_len, "ht vht");
developer72fb0bb2023-01-11 09:46:29 +080013199
developera3511852023-06-14 14:12:59 +080013200 if (0 == strcmp(hw_mode, "n"))
13201 sncopy(bw_mode, bw_mode_len, "ht");
developer72fb0bb2023-01-11 09:46:29 +080013202
developera3511852023-06-14 14:12:59 +080013203 return;
developer72fb0bb2023-01-11 09:46:29 +080013204}
13205
13206static int util_chan_to_freq(int chan)
13207{
developera3511852023-06-14 14:12:59 +080013208 if (chan == 14)
13209 return 2484;
13210 else if (chan < 14)
13211 return 2407 + chan * 5;
13212 else if (chan >= 182 && chan <= 196)
13213 return 4000 + chan * 5;
13214 else
13215 return 5000 + chan * 5;
13216 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013217}
13218
13219static int util_6G_chan_to_freq(int chan)
13220{
developera3511852023-06-14 14:12:59 +080013221 if (chan)
13222 return 5950 + chan * 5;
13223 else
13224 return 0;
developer69b61b02023-03-07 17:17:44 +080013225
developer72fb0bb2023-01-11 09:46:29 +080013226}
13227const int *util_unii_5g_chan2list(int chan, int width)
13228{
developera3511852023-06-14 14:12:59 +080013229 static const int lists[] = {
13230 // <width>, <chan1>, <chan2>..., 0,
13231 20, 36, 0,
13232 20, 40, 0,
13233 20, 44, 0,
13234 20, 48, 0,
13235 20, 52, 0,
13236 20, 56, 0,
13237 20, 60, 0,
13238 20, 64, 0,
13239 20, 100, 0,
13240 20, 104, 0,
13241 20, 108, 0,
13242 20, 112, 0,
13243 20, 116, 0,
13244 20, 120, 0,
13245 20, 124, 0,
13246 20, 128, 0,
13247 20, 132, 0,
13248 20, 136, 0,
13249 20, 140, 0,
13250 20, 144, 0,
13251 20, 149, 0,
13252 20, 153, 0,
13253 20, 157, 0,
13254 20, 161, 0,
13255 20, 165, 0,
13256 40, 36, 40, 0,
13257 40, 44, 48, 0,
13258 40, 52, 56, 0,
13259 40, 60, 64, 0,
13260 40, 100, 104, 0,
13261 40, 108, 112, 0,
13262 40, 116, 120, 0,
13263 40, 124, 128, 0,
13264 40, 132, 136, 0,
13265 40, 140, 144, 0,
13266 40, 149, 153, 0,
13267 40, 157, 161, 0,
13268 80, 36, 40, 44, 48, 0,
13269 80, 52, 56, 60, 64, 0,
13270 80, 100, 104, 108, 112, 0,
13271 80, 116, 120, 124, 128, 0,
13272 80, 132, 136, 140, 144, 0,
13273 80, 149, 153, 157, 161, 0,
13274 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
13275 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
13276 -1 // final delimiter
13277 };
13278 const int *start;
13279 const int *p;
developer72fb0bb2023-01-11 09:46:29 +080013280
developera3511852023-06-14 14:12:59 +080013281 for (p = lists; *p != -1; p++) {
13282 if (*p == width) {
13283 for (start = ++p; *p != 0; p++) {
13284 if (*p == chan)
13285 return start;
13286 }
13287 }
13288 // move to the end of channel list of given width
13289 while (*p != 0) {
13290 p++;
13291 }
13292 }
developer72fb0bb2023-01-11 09:46:29 +080013293
developera3511852023-06-14 14:12:59 +080013294 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080013295}
13296
13297static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
13298{
developera3511852023-06-14 14:12:59 +080013299 if (NULL == ht_mode)
13300 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013301
developera3511852023-06-14 14:12:59 +080013302 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
13303 const int *chans = util_unii_5g_chan2list(channel, width);
13304 int sum = 0;
13305 int cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013306
developera3511852023-06-14 14:12:59 +080013307 if (NULL == chans)
13308 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013309
developera3511852023-06-14 14:12:59 +080013310 while (*chans) {
13311 sum += *chans;
13312 cnt++;
13313 chans++;
13314 }
13315 if (cnt == 0)
13316 return 0;
13317 return sum / cnt;
developer72fb0bb2023-01-11 09:46:29 +080013318}
13319
13320static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
13321{
developerc14d83a2023-06-29 20:09:42 +080013322 long int width;
developera3511852023-06-14 14:12:59 +080013323 int idx = 0 ;
13324 int centerchan = 0;
13325 int chan_ofs = 1;
developer72fb0bb2023-01-11 09:46:29 +080013326
developerc14d83a2023-06-29 20:09:42 +080013327 if (NULL == ht_mode)
13328 return 0;
13329
13330 if (hal_strtol((char *)(ht_mode + 2), 10, &width) < 0) {
13331 wifi_debug(DEBUG_ERROR, "strtol fail\n");
13332 }
13333
developera3511852023-06-14 14:12:59 +080013334 if (width == 40){
13335 idx = ((channel/4) + chan_ofs)%2;
13336 switch (idx) {
13337 case 0:
13338 centerchan = (channel - 2);
13339 break;
13340 case 1:
13341 centerchan = (channel + 2);
13342 break;
13343 default:
13344 return -EINVAL;
13345 }
13346 }else if (width == 80){
13347 idx = ((channel/4) + chan_ofs)%4;
13348 switch (idx) {
13349 case 0:
13350 centerchan = (channel - 6);
13351 break;
13352 case 1:
13353 centerchan = (channel + 6);
13354 break;
13355 case 2:
13356 centerchan = (channel + 2);
13357 break;
13358 case 3:
13359 centerchan = (channel - 2);
13360 break;
13361 default:
13362 return -EINVAL;
13363 }
13364 }else if (width == 160){
13365 switch (channel) {
13366 case 1 ... 29:
13367 centerchan = 15;
13368 break;
13369 case 33 ... 61:
13370 centerchan = 47;
13371 break;
13372 case 65 ... 93:
13373 centerchan = 79;
13374 break;
13375 case 97 ... 125:
13376 centerchan = 111;
13377 break;
13378 case 129 ... 157:
13379 centerchan = 143;
13380 break;
13381 case 161 ... 189:
13382 centerchan = 175;
13383 break;
13384 case 193 ... 221:
13385 centerchan = 207;
13386 break;
13387 default:
13388 return -EINVAL;
13389 }
13390 }
13391 return centerchan;
developer72fb0bb2023-01-11 09:46:29 +080013392}
13393static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
13394{
developera3511852023-06-14 14:12:59 +080013395 BOOL onlyG, onlyN, onlyA;
13396 CHAR tmp[64];
13397 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
13398 if (ret == RETURN_OK) {
13399 sncopy(hw_mode, hw_mode_size, tmp);
13400 }
13401 return ret;
developer72fb0bb2023-01-11 09:46:29 +080013402}
13403
13404INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
13405{
developera3511852023-06-14 14:12:59 +080013406 // Sample commands:
13407 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
13408 // hostapd_cli -i wifi0 chan_switch 30 2437
13409 int ret = 0;
13410 char center_freq1_str[32] = ""; // center_freq1=%d
13411 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
13412 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
13413 char hw_mode[16] = ""; // n|ac
13414 char bw_mode[16] = ""; // ht|ht vht
13415 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
13416 char interface_name[16] = {0};
13417 int sec_chan_offset;
13418 int width;
13419 char config_file[64] = {0};
13420 char *ext_str = "None";
13421 wifi_band band = band_invalid;
13422 int center_chan = 0;
13423 int center_freq1 = 0;
developere40952c2023-06-15 18:46:43 +080013424 int res;
developer72fb0bb2023-01-11 09:46:29 +080013425
developere40952c2023-06-15 18:46:43 +080013426 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
13427 if (os_snprintf_error(sizeof(config_file), res)) {
13428 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13429 return RETURN_ERR;
13430 }
developer72fb0bb2023-01-11 09:46:29 +080013431
developera3511852023-06-14 14:12:59 +080013432 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
13433 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013434
developera3511852023-06-14 14:12:59 +080013435 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013436
developera3511852023-06-14 14:12:59 +080013437 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013438
developera3511852023-06-14 14:12:59 +080013439 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
developer72fb0bb2023-01-11 09:46:29 +080013440
developera3511852023-06-14 14:12:59 +080013441 // Get radio mode HT20|HT40|HT80 etc.
13442 if (channel){
developere40952c2023-06-15 18:46:43 +080013443 res = snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
13444 if (os_snprintf_error(sizeof(ht_mode), res)) {
13445 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13446 return RETURN_ERR;
13447 }
developer72fb0bb2023-01-11 09:46:29 +080013448
developera3511852023-06-14 14:12:59 +080013449 // Provide bandwith if specified
13450 if (channel_width_MHz > 20) {
13451 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
13452 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
13453 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
developer72fb0bb2023-01-11 09:46:29 +080013454
developere40952c2023-06-15 18:46:43 +080013455 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
developera3511852023-06-14 14:12:59 +080013456 }else if (channel_width_MHz == 20){
developere40952c2023-06-15 18:46:43 +080013457 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
developera3511852023-06-14 14:12:59 +080013458 }
developer72fb0bb2023-01-11 09:46:29 +080013459
developere40952c2023-06-15 18:46:43 +080013460 if (os_snprintf_error(sizeof(opt_chan_info_str), res)) {
13461 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13462 return RETURN_ERR;
13463 }
developer72fb0bb2023-01-11 09:46:29 +080013464
developera3511852023-06-14 14:12:59 +080013465 if (channel_width_MHz > 20) {
13466 if (band == band_6){
13467 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
13468 if(center_chan){
13469 center_freq1 = util_6G_chan_to_freq(center_chan);
13470 }
13471 }else{
13472 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
13473 if(center_chan){
13474 center_freq1 = util_chan_to_freq(center_chan);
13475 }
13476 }
developer69b61b02023-03-07 17:17:44 +080013477
developera3511852023-06-14 14:12:59 +080013478 if (center_freq1)
developere40952c2023-06-15 18:46:43 +080013479 res = snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080013480
developera3511852023-06-14 14:12:59 +080013481 }
developere40952c2023-06-15 18:46:43 +080013482 if (os_snprintf_error(sizeof(center_freq1_str), res)) {
13483 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13484 return RETURN_ERR;
13485 }
developer72fb0bb2023-01-11 09:46:29 +080013486
developera3511852023-06-14 14:12:59 +080013487 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
13488 if (band == band_6){
13489 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
13490 }else{
13491 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
13492 }
developere40952c2023-06-15 18:46:43 +080013493 if (sec_chan_offset != -EINVAL) {
13494 res = snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
13495 if (os_snprintf_error(sizeof(sec_chan_offset_str), res)) {
13496 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13497 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013498 }
developere40952c2023-06-15 18:46:43 +080013499 }
developera3511852023-06-14 14:12:59 +080013500 // Only the first AP, other are hanging on the same radio
13501 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
13502 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080013503 wifi_debug(DEBUG_ERROR,"wifi_setChannel return error.\n");
developera3511852023-06-14 14:12:59 +080013504 return RETURN_ERR;
13505 }
13506 /* wifi_dbg_printf("execute: '%s'\n", cmd);
13507 ret = _syscmd(cmd, buf, sizeof(buf));
13508 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080013509
developera3511852023-06-14 14:12:59 +080013510 ret = wifi_setRadioChannel(radioIndex, channel);
13511 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080013512 wifi_debug(DEBUG_ERROR,"wifi_setRadioChannel return error.\n");
developera3511852023-06-14 14:12:59 +080013513 return RETURN_ERR;
13514 }
developer72fb0bb2023-01-11 09:46:29 +080013515
developera3511852023-06-14 14:12:59 +080013516 if (sec_chan_offset == 1)
13517 ext_str = "Above";
13518 else if (sec_chan_offset == -1)
13519 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080013520
developera3511852023-06-14 14:12:59 +080013521 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080013522
developera3511852023-06-14 14:12:59 +080013523 } else {
13524 if (channel_width_MHz > 20)
13525 ext_str = "Above";
13526 }
developer72fb0bb2023-01-11 09:46:29 +080013527
developera3511852023-06-14 14:12:59 +080013528 wifi_setRadioExtChannel(radioIndex, ext_str);
developer72fb0bb2023-01-11 09:46:29 +080013529
developera3511852023-06-14 14:12:59 +080013530 char mhz_str[16];
developere40952c2023-06-15 18:46:43 +080013531 res = snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
13532 if (os_snprintf_error(sizeof(mhz_str), res)) {
13533 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13534 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013535 }
developera3511852023-06-14 14:12:59 +080013536 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
developer72fb0bb2023-01-11 09:46:29 +080013537
developera3511852023-06-14 14:12:59 +080013538 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013539
developera3511852023-06-14 14:12:59 +080013540 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013541}
13542
13543INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
13544{
developera3511852023-06-14 14:12:59 +080013545 int index = -1;
13546 wifi_neighbor_ap2_t *scan_array = NULL;
13547 char cmd[256]={0};
13548 char buf[128]={0};
13549 char file_name[32] = {0};
13550 char filter_SSID[32] = {0};
13551 char line[256] = {0};
13552 char interface_name[16] = {0};
13553 char *ret = NULL;
13554 int freq=0;
13555 FILE *f = NULL;
developer86035662023-06-28 19:21:12 +080013556 long int channels_num = 0;
developera3511852023-06-14 14:12:59 +080013557 int vht_channel_width = 0;
13558 int get_noise_ret = RETURN_ERR;
13559 bool filter_enable = false;
13560 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
13561 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080013562 int res;
developer32f2a182023-06-27 19:50:41 +080013563 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080013564
developera3511852023-06-14 14:12:59 +080013565 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013566
developere40952c2023-06-15 18:46:43 +080013567 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
13568 if (os_snprintf_error(sizeof(file_name), res)) {
13569 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13570 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080013571 }
developera3511852023-06-14 14:12:59 +080013572 f = fopen(file_name, "r");
13573 if (f != NULL) {
developer86035662023-06-28 19:21:12 +080013574 if (fgets(filter_SSID, sizeof(file_name), f) == NULL) {
13575 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013576 if (fclose(f) != 0) {
13577 wifi_debug(DEBUG_ERROR, "fclose fail\n");
13578 }
developer86035662023-06-28 19:21:12 +080013579 return RETURN_ERR;
13580 }
developera3511852023-06-14 14:12:59 +080013581 if (strlen(filter_SSID) != 0)
13582 filter_enable = true;
developerd14dff12023-06-28 22:47:44 +080013583 if (fclose(f) != 0) {
13584 wifi_debug(DEBUG_ERROR, "fclose fail\n");
13585 return RETURN_ERR;
13586 }
developera3511852023-06-14 14:12:59 +080013587 }
developer72fb0bb2023-01-11 09:46:29 +080013588
developera3511852023-06-14 14:12:59 +080013589 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
13590 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013591
developera3511852023-06-14 14:12:59 +080013592 phyId = radio_index_to_phy(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013593
developere40952c2023-06-15 18:46:43 +080013594 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
13595 if (os_snprintf_error(sizeof(cmd), res)) {
13596 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13597 return RETURN_ERR;
13598 }
developera3511852023-06-14 14:12:59 +080013599 _syscmd(cmd, buf, sizeof(buf));
developer86035662023-06-28 19:21:12 +080013600 if (hal_strtol(buf, 10, &channels_num) < 0) {
13601 wifi_debug(DEBUG_ERROR, "strtol fail\n");
13602 return RETURN_ERR;
13603 }
developer72fb0bb2023-01-11 09:46:29 +080013604
developer32f2a182023-06-27 19:50:41 +080013605 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
developera3511852023-06-14 14:12:59 +080013606 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
developer32f2a182023-06-27 19:50:41 +080013607 if (os_snprintf_error(sizeof(cmd), res)) {
13608 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13609 return RETURN_ERR;
13610 }
13611
developer86035662023-06-28 19:21:12 +080013612 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developera3511852023-06-14 14:12:59 +080013613 if ((f = popen(cmd, "r")) == NULL) {
13614 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
13615 return RETURN_ERR;
13616 }
developer69b61b02023-03-07 17:17:44 +080013617
developera3511852023-06-14 14:12:59 +080013618 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
developer86035662023-06-28 19:21:12 +080013619
13620 if (channels_noise_arr == NULL) {
13621 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13622 goto err;
developer9ce44382023-06-28 11:09:37 +080013623 }
developer86035662023-06-28 19:21:12 +080013624 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
13625
developera3511852023-06-14 14:12:59 +080013626 ret = fgets(line, sizeof(line), f);
13627 while (ret != NULL) {
13628 if(strstr(line, "BSS") != NULL) { // new neighbor info
13629 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
13630 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
13631 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
developer72fb0bb2023-01-11 09:46:29 +080013632
developera3511852023-06-14 14:12:59 +080013633 if (!filter_BSS) {
13634 index++;
13635 wifi_neighbor_ap2_t *tmp;
13636 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
13637 if (tmp == NULL) { // no more memory to use
13638 index--;
13639 wifi_dbg_printf("%s: realloc failed\n", __func__);
13640 break;
13641 }
13642 scan_array = tmp;
13643 }
13644 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +080013645
developera3511852023-06-14 14:12:59 +080013646 filter_BSS = false;
developer86035662023-06-28 19:21:12 +080013647 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
13648 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13649 goto err;
13650 }
developerc79e9172023-06-06 19:48:03 +080013651 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +080013652 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +080013653 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +080013654 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +080013655 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +080013656 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
13657 } else if (strstr(line, "freq") != NULL) {
developer86035662023-06-28 19:21:12 +080013658 if (sscanf(line," freq: %d", &freq) != 1) {
13659 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13660 goto err;
13661 }
developera3511852023-06-14 14:12:59 +080013662 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080013663
developera3511852023-06-14 14:12:59 +080013664 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +080013665 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080013666 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +080013667 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080013668 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +080013669 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080013670 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
13671 }
13672 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +080013673 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080013674 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +080013675 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080013676 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +080013677 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080013678 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
13679 }
developer72fb0bb2023-01-11 09:46:29 +080013680
developera3511852023-06-14 14:12:59 +080013681 scan_array[index].ap_Noise = 0;
13682 if (get_noise_ret == RETURN_OK) {
13683 for (int i = 0; i < channels_num; i++) {
13684 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
13685 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
13686 break;
13687 }
13688 }
13689 }
13690 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +080013691 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
13692 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13693 goto err;
13694 }
developera3511852023-06-14 14:12:59 +080013695 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +080013696 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
13697 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13698 goto err;
13699 }
developera3511852023-06-14 14:12:59 +080013700 } else if (strstr(line,"SSID") != NULL) {
developer86035662023-06-28 19:21:12 +080013701 if (sscanf(line," SSID: %63s", scan_array[index].ap_SSID) != 1) {
13702 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13703 goto err;
13704 }
developera3511852023-06-14 14:12:59 +080013705 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
13706 filter_BSS = true;
13707 }
13708 } else if (strstr(line, "Supported rates") != NULL) {
13709 char SRate[80] = {0}, *tmp = NULL;
13710 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080013711 len = strlen(line);
13712 if (len >= sizeof(SRate)) {
13713 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013714 goto err;
developer32f2a182023-06-27 19:50:41 +080013715 }
13716 strncpy(SRate, line, len);
developera3511852023-06-14 14:12:59 +080013717 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +080013718 if (tmp == NULL)
13719 goto err;
developera3511852023-06-14 14:12:59 +080013720 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +080013721 if (tmp == NULL)
13722 goto err;
13723
developer32f2a182023-06-27 19:50:41 +080013724 len = strlen(tmp);
13725 if (len >= sizeof(buf)) {
13726 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
developer86035662023-06-28 19:21:12 +080013727 goto err;
developer32f2a182023-06-27 19:50:41 +080013728 }
13729 strncpy(buf, tmp, len);
developera3511852023-06-14 14:12:59 +080013730 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +080013731
developera3511852023-06-14 14:12:59 +080013732 tmp = strtok(buf, " \n");
13733 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +080013734 if ((sizeof(SRate) - strlen(SRate)) <= strlen(tmp)) {
13735 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013736 goto err;
developer32f2a182023-06-27 19:50:41 +080013737 }
13738 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +080013739 if (SRate[strlen(SRate) - 1] == '*') {
13740 SRate[strlen(SRate) - 1] = '\0';
13741 }
developer32f2a182023-06-27 19:50:41 +080013742 if ((sizeof(SRate) - strlen(SRate)) <= 1) {
13743 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013744 goto err;
developer32f2a182023-06-27 19:50:41 +080013745 }
13746 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +080013747
developera3511852023-06-14 14:12:59 +080013748 tmp = strtok(NULL, " \n");
13749 }
13750 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +080013751 len = strlen(SRate);
13752 if (len >= sizeof(scan_array[index].ap_SupportedDataTransferRates)) {
13753 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedDataTransferRates\n");
developer86035662023-06-28 19:21:12 +080013754 goto err;
developer32f2a182023-06-27 19:50:41 +080013755 }
13756 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, len);
13757 scan_array[index].ap_SupportedDataTransferRates[len] = '\0';
developera3511852023-06-14 14:12:59 +080013758 } else if (strstr(line, "DTIM") != NULL) {
developer86035662023-06-28 19:21:12 +080013759 if (sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod)) != 1) {
13760 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13761 goto err;
13762 }
developera3511852023-06-14 14:12:59 +080013763 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013764 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
13765 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013766 goto err;
developer32f2a182023-06-27 19:50:41 +080013767 }
13768 strncat(scan_array[index].ap_SupportedStandards, ",ac",
13769 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13770 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
13771 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +080013772 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013773 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 2) {
13774 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013775 goto err;
developer32f2a182023-06-27 19:50:41 +080013776 }
13777 strncat(scan_array[index].ap_SupportedStandards, ",n",
13778 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13779 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
13780 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +080013781 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080013782 if (fgets(line, sizeof(line), f) == NULL) {
13783 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13784 goto err;
13785 }
13786 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
13787 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13788 goto err;
13789 }
developera3511852023-06-14 14:12:59 +080013790 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +080013791 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +080013792 } else {
developere40952c2023-06-15 18:46:43 +080013793 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +080013794 }
developere40952c2023-06-15 18:46:43 +080013795 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
13796 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080013797 goto err;
developer32f2a182023-06-27 19:50:41 +080013798 }
developere40952c2023-06-15 18:46:43 +080013799
developera3511852023-06-14 14:12:59 +080013800 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
13801 continue;
13802 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080013803 if (fgets(line, sizeof(line), f) == NULL) {
13804 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13805 goto err;
13806 }
developer86035662023-06-28 19:21:12 +080013807 if (sscanf(line," * secondary channel offset: %127s", buf) != 1) {
13808 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13809 goto err;
13810 }
developera3511852023-06-14 14:12:59 +080013811 if (!strcmp(buf, "above")) {
13812 //40Mhz +
developere40952c2023-06-15 18:46:43 +080013813 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
developera3511852023-06-14 14:12:59 +080013814 }
13815 else if (!strcmp(buf, "below")) {
13816 //40Mhz -
developere40952c2023-06-15 18:46:43 +080013817 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
developera3511852023-06-14 14:12:59 +080013818 } else {
13819 //20Mhz
developere40952c2023-06-15 18:46:43 +080013820 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
developera3511852023-06-14 14:12:59 +080013821 }
developere40952c2023-06-15 18:46:43 +080013822 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
13823 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080013824 goto err;
developer32f2a182023-06-27 19:50:41 +080013825 }
developere40952c2023-06-15 18:46:43 +080013826
developera3511852023-06-14 14:12:59 +080013827 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
13828 continue;
13829 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013830 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
13831 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013832 goto err;
developer32f2a182023-06-27 19:50:41 +080013833 }
13834 strncat(scan_array[index].ap_SupportedStandards, ",ax",
13835 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13836 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
13837 scan_array[index].ap_OperatingStandards[2] = '\0';
developerc14d83a2023-06-29 20:09:42 +080013838 if (fgets(line, sizeof(line), f) == NULL) {
13839 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13840 goto err;
13841 }
developera3511852023-06-14 14:12:59 +080013842 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +080013843 if (strstr(line, "HE40/2.4GHz") != NULL) {
13844 len = strlen("11AXHE40PLUS");
13845 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
13846 } else {
13847 len = strlen("11AXHE20");
13848 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
13849 }
13850 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080013851 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
13852 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013853 len = strlen("11AXHE80");
13854 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
13855 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080013856 ret = fgets(line, sizeof(line), f);
13857 } else
13858 continue;
developer32f2a182023-06-27 19:50:41 +080013859 if (strstr(line, "HE160/5GHz") != NULL) {
13860 len = strlen("11AXHE160");
13861 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
13862 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
13863 }
developera3511852023-06-14 14:12:59 +080013864 }
13865 continue;
13866 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013867 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
13868 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080013869 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013870 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
13871 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080013872 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +080013873 if (sscanf(line, " * Group cipher: %63s", scan_array[index].ap_EncryptionMode) != 1) {
13874 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13875 goto err;
13876 }
developera3511852023-06-14 14:12:59 +080013877 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +080013878 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
13879 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +080013880 }
13881 }
13882 ret = fgets(line, sizeof(line), f);
13883 }
developer72fb0bb2023-01-11 09:46:29 +080013884
developera3511852023-06-14 14:12:59 +080013885 if (!filter_BSS) {
13886 *output_array_size = index + 1;
13887 } else {
13888 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
13889 *output_array_size = index;
13890 }
13891 *neighbor_ap_array = scan_array;
13892 pclose(f);
13893 free(channels_noise_arr);
13894 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13895 return RETURN_OK;
developer86035662023-06-28 19:21:12 +080013896err:
developerc14d83a2023-06-29 20:09:42 +080013897 pclose(f);
developer86035662023-06-28 19:21:12 +080013898 free(channels_noise_arr);
developerc14d83a2023-06-29 20:09:42 +080013899 if (scan_array)
13900 free(scan_array);
developer86035662023-06-28 19:21:12 +080013901 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013902}
13903
13904INT wifi_getApAssociatedDeviceStats(
developera3511852023-06-14 14:12:59 +080013905 INT apIndex,
13906 mac_address_t *clientMacAddress,
13907 wifi_associated_dev_stats_t *associated_dev_stats,
13908 u64 *handle)
developer72fb0bb2023-01-11 09:46:29 +080013909{
developera3511852023-06-14 14:12:59 +080013910 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
13911 char interface_name[50] = {0};
13912 char cmd[1024] = {0};
13913 char mac_str[18] = {0};
13914 char *key = NULL;
13915 char *val = NULL;
13916 FILE *f = NULL;
13917 char *line = NULL;
13918 size_t len = 0;
developer75bd10c2023-06-27 11:34:08 +080013919 int res;
developer72fb0bb2023-01-11 09:46:29 +080013920
developera3511852023-06-14 14:12:59 +080013921 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
13922 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
13923 return RETURN_ERR;
13924 }
developer72fb0bb2023-01-11 09:46:29 +080013925
developer32f2a182023-06-27 19:50:41 +080013926 res = snprintf(mac_str, sizeof(mac_str), "%x:%x:%x:%x:%x:%x",
13927 (*clientMacAddress)[0], (*clientMacAddress)[1], (*clientMacAddress)[2],
13928 (*clientMacAddress)[3], (*clientMacAddress)[4], (*clientMacAddress)[5]);
developer75bd10c2023-06-27 11:34:08 +080013929 if (os_snprintf_error(sizeof(mac_str), res)) {
13930 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13931 return RETURN_ERR;
13932 }
13933
13934 res = snprintf(cmd, sizeof(cmd), "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
13935 if (os_snprintf_error(sizeof(cmd), res)) {
13936 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13937 return RETURN_ERR;
13938 }
13939
developera3511852023-06-14 14:12:59 +080013940 if((f = popen(cmd, "r")) == NULL) {
13941 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
13942 return RETURN_ERR;
13943 }
developer72fb0bb2023-01-11 09:46:29 +080013944
developera3511852023-06-14 14:12:59 +080013945 while ((getline(&line, &len, f)) != -1) {
13946 key = strtok(line,":");
developer37646972023-06-29 10:58:43 +080013947 if (key == NULL)
13948 continue;
developera3511852023-06-14 14:12:59 +080013949 val = strtok(NULL,":");
developer37646972023-06-29 10:58:43 +080013950 if (val == NULL)
13951 continue;
developer72fb0bb2023-01-11 09:46:29 +080013952
developerb61d3362023-06-29 14:10:19 +080013953 if(!strncmp(key,"rx bytes",8))
13954 if (sscanf(val, "%llu", &dev_stats->cli_rx_bytes) != 1) {
13955 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
developer37646972023-06-29 10:58:43 +080013956 continue;
developerb61d3362023-06-29 14:10:19 +080013957 }
13958 if(!strncmp(key,"tx bytes",8))
13959 if (sscanf(val, "%llu", &dev_stats->cli_tx_bytes) != 1) {
13960 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
developer37646972023-06-29 10:58:43 +080013961 continue;
developerb61d3362023-06-29 14:10:19 +080013962 }
developer37646972023-06-29 10:58:43 +080013963 if(!strncmp(key,"rx packets",10)) {
13964 if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
13965 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13966 continue;
13967 }
13968 }
13969 if(!strncmp(key,"tx packets",10)) {
13970 if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
13971 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13972 continue;
13973 }
13974 }
13975 if(!strncmp(key,"tx retries",10)) {
13976 if (sscanf(val, "%llu", &dev_stats->cli_tx_retries) == EOF) {
13977 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13978 continue;
13979 }
13980 }
13981 if(!strncmp(key,"tx failed",9)) {
13982 if (sscanf(val, "%llu", &dev_stats->cli_tx_errors) == EOF) {
13983 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13984 continue;
13985 }
13986 }
13987 if(!strncmp(key,"rx drop misc",13)) {
13988 if (sscanf(val, "%llu", &dev_stats->cli_rx_errors) == EOF) {
13989 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13990 continue;
13991 }
developerd14dff12023-06-28 22:47:44 +080013992 }
developera3511852023-06-14 14:12:59 +080013993 if(!strncmp(key,"rx bitrate",10)) {
13994 val = strtok(val, " ");
developerc14d83a2023-06-29 20:09:42 +080013995 if (val == NULL)
13996 continue;
developer37646972023-06-29 10:58:43 +080013997 if (sscanf(val, "%lf", &dev_stats->cli_rx_rate) == EOF) {
13998 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13999 continue;
14000 }
developera3511852023-06-14 14:12:59 +080014001 }
14002 if(!strncmp(key,"tx bitrate",10)) {
14003 val = strtok(val, " ");
developerc14d83a2023-06-29 20:09:42 +080014004 if (val == NULL)
14005 continue;
developer37646972023-06-29 10:58:43 +080014006 if (sscanf(val, "%lf", &dev_stats->cli_tx_rate) == EOF) {
14007 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
14008 continue;
14009 }
developera3511852023-06-14 14:12:59 +080014010 }
14011 }
14012 free(line);
14013 pclose(f);
14014 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014015}
14016
14017INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
14018{
developera3511852023-06-14 14:12:59 +080014019 char interface_name[IF_NAME_SIZE] = {0};
14020 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
developere40952c2023-06-15 18:46:43 +080014021 int res;
developer72fb0bb2023-01-11 09:46:29 +080014022
developera3511852023-06-14 14:12:59 +080014023 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080014024
developera3511852023-06-14 14:12:59 +080014025 if (NULL == output_string)
14026 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014027
developera3511852023-06-14 14:12:59 +080014028 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14029 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080014030
developere40952c2023-06-15 18:46:43 +080014031 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
14032 if (os_snprintf_error(sizeof(cmd), res)) {
14033 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14034 return RETURN_ERR;
14035 }
developera3511852023-06-14 14:12:59 +080014036 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080014037
developera3511852023-06-14 14:12:59 +080014038 //size of SSID name restricted to value less than 32 bytes
developere40952c2023-06-15 18:46:43 +080014039 res = snprintf(output_string, 32, "%s", buf);
14040 if (os_snprintf_error(32, res)) {
14041 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14042 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014043 }
developera3511852023-06-14 14:12:59 +080014044 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014045
developera3511852023-06-14 14:12:59 +080014046 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014047}
14048
14049INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
14050{
developer2edaf012023-05-24 14:24:53 +080014051 char *mac_arry_buf = NULL;
14052 INT policy = -1;
14053 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080014054
developer2edaf012023-05-24 14:24:53 +080014055 mac_arry_buf = malloc(buf_size);
14056 if (!mac_arry_buf) {
14057 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080014058 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080014059 }
14060 memset(mac_arry_buf, 0, buf_size);
14061 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
14062 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
14063 goto err;
14064 }
14065 /*
14066 mtk format to get policy:
14067 "policy=1
14068 00:11:22:33:44:55
14069 00:11:22:33:44:66
14070 "
14071 */
14072 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
14073 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
14074 goto err;
14075 }
14076 if (!(policy >=0 && policy <= 2)){
14077 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
14078 goto err;
14079 }
14080 *output_filterMode = policy;
14081 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
14082 free(mac_arry_buf);
14083 mac_arry_buf = NULL;
14084 return RETURN_OK;
14085err:
14086 free(mac_arry_buf);
14087 mac_arry_buf = NULL;
14088 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
14089 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014090}
14091
developer2edaf012023-05-24 14:24:53 +080014092
developer72fb0bb2023-01-11 09:46:29 +080014093INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
14094{
developera3511852023-06-14 14:12:59 +080014095 FILE *fp = NULL;
14096 char str[MAX_BUF_SIZE] = {0};
14097 int wificlientindex = 0 ;
14098 int count = 0;
14099 int signalstrength = 0;
14100 int arr[MACADDRESS_SIZE] = {0};
14101 unsigned char mac[MACADDRESS_SIZE] = {0};
14102 UINT wifi_count = 0;
14103 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014104 int res;
developer72fb0bb2023-01-11 09:46:29 +080014105
developera3511852023-06-14 14:12:59 +080014106 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14107 *output_array_size = 0;
14108 *associated_dev_array = NULL;
14109 char interface_name[50] = {0};
developer72fb0bb2023-01-11 09:46:29 +080014110
developera3511852023-06-14 14:12:59 +080014111 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
14112 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
14113 return RETURN_ERR;
14114 }
developer72fb0bb2023-01-11 09:46:29 +080014115
developer75bd10c2023-06-27 11:34:08 +080014116 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
14117 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14118 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14119 return RETURN_ERR;
14120 }
developera3511852023-06-14 14:12:59 +080014121 fp = popen(pipeCmd, "r");
14122 if (fp == NULL)
14123 {
14124 printf("Failed to run command inside function %s\n",__FUNCTION__ );
14125 return RETURN_ERR;
14126 }
developer72fb0bb2023-01-11 09:46:29 +080014127
developera3511852023-06-14 14:12:59 +080014128 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080014129 if (fgets(str, sizeof(str)-1, fp) == NULL) {
14130 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14131 pclose(fp);
14132 return RETURN_ERR;
14133 }
developera3511852023-06-14 14:12:59 +080014134 wifi_count = (unsigned int) atoi ( str );
14135 *output_array_size = wifi_count;
14136 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
14137 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014138
developera3511852023-06-14 14:12:59 +080014139 if(wifi_count == 0)
14140 {
14141 return RETURN_OK;
14142 }
14143 else
14144 {
14145 wifi_associated_dev2_t* temp = NULL;
14146 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
14147 *associated_dev_array = temp;
14148 if(temp == NULL)
14149 {
14150 printf("Error Statement. Insufficient memory \n");
14151 return RETURN_ERR;
14152 }
developer72fb0bb2023-01-11 09:46:29 +080014153
developere40952c2023-06-15 18:46:43 +080014154 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
14155 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14156 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14157 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014158 }
developere40952c2023-06-15 18:46:43 +080014159
developera3511852023-06-14 14:12:59 +080014160 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080014161
developera3511852023-06-14 14:12:59 +080014162 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
14163 if(fp == NULL)
14164 {
14165 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
14166 return RETURN_ERR;
14167 }
developere75ba632023-06-29 16:03:33 +080014168 if (fclose(fp) == EOF) {
14169 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
14170 return RETURN_ERR;
14171 }
developer72fb0bb2023-01-11 09:46:29 +080014172
developer86035662023-06-28 19:21:12 +080014173 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
14174 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14175 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14176 return RETURN_ERR;
14177 }
developera3511852023-06-14 14:12:59 +080014178 fp = popen(pipeCmd, "r");
14179 if(fp)
14180 {
14181 for(count =0 ; count < wifi_count; count++)
14182 {
developer86035662023-06-28 19:21:12 +080014183 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14184 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14185 pclose(fp);
14186 return RETURN_ERR;
14187 }
developera3511852023-06-14 14:12:59 +080014188 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
14189 {
14190 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
14191 {
14192 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080014193
developera3511852023-06-14 14:12:59 +080014194 }
14195 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
14196 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]);
14197 }
14198 temp[count].cli_AuthenticationState = 1; //TODO
14199 temp[count].cli_Active = 1; //TODO
14200 }
14201 pclose(fp);
14202 }
developer72fb0bb2023-01-11 09:46:29 +080014203
developera3511852023-06-14 14:12:59 +080014204 //Updating RSSI per client
developer86035662023-06-28 19:21:12 +080014205 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
14206 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14207 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14208 return RETURN_ERR;
14209 }
14210
developera3511852023-06-14 14:12:59 +080014211 fp = popen(pipeCmd, "r");
14212 if(fp)
14213 {
14214 pclose(fp);
14215 }
14216 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
14217 if(fp)
14218 {
14219 for(count =0 ; count < wifi_count ;count++)
14220 {
developer86035662023-06-28 19:21:12 +080014221 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14222 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14223 pclose(fp);
14224 return RETURN_ERR;
14225 }
developera3511852023-06-14 14:12:59 +080014226 signalstrength = atoi(str);
14227 temp[count].cli_RSSI = signalstrength;
14228 }
14229 pclose(fp);
14230 }
developer72fb0bb2023-01-11 09:46:29 +080014231
14232
developera3511852023-06-14 14:12:59 +080014233 //LastDataDownlinkRate
developer86035662023-06-28 19:21:12 +080014234 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
14235 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14236 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14237 return RETURN_ERR;
14238 }
developera3511852023-06-14 14:12:59 +080014239 fp = popen(pipeCmd, "r");
14240 if (fp)
14241 {
14242 pclose(fp);
14243 }
14244 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
14245 if (fp)
14246 {
developerc14d83a2023-06-29 20:09:42 +080014247 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080014248 for (count = 0; count < wifi_count; count++)
14249 {
developer86035662023-06-28 19:21:12 +080014250 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14251 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14252 pclose(fp);
14253 return RETURN_ERR;
14254 }
developerc14d83a2023-06-29 20:09:42 +080014255 if (hal_strtoul(str, 10, &tmp_u) < 0) {
14256 wifi_debug(DEBUG_ERROR, "strtol fail\n");
14257 }
14258 temp[count].cli_LastDataDownlinkRate = tmp_u;
developera3511852023-06-14 14:12:59 +080014259 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
14260 }
14261 pclose(fp);
14262 }
developer72fb0bb2023-01-11 09:46:29 +080014263
developera3511852023-06-14 14:12:59 +080014264 //LastDataUplinkRate
developer86035662023-06-28 19:21:12 +080014265 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
14266 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14267 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14268 return RETURN_ERR;
14269 }
developera3511852023-06-14 14:12:59 +080014270 fp = popen(pipeCmd, "r");
14271 if (fp)
14272 {
14273 pclose(fp);
14274 }
14275 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
14276 if (fp)
14277 {
developerc14d83a2023-06-29 20:09:42 +080014278 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080014279 for (count = 0; count < wifi_count; count++)
14280 {
developer86035662023-06-28 19:21:12 +080014281 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14282 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14283 pclose(fp);
14284 return RETURN_ERR;
14285 }
developerc14d83a2023-06-29 20:09:42 +080014286 if (hal_strtoul(str, 10, &tmp_u) < 0) {
14287 wifi_debug(DEBUG_ERROR, "strtol fail\n");
14288 }
14289 temp[count].cli_LastDataUplinkRate = tmp_u;
developera3511852023-06-14 14:12:59 +080014290 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
14291 }
14292 pclose(fp);
14293 }
14294 }
14295 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14296 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014297
14298}
14299
14300INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
14301{
developera3511852023-06-14 14:12:59 +080014302 FILE *fp = NULL;
14303 char interface_name[50] = {0};
14304 char pipeCmd[128] = {0};
14305 char str[256] = {0};
14306 wifi_ssidTrafficStats2_t *out = output_struct;
developer75bd10c2023-06-27 11:34:08 +080014307 int res;
developerd14dff12023-06-28 22:47:44 +080014308 unsigned int recv;
developer72fb0bb2023-01-11 09:46:29 +080014309
developera3511852023-06-14 14:12:59 +080014310 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
14311 if (!output_struct)
14312 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014313
developera3511852023-06-14 14:12:59 +080014314 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
14315 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
14316 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080014317 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /proc/net/dev | grep %s", interface_name);
14318 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14319 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14320 return RETURN_ERR;
14321 }
developer72fb0bb2023-01-11 09:46:29 +080014322
developera3511852023-06-14 14:12:59 +080014323 fp = popen(pipeCmd, "r");
14324 if (fp == NULL) {
developer86035662023-06-28 19:21:12 +080014325 wifi_debug(DEBUG_ERROR, "%s: popen failed\n", __func__);
14326 return RETURN_ERR;
14327 }
14328 if (fgets(str, sizeof(str), fp) == NULL) {
14329 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14330 pclose(fp);
developera3511852023-06-14 14:12:59 +080014331 return RETURN_ERR;
14332 }
developer86035662023-06-28 19:21:12 +080014333
developera3511852023-06-14 14:12:59 +080014334 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014335
developera3511852023-06-14 14:12:59 +080014336 if (strlen(str) == 0) // interface not exist
14337 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014338
developerd14dff12023-06-28 22:47:44 +080014339 recv = sscanf(str, "%*[^:]: %lu %lu %lu %lu %*d %*d %*d %*d %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
developera3511852023-06-14 14:12:59 +080014340 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
developerd14dff12023-06-28 22:47:44 +080014341 if (recv != 8) {
14342 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
14343 return RETURN_ERR;
14344 }
developer72fb0bb2023-01-11 09:46:29 +080014345
developera3511852023-06-14 14:12:59 +080014346 memset(str, 0, sizeof(str));
developer75bd10c2023-06-27 11:34:08 +080014347
14348 res = snprintf(pipeCmd, sizeof(pipeCmd), "tail -n1 /proc/net/netstat");
14349 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14350 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14351 return RETURN_ERR;
14352 }
developera3511852023-06-14 14:12:59 +080014353 fp = popen(pipeCmd, "r");
14354 if (fp == NULL) {
developer75bd10c2023-06-27 11:34:08 +080014355 wifi_debug(DEBUG_ERROR, "popen failed\n");
developera3511852023-06-14 14:12:59 +080014356 return RETURN_ERR;
14357 }
developer86035662023-06-28 19:21:12 +080014358
14359 if (fgets(str, sizeof(str), fp) == NULL) {
14360 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14361 pclose(fp);
14362 return RETURN_ERR;
14363 }
developer72fb0bb2023-01-11 09:46:29 +080014364
developer37646972023-06-29 10:58:43 +080014365 if (sscanf(str, "%*[^:]: %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
14366 &out->ssid_BroadcastPacketsSent) == EOF)
14367 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developera3511852023-06-14 14:12:59 +080014368 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014369
developera3511852023-06-14 14:12:59 +080014370 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
14371 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +080014372
developera3511852023-06-14 14:12:59 +080014373 // Not supported
14374 output_struct->ssid_RetransCount = 0;
14375 output_struct->ssid_FailedRetransCount = 0;
14376 output_struct->ssid_RetryCount = 0;
14377 output_struct->ssid_MultipleRetryCount = 0;
14378 output_struct->ssid_ACKFailureCount = 0;
14379 output_struct->ssid_AggregatedPacketCount = 0;
developer72fb0bb2023-01-11 09:46:29 +080014380
developera3511852023-06-14 14:12:59 +080014381 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014382}
14383
14384//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).
14385INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
14386{
developera3511852023-06-14 14:12:59 +080014387 char output_val[16]={'\0'};
14388 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080014389 int res;
developer72fb0bb2023-01-11 09:46:29 +080014390
developera3511852023-06-14 14:12:59 +080014391 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14392 if (!output)
14393 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080014394
14395 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14396 if (os_snprintf_error(sizeof(config_file), res)) {
14397 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14398 return RETURN_ERR;
14399 }
developera3511852023-06-14 14:12:59 +080014400 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
developer72fb0bb2023-01-11 09:46:29 +080014401
developera3511852023-06-14 14:12:59 +080014402 if( strcmp(output_val,"1") == 0 )
14403 *output = TRUE;
14404 else
14405 *output = FALSE;
14406 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014407
developera3511852023-06-14 14:12:59 +080014408 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014409}
14410
14411INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
14412{
developera3511852023-06-14 14:12:59 +080014413 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14414 char string[MAX_BUF_SIZE]={'\0'};
14415 char config_file[MAX_BUF_SIZE] = {0};
14416 struct params params;
developer75bd10c2023-06-27 11:34:08 +080014417 int res;
developer72fb0bb2023-01-11 09:46:29 +080014418
developer32f2a182023-06-27 19:50:41 +080014419 string[0] = enable == TRUE ? '1' : '0';
developer72fb0bb2023-01-11 09:46:29 +080014420
developera3511852023-06-14 14:12:59 +080014421 params.name = "ap_isolate";
14422 params.value = string;
developer72fb0bb2023-01-11 09:46:29 +080014423
developer75bd10c2023-06-27 11:34:08 +080014424 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14425 if (os_snprintf_error(sizeof(config_file), res)) {
14426 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14427 return RETURN_ERR;
14428 }
14429
developera3511852023-06-14 14:12:59 +080014430 wifi_hostapdWrite(config_file,&params,1);
14431 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014432
developera3511852023-06-14 14:12:59 +080014433 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014434}
14435
14436INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
14437{
developera3511852023-06-14 14:12:59 +080014438 char mgmtpwr_file[32] = {0};
14439 char cmd[64] = {0};
14440 char buf[32]={0};
developere40952c2023-06-15 18:46:43 +080014441 int res;
developerc14d83a2023-06-29 20:09:42 +080014442 long int tmp;
developera1255e42023-05-13 17:45:02 +080014443
developera3511852023-06-14 14:12:59 +080014444 if (NULL == output_dBm)
14445 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080014446 res = snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
14447 if (os_snprintf_error(sizeof(mgmtpwr_file), res)) {
14448 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14449 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014450 }
developere40952c2023-06-15 18:46:43 +080014451
14452 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
14453 if (os_snprintf_error(sizeof(cmd), res)) {
14454 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14455 return RETURN_ERR;
14456 }
developera3511852023-06-14 14:12:59 +080014457 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +080014458 if (strlen(buf) > 0) {
14459 if (hal_strtol(buf, 10, &tmp) < 0) {
14460 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080014461 }
developerc14d83a2023-06-29 20:09:42 +080014462 *output_dBm = tmp;
developerd14dff12023-06-28 22:47:44 +080014463 } else
developera1255e42023-05-13 17:45:02 +080014464 *output_dBm = 23;
developera3511852023-06-14 14:12:59 +080014465 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014466}
14467
14468INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
14469{
developera1255e42023-05-13 17:45:02 +080014470 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080014471 char mgmt_pwr_file[128]={0};
14472 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080014473 int if_idx, ret = 0;
14474 struct nl_msg *msg = NULL;
14475 struct nlattr * msg_data = NULL;
14476 struct mtk_nl80211_param param;
14477 struct unl unl_ins;
14478 char power[16] = {0};
developere40952c2023-06-15 18:46:43 +080014479 int res;
developera1255e42023-05-13 17:45:02 +080014480
14481 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14482
14483 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
14484 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080014485
14486 if_idx = if_nametoindex(interface_name);
14487 /*init mtk nl80211 vendor cmd*/
14488 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
14489 param.if_type = NL80211_ATTR_IFINDEX;
14490 param.if_idx = if_idx;
14491
14492 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
14493 if (ret) {
14494 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
14495 return RETURN_ERR;
14496 }
14497
14498 /*add mtk vendor cmd data*/
developere40952c2023-06-15 18:46:43 +080014499 res = snprintf(power, sizeof(power), "%d", dBm);
14500 if (os_snprintf_error(sizeof(power), res)) {
14501 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14502 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014503 }
developere40952c2023-06-15 18:46:43 +080014504
developerfead3972023-05-25 20:15:02 +080014505 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
14506 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
14507 nlmsg_free(msg);
14508 goto err;
14509 }
14510
14511 /*send mtk nl80211 vendor msg*/
14512 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
14513 if (ret) {
14514 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
14515 goto err;
14516 }
14517
14518 /*deinit mtk nl80211 vendor msg*/
14519 mtk_nl80211_deint(&unl_ins);
14520 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
14521
developere40952c2023-06-15 18:46:43 +080014522 res = snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
14523 if (os_snprintf_error(sizeof(mgmt_pwr_file), res)) {
14524 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14525 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014526 }
developere40952c2023-06-15 18:46:43 +080014527
developera1255e42023-05-13 17:45:02 +080014528 f = fopen(mgmt_pwr_file, "w");
14529 if (f == NULL) {
developerc14d83a2023-06-29 20:09:42 +080014530 wifi_debug(DEBUG_ERROR, "%s: fopen failed\n", __func__);
developera1255e42023-05-13 17:45:02 +080014531 return RETURN_ERR;
14532 }
14533 fprintf(f, "%d", dBm);
developerc14d83a2023-06-29 20:09:42 +080014534 if (fclose(f) == EOF)
14535 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
14536
developer72fb0bb2023-01-11 09:46:29 +080014537 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080014538err:
14539 mtk_nl80211_deint(&unl_ins);
14540 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
14541 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014542}
14543INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
14544{
developera3511852023-06-14 14:12:59 +080014545 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014546}
14547INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
14548{
developera3511852023-06-14 14:12:59 +080014549 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014550}
14551INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
14552{
developera3511852023-06-14 14:12:59 +080014553 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014554}
14555INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
14556{
developera3511852023-06-14 14:12:59 +080014557 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014558}
14559INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
14560{
developera3511852023-06-14 14:12:59 +080014561 char config_file[MAX_BUF_SIZE] = {0};
14562 struct params list;
developere40952c2023-06-15 18:46:43 +080014563 int res;
developer72fb0bb2023-01-11 09:46:29 +080014564
developera3511852023-06-14 14:12:59 +080014565 list.name = "bss_transition";
14566 list.value = activate?"1":"0";
developere40952c2023-06-15 18:46:43 +080014567 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
14568 if (os_snprintf_error(sizeof(config_file), res)) {
14569 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14570 return RETURN_ERR;
14571 }
developera3511852023-06-14 14:12:59 +080014572 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080014573
developera3511852023-06-14 14:12:59 +080014574 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014575}
14576wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
14577
14578void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
14579{
developera3511852023-06-14 14:12:59 +080014580 return;
developer72fb0bb2023-01-11 09:46:29 +080014581}
14582
14583INT wifi_setApCsaDeauth(INT apIndex, INT mode)
14584{
developera3511852023-06-14 14:12:59 +080014585 // TODO Implement me!
14586 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014587}
14588
14589INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
14590{
developera3511852023-06-14 14:12:59 +080014591 char file_name[128] = {0};
14592 FILE *f = NULL;
14593 int max_num_radios = 0;
developer75bd10c2023-06-27 11:34:08 +080014594 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080014595
developera3511852023-06-14 14:12:59 +080014596 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014597
developera3511852023-06-14 14:12:59 +080014598 wifi_getMaxRadioNumber(&max_num_radios);
14599 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
14600 for (int index = 0; index < max_num_radios; index++) {
developere40952c2023-06-15 18:46:43 +080014601 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
14602 if (os_snprintf_error(sizeof(file_name), res)) {
14603 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14604 return RETURN_ERR;
14605 }
14606
developera3511852023-06-14 14:12:59 +080014607 f = fopen(file_name, "w");
14608 if (f == NULL)
14609 return RETURN_ERR;
14610 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080014611 if (mode) {
14612 ret = fprintf(f, "%s", essid);
14613 if (ret < 0)
14614 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
14615 }
developer72fb0bb2023-01-11 09:46:29 +080014616
developerd14dff12023-06-28 22:47:44 +080014617 if (fclose(f) != 0) {
14618 wifi_debug(DEBUG_ERROR, "fclose fail\n");
14619 return RETURN_ERR;
14620 }
developera3511852023-06-14 14:12:59 +080014621 }
14622 } else { // special case, need to set AP's SSID as filter for each radio.
developere40952c2023-06-15 18:46:43 +080014623 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
14624 if (os_snprintf_error(sizeof(file_name), res)) {
14625 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14626 return RETURN_ERR;
14627 }
14628
developera3511852023-06-14 14:12:59 +080014629 f = fopen(file_name, "w");
14630 if (f == NULL)
14631 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014632
developera3511852023-06-14 14:12:59 +080014633 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080014634 if (mode) {
14635 ret = fprintf(f, "%s", essid);
14636 if (ret < 0)
14637 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
14638 }
developer72fb0bb2023-01-11 09:46:29 +080014639
developer37646972023-06-29 10:58:43 +080014640 if (fclose(f) == EOF) {
14641 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
14642 return RETURN_ERR;
14643 }
developera3511852023-06-14 14:12:59 +080014644 }
developer72fb0bb2023-01-11 09:46:29 +080014645
developera3511852023-06-14 14:12:59 +080014646 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14647 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014648}
14649
14650INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
14651{
developera3511852023-06-14 14:12:59 +080014652 // TODO Implement me!
14653 //Apply wifi_pushRadioChannel() instantly
14654 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014655}
14656
14657INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
14658{
developera3511852023-06-14 14:12:59 +080014659 // TODO Implement me!
14660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014661}
14662
developer72fb0bb2023-01-11 09:46:29 +080014663
developera3511852023-06-14 14:12:59 +080014664static int tidStats_callback(struct nl_msg *msg, void *arg) {
14665 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14666 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14667 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14668 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
14669 int rem , tid_index = 0;
developer72fb0bb2023-01-11 09:46:29 +080014670
developera3511852023-06-14 14:12:59 +080014671 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
14672 wifi_associated_dev_tid_entry_t *stats_entry;
developer72fb0bb2023-01-11 09:46:29 +080014673
developera3511852023-06-14 14:12:59 +080014674 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
14675 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
14676 };
14677 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
14678 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
14679 };
developer72fb0bb2023-01-11 09:46:29 +080014680
developera3511852023-06-14 14:12:59 +080014681 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
14682 genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080014683
developer72fb0bb2023-01-11 09:46:29 +080014684
developera3511852023-06-14 14:12:59 +080014685 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014686 wifi_debug(DEBUG_ERROR, "station stats missing!\n");
developera3511852023-06-14 14:12:59 +080014687 return NL_SKIP;
14688 }
developer72fb0bb2023-01-11 09:46:29 +080014689
developera3511852023-06-14 14:12:59 +080014690 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
14691 tb[NL80211_ATTR_STA_INFO],
14692 stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014693 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014694 return NL_SKIP;
14695 }
developer72fb0bb2023-01-11 09:46:29 +080014696
developera3511852023-06-14 14:12:59 +080014697 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14698 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
14699 {
14700 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080014701
developera3511852023-06-14 14:12:59 +080014702 stats_entry->tid = tid_index;
14703 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080014704
developera3511852023-06-14 14:12:59 +080014705 if(sinfo[NL80211_STA_INFO_TID_STATS])
14706 {
14707 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
14708 printf("failed to parse nested stats attributes!");
14709 return NL_SKIP;
14710 }
14711 }
14712 if(stats_info[NL80211_TID_STATS_TX_MSDU])
14713 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080014714
developera3511852023-06-14 14:12:59 +080014715 if(tid_index < (PS_MAX_TID - 1))
14716 tid_index++;
14717 }
14718 }
14719 //ToDo: sum_time_ms, ewma_time_ms
14720 return NL_SKIP;
14721}
developer72fb0bb2023-01-11 09:46:29 +080014722
developera3511852023-06-14 14:12:59 +080014723INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
14724{
14725 Netlink nl;
14726 char if_name[IF_NAME_SIZE];
14727 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014728 int res;
developer72fb0bb2023-01-11 09:46:29 +080014729
developera3511852023-06-14 14:12:59 +080014730 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
14731 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014732
developere40952c2023-06-15 18:46:43 +080014733 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
14734 if (os_snprintf_error(sizeof(if_name), res)) {
14735 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14736 return RETURN_ERR;
14737 }
developer72fb0bb2023-01-11 09:46:29 +080014738
developera3511852023-06-14 14:12:59 +080014739 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014740
developera3511852023-06-14 14:12:59 +080014741 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080014742 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080014743 return -1;
14744 }
developer72fb0bb2023-01-11 09:46:29 +080014745
developera3511852023-06-14 14:12:59 +080014746 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014747
developera3511852023-06-14 14:12:59 +080014748 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080014749 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080014750 nlfree(&nl);
14751 return -2;
14752 }
developer72fb0bb2023-01-11 09:46:29 +080014753
developera3511852023-06-14 14:12:59 +080014754 genlmsg_put(msg,
14755 NL_AUTO_PID,
14756 NL_AUTO_SEQ,
14757 nl.id,
14758 0,
14759 0,
14760 NL80211_CMD_GET_STATION,
14761 0);
developer72fb0bb2023-01-11 09:46:29 +080014762
developera3511852023-06-14 14:12:59 +080014763 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
14764 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14765 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
14766 nl_send_auto_complete(nl.socket, msg);
14767 nl_recvmsgs(nl.socket, nl.cb);
14768 nlmsg_free(msg);
14769 nlfree(&nl);
14770 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014771}
14772
14773
14774INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
14775{
developera3511852023-06-14 14:12:59 +080014776 char interface_name[16] = {0};
14777 char cmd[128]={0};
14778 char buf[128]={0};
14779 int freq = 0;
developere40952c2023-06-15 18:46:43 +080014780 int res;
developer72fb0bb2023-01-11 09:46:29 +080014781
developera3511852023-06-14 14:12:59 +080014782 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014783
developera3511852023-06-14 14:12:59 +080014784 // full mode is used to scan all channels.
14785 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
14786 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
14787 ieee80211_channel_to_frequency(chan_list[0], &freq);
developer72fb0bb2023-01-11 09:46:29 +080014788
developera3511852023-06-14 14:12:59 +080014789 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14790 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014791
developera3511852023-06-14 14:12:59 +080014792 if (freq)
developere40952c2023-06-15 18:46:43 +080014793 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
developera3511852023-06-14 14:12:59 +080014794 else
developere40952c2023-06-15 18:46:43 +080014795 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
14796 if (os_snprintf_error(sizeof(cmd), res)) {
14797 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14798 return RETURN_ERR;
14799 }
developer72fb0bb2023-01-11 09:46:29 +080014800
developera3511852023-06-14 14:12:59 +080014801 _syscmd(cmd, buf, sizeof(buf));
14802 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014803
developera3511852023-06-14 14:12:59 +080014804 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014805}
14806
14807
14808INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
14809{
developera3511852023-06-14 14:12:59 +080014810 // TODO Implement me!
14811 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014812}
14813
14814INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
14815{
developera3511852023-06-14 14:12:59 +080014816 // TODO Implement me!
14817 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014818}
14819
14820INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
14821{
developera3511852023-06-14 14:12:59 +080014822 // TODO Implement me!
14823 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014824}
14825
14826INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
14827{
developera3511852023-06-14 14:12:59 +080014828 // TODO Implement me!
14829 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014830}
14831
14832INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
14833{
developera3511852023-06-14 14:12:59 +080014834 // TODO Implement me!
14835 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014836}
14837
14838INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
14839{
developera3511852023-06-14 14:12:59 +080014840 // TODO Implement me!
14841 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014842}
14843
14844INT wifi_steering_eventUnregister(void)
14845{
developera3511852023-06-14 14:12:59 +080014846 // TODO Implement me!
14847 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014848}
14849
14850INT wifi_delApAclDevices(INT apIndex)
14851{
developer7e4a2a62023-04-06 19:56:03 +080014852 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080014853 struct unl unl_ins;
14854 int if_idx = 0, ret = 0;
14855 struct nl_msg *msg = NULL;
14856 struct nlattr * msg_data = NULL;
14857 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080014858
developer7e4a2a62023-04-06 19:56:03 +080014859 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
14860 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080014861 if_idx = if_nametoindex(inf_name);
14862 if (!if_idx) {
14863 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
14864 return RETURN_ERR;
14865 }
14866 /*init mtk nl80211 vendor cmd*/
14867 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
14868 param.if_type = NL80211_ATTR_IFINDEX;
14869 param.if_idx = if_idx;
14870 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
14871 if (ret) {
14872 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
14873 return RETURN_ERR;
14874 }
14875 /*add mtk vendor cmd data*/
14876 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
14877 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
14878 nlmsg_free(msg);
14879 goto err;
14880 }
14881 /*send mtk nl80211 vendor msg*/
14882 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
14883 if (ret) {
14884 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
14885 goto err;
14886 }
14887 /*deinit mtk nl80211 vendor msg*/
14888 mtk_nl80211_deint(&unl_ins);
14889 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
14890 return RETURN_OK;
14891err:
14892 mtk_nl80211_deint(&unl_ins);
14893 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
14894 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014895
developera3511852023-06-14 14:12:59 +080014896 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014897}
14898
developer72fb0bb2023-01-11 09:46:29 +080014899static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080014900 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14901 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developerc14d83a2023-06-29 20:09:42 +080014902 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
14903 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
developera3511852023-06-14 14:12:59 +080014904 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
14905 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080014906
developera3511852023-06-14 14:12:59 +080014907 nla_parse(tb,
14908 NL80211_ATTR_MAX,
14909 genlmsg_attrdata(gnlh, 0),
14910 genlmsg_attrlen(gnlh, 0),
14911 NULL);
developer72fb0bb2023-01-11 09:46:29 +080014912
developera3511852023-06-14 14:12:59 +080014913 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014914 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080014915 return NL_SKIP;
14916 }
developer72fb0bb2023-01-11 09:46:29 +080014917
developera3511852023-06-14 14:12:59 +080014918 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014919 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014920 return NL_SKIP;
14921 }
14922 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080014923
developera3511852023-06-14 14:12:59 +080014924 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080014925
developera3511852023-06-14 14:12:59 +080014926 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
14927 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
developer75bd10c2023-06-27 11:34:08 +080014928 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080014929 return NL_SKIP;
14930 }
14931 }
developer72fb0bb2023-01-11 09:46:29 +080014932
developera3511852023-06-14 14:12:59 +080014933 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14934 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
14935 printf("failed to parse nested stats attributes!");
14936 return NL_SKIP;
14937 }
14938 }
14939 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080014940
developera3511852023-06-14 14:12:59 +080014941 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
14942 {
14943 printf("Type is VHT\n");
14944 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
14945 ((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 +080014946
developera3511852023-06-14 14:12:59 +080014947 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
14948 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
14949 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
14950 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14951 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
14952 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14953 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
14954 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14955 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
14956 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
14957 } else {
14958 printf(" OFDM or CCK \n");
14959 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
14960 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
14961 }
14962 }
developer72fb0bb2023-01-11 09:46:29 +080014963
developera3511852023-06-14 14:12:59 +080014964 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
developereff896f2023-05-29 14:52:55 +080014965 if(rinfo[NL80211_RATE_INFO_MCS])
14966 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
14967 }
developera3511852023-06-14 14:12:59 +080014968 if (sinfo[NL80211_STA_INFO_RX_BYTES64])
developereff896f2023-05-29 14:52:55 +080014969 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
14970 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
14971 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
developer72fb0bb2023-01-11 09:46:29 +080014972
developera3511852023-06-14 14:12:59 +080014973 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14974 if (stats_info[NL80211_TID_STATS_RX_MSDU])
developereff896f2023-05-29 14:52:55 +080014975 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
14976 }
developer72fb0bb2023-01-11 09:46:29 +080014977
developereff896f2023-05-29 14:52:55 +080014978 if (sinfo[NL80211_STA_INFO_SIGNAL])
14979 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
14980 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
14981 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
14982 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
14983 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
14984 //rssi_array need to be filled
14985 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080014986}
developer72fb0bb2023-01-11 09:46:29 +080014987
14988INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
14989{
developera3511852023-06-14 14:12:59 +080014990 Netlink nl;
14991 char if_name[32];
14992 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
14993 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014994
developera3511852023-06-14 14:12:59 +080014995 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080014996
developera3511852023-06-14 14:12:59 +080014997 if (*output_array_size <= 0)
14998 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014999
developera3511852023-06-14 14:12:59 +080015000 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080015001
developera3511852023-06-14 14:12:59 +080015002 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080015003 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080015004 return 0;
15005 }
developer72fb0bb2023-01-11 09:46:29 +080015006
developera3511852023-06-14 14:12:59 +080015007 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080015008
developera3511852023-06-14 14:12:59 +080015009 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080015010 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080015011 nlfree(&nl);
15012 return 0;
15013 }
developer72fb0bb2023-01-11 09:46:29 +080015014
developera3511852023-06-14 14:12:59 +080015015 genlmsg_put(msg,
15016 NL_AUTO_PID,
15017 NL_AUTO_SEQ,
15018 nl.id,
15019 0,
15020 0,
15021 NL80211_CMD_GET_STATION,
15022 0);
developer72fb0bb2023-01-11 09:46:29 +080015023
developera3511852023-06-14 14:12:59 +080015024 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
15025 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
15026 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
15027 nl_send_auto_complete(nl.socket, msg);
15028 nl_recvmsgs(nl.socket, nl.cb);
15029 nlmsg_free(msg);
15030 nlfree(&nl);
15031 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015032}
15033
developer72fb0bb2023-01-11 09:46:29 +080015034static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080015035 struct nlattr *tb[NL80211_ATTR_MAX + 1];
15036 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developerc14d83a2023-06-29 20:09:42 +080015037 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
15038 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
developera3511852023-06-14 14:12:59 +080015039 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
15040 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080015041
developera3511852023-06-14 14:12:59 +080015042 nla_parse(tb,
15043 NL80211_ATTR_MAX,
15044 genlmsg_attrdata(gnlh, 0),
15045 genlmsg_attrlen(gnlh, 0),
15046 NULL);
developer72fb0bb2023-01-11 09:46:29 +080015047
developera3511852023-06-14 14:12:59 +080015048 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080015049 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080015050 return NL_SKIP;
15051 }
developer72fb0bb2023-01-11 09:46:29 +080015052
developera3511852023-06-14 14:12:59 +080015053 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080015054 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080015055 return NL_SKIP;
15056 }
developer72fb0bb2023-01-11 09:46:29 +080015057
developera3511852023-06-14 14:12:59 +080015058 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080015059
developera3511852023-06-14 14:12:59 +080015060 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080015061
developera3511852023-06-14 14:12:59 +080015062 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
15063 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +080015064 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080015065 return NL_SKIP;
15066 }
15067 }
developer72fb0bb2023-01-11 09:46:29 +080015068
developera3511852023-06-14 14:12:59 +080015069 if(sinfo[NL80211_STA_INFO_TID_STATS])
15070 {
15071 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
15072 printf("failed to parse nested stats attributes!");
15073 return NL_SKIP;
15074 }
15075 }
15076 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
15077 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
15078 {
15079 printf("Type is VHT\n");
15080 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
15081 ((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 +080015082
developera3511852023-06-14 14:12:59 +080015083 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
15084 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
15085 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
15086 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
15087 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
15088 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
15089 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
15090 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
15091 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
15092 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
15093 }
15094 else
15095 {
15096 printf(" OFDM or CCK \n");
15097 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
15098 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
15099 }
15100 }
developer72fb0bb2023-01-11 09:46:29 +080015101
developera3511852023-06-14 14:12:59 +080015102 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
15103 if(rinfo[NL80211_RATE_INFO_MCS])
15104 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
15105 }
developer72fb0bb2023-01-11 09:46:29 +080015106
developera3511852023-06-14 14:12:59 +080015107 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
15108 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
15109 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
15110 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
developer72fb0bb2023-01-11 09:46:29 +080015111
developera3511852023-06-14 14:12:59 +080015112 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
15113 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
15114 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080015115
developera3511852023-06-14 14:12:59 +080015116 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
15117 if(stats_info[NL80211_TID_STATS_TX_MSDU])
15118 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
15119 }
developer72fb0bb2023-01-11 09:46:29 +080015120
developera3511852023-06-14 14:12:59 +080015121 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
15122 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
developer72fb0bb2023-01-11 09:46:29 +080015123
developera3511852023-06-14 14:12:59 +080015124 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
15125 ((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]);
developer72fb0bb2023-01-11 09:46:29 +080015126
developera3511852023-06-14 14:12:59 +080015127 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080015128}
developer72fb0bb2023-01-11 09:46:29 +080015129
15130INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
15131{
developera3511852023-06-14 14:12:59 +080015132 Netlink nl;
15133 char if_name[IF_NAME_SIZE];
15134 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080015135 int res;
15136
developera3511852023-06-14 14:12:59 +080015137 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
15138 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015139
developera3511852023-06-14 14:12:59 +080015140 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080015141
developera3511852023-06-14 14:12:59 +080015142 if (*output_array_size <= 0)
15143 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015144
developere40952c2023-06-15 18:46:43 +080015145 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
15146 if (os_snprintf_error(sizeof(if_name), res)) {
15147 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15148 return RETURN_ERR;
15149 }
developer72fb0bb2023-01-11 09:46:29 +080015150
developera3511852023-06-14 14:12:59 +080015151 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080015152
developera3511852023-06-14 14:12:59 +080015153 if(nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080015154 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080015155 return 0;
15156 }
developer72fb0bb2023-01-11 09:46:29 +080015157
developera3511852023-06-14 14:12:59 +080015158 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080015159
developera3511852023-06-14 14:12:59 +080015160 if(!msg) {
developer75bd10c2023-06-27 11:34:08 +080015161 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080015162 nlfree(&nl);
15163 return 0;
15164 }
developer72fb0bb2023-01-11 09:46:29 +080015165
developera3511852023-06-14 14:12:59 +080015166 genlmsg_put(msg,
15167 NL_AUTO_PID,
15168 NL_AUTO_SEQ,
15169 nl.id,
15170 0,
15171 0,
15172 NL80211_CMD_GET_STATION,
15173 0);
developer72fb0bb2023-01-11 09:46:29 +080015174
developera3511852023-06-14 14:12:59 +080015175 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
15176 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
15177 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
15178 nl_send_auto_complete(nl.socket, msg);
15179 nl_recvmsgs(nl.socket, nl.cb);
15180 nlmsg_free(msg);
15181 nlfree(&nl);
15182 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015183}
15184
15185INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
15186{
developera3511852023-06-14 14:12:59 +080015187 // TODO Implement me!
15188 char buf[MAX_BUF_SIZE] = {0};
15189 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080015190 int res;
developer72fb0bb2023-01-11 09:46:29 +080015191
developere40952c2023-06-15 18:46:43 +080015192 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15193 if (os_snprintf_error(sizeof(config_file), res)) {
15194 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15195 return RETURN_ERR;
15196 }
developera3511852023-06-14 14:12:59 +080015197 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
15198 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080015199
developera3511852023-06-14 14:12:59 +080015200 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015201}
15202
15203INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
15204{
developera3511852023-06-14 14:12:59 +080015205 char config_file[MAX_BUF_SIZE] = {0};
15206 struct params list;
developer75bd10c2023-06-27 11:34:08 +080015207 int res;
developer72fb0bb2023-01-11 09:46:29 +080015208
developera3511852023-06-14 14:12:59 +080015209 list.name = "rrm_neighbor_report";
15210 list.value = activate?"1":"0";
developer75bd10c2023-06-27 11:34:08 +080015211 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15212 if (os_snprintf_error(sizeof(config_file), res)) {
15213 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15214 return RETURN_ERR;
15215 }
developera3511852023-06-14 14:12:59 +080015216 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080015217
developera3511852023-06-14 14:12:59 +080015218 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015219}
15220
15221INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
15222{
developera3511852023-06-14 14:12:59 +080015223 char buf[32] = {0};
15224 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080015225 int res;
developer72fb0bb2023-01-11 09:46:29 +080015226
developer75bd10c2023-06-27 11:34:08 +080015227 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15228 if (os_snprintf_error(sizeof(config_file), res)) {
15229 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15230 return RETURN_ERR;
15231 }
developera3511852023-06-14 14:12:59 +080015232 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
15233 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080015234
developera3511852023-06-14 14:12:59 +080015235 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015236}
15237#undef HAL_NETLINK_IMPL
15238#ifdef HAL_NETLINK_IMPL
15239static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080015240 struct nlattr *tb[NL80211_ATTR_MAX + 1];
15241 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
15242 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
15243 char dev[20];
15244 int freq =0 ;
15245 static int i=0;
developer72fb0bb2023-01-11 09:46:29 +080015246
developera3511852023-06-14 14:12:59 +080015247 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
developer72fb0bb2023-01-11 09:46:29 +080015248
developera3511852023-06-14 14:12:59 +080015249 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
15250 };
developer72fb0bb2023-01-11 09:46:29 +080015251
developera3511852023-06-14 14:12:59 +080015252 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080015253
developera3511852023-06-14 14:12:59 +080015254 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080015255
developera3511852023-06-14 14:12:59 +080015256 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
15257 fprintf(stderr, "survey data missing!\n");
15258 return NL_SKIP;
15259 }
developer72fb0bb2023-01-11 09:46:29 +080015260
developera3511852023-06-14 14:12:59 +080015261 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
15262 {
15263 fprintf(stderr, "failed to parse nested attributes!\n");
15264 return NL_SKIP;
15265 }
developer72fb0bb2023-01-11 09:46:29 +080015266
15267
developera3511852023-06-14 14:12:59 +080015268 if(out[0].array_size == 1 )
15269 {
15270 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
15271 {
15272 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
15273 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
15274 out[0].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080015275
developera3511852023-06-14 14:12:59 +080015276 if (sinfo[NL80211_SURVEY_INFO_NOISE])
15277 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
15278 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
15279 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
15280 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
15281 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
15282 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
15283 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
15284 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
15285 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
15286 if (sinfo[NL80211_SURVEY_INFO_TIME])
15287 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
15288 return NL_STOP;
15289 }
15290 } else {
15291 if ( i <= out[0].array_size ) {
15292 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
15293 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
15294 out[i].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080015295
developera3511852023-06-14 14:12:59 +080015296 if (sinfo[NL80211_SURVEY_INFO_NOISE])
15297 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
15298 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
15299 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
15300 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
15301 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
15302 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
15303 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
15304 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
15305 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
15306 if (sinfo[NL80211_SURVEY_INFO_TIME])
15307 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
15308 }
15309 }
developer72fb0bb2023-01-11 09:46:29 +080015310
developera3511852023-06-14 14:12:59 +080015311 i++;
15312 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080015313}
15314#endif
15315
15316static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
15317{
developera3511852023-06-14 14:12:59 +080015318 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
15319 FILE *fp;
developere40952c2023-06-15 18:46:43 +080015320 int res;
developer72fb0bb2023-01-11 09:46:29 +080015321
developera3511852023-06-14 14:12:59 +080015322 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
15323 {
15324 printf("Creating Frequency-Channel Map\n");
15325 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
15326 }
developere40952c2023-06-15 18:46:43 +080015327 res = snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
15328 if (os_snprintf_error(sizeof(command), res)) {
15329 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15330 return RETURN_ERR;
15331 }
15332
developera3511852023-06-14 14:12:59 +080015333 if((fp = popen(command, "r")))
15334 {
15335 fgets(output, sizeof(output), fp);
developerc14d83a2023-06-29 20:09:42 +080015336 if (fgets(output, sizeof(output), fp) == NULL) {
15337 wifi_debug(DEBUG_ERROR, "fgets fail\n");
15338 pclose(fp);
15339 return RETURN_ERR;
15340 }
developera3511852023-06-14 14:12:59 +080015341 *freqMHz = atoi(output);
15342 pclose(fp);
15343 }
developer72fb0bb2023-01-11 09:46:29 +080015344
developera3511852023-06-14 14:12:59 +080015345 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015346}
15347
developer2f79c922023-06-02 17:33:42 +080015348static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
developer72fb0bb2023-01-11 09:46:29 +080015349{
developera3511852023-06-14 14:12:59 +080015350 int freqMHz = -1;
15351 char cmd[MAX_CMD_SIZE] = {'\0'};
15352 char interface_name[16] = {0};
developer32f2a182023-06-27 19:50:41 +080015353 int res;
developer72fb0bb2023-01-11 09:46:29 +080015354
developera3511852023-06-14 14:12:59 +080015355 ieee80211_channel_to_frequency(channel, &freqMHz);
15356 if (freqMHz == -1) {
15357 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
15358 return -1;
15359 }
developer72fb0bb2023-01-11 09:46:29 +080015360
developer86035662023-06-28 19:21:12 +080015361 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
15362 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
15363 }
developer32f2a182023-06-27 19:50:41 +080015364 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz);
15365 if (os_snprintf_error(sizeof(cmd), res)) {
15366 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15367 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080015368 }
developer72fb0bb2023-01-11 09:46:29 +080015369
developera3511852023-06-14 14:12:59 +080015370 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
15371 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
15372 return -1;
15373 }
developer72fb0bb2023-01-11 09:46:29 +080015374
developera3511852023-06-14 14:12:59 +080015375 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015376}
15377
15378static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
15379{
developera3511852023-06-14 14:12:59 +080015380 const char *ptr = buf;
15381 char *key = NULL;
15382 char *val = NULL;
15383 char line[256] = { '\0' };
developer72fb0bb2023-01-11 09:46:29 +080015384
developera3511852023-06-14 14:12:59 +080015385 while ((ptr = get_line_from_str_buf(ptr, line))) {
15386 if (strstr(line, "Frequency")) continue;
developer72fb0bb2023-01-11 09:46:29 +080015387
developera3511852023-06-14 14:12:59 +080015388 key = strtok(line, ":");
developerc14d83a2023-06-29 20:09:42 +080015389 if (key == NULL)
15390 continue;
developera3511852023-06-14 14:12:59 +080015391 val = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080015392 if (val == NULL)
15393 continue;
developera3511852023-06-14 14:12:59 +080015394 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
developer72fb0bb2023-01-11 09:46:29 +080015395
developera3511852023-06-14 14:12:59 +080015396 if (!strcmp(key, "noise")) {
developer37646972023-06-29 10:58:43 +080015397 if (sscanf(val, "%d", &stats->ch_noise) == EOF)
15398 continue;
developera3511852023-06-14 14:12:59 +080015399 if (stats->ch_noise == 0) {
15400 // Workaround for missing noise information.
15401 // Assume -95 for 2.4G and -103 for 5G
15402 if (radioIndex == 0) stats->ch_noise = -95;
15403 if (radioIndex == 1) stats->ch_noise = -103;
15404 }
15405 }
15406 else if (!strcmp(key, "channel active time")) {
developer37646972023-06-29 10:58:43 +080015407 if (sscanf(val, "%llu", &stats->ch_utilization_total) == EOF)
15408 continue;
developera3511852023-06-14 14:12:59 +080015409 }
15410 else if (!strcmp(key, "channel busy time")) {
developer37646972023-06-29 10:58:43 +080015411 if (sscanf(val, "%llu", &stats->ch_utilization_busy) == EOF)
15412 continue;
developera3511852023-06-14 14:12:59 +080015413 }
15414 else if (!strcmp(key, "channel receive time")) {
developer37646972023-06-29 10:58:43 +080015415 if (sscanf(val, "%llu", &stats->ch_utilization_busy_rx) == EOF)
15416 continue;
developera3511852023-06-14 14:12:59 +080015417 }
15418 else if (!strcmp(key, "channel transmit time")) {
developer37646972023-06-29 10:58:43 +080015419 if (sscanf(val, "%llu", &stats->ch_utilization_busy_tx) == EOF)
15420 continue;
developera3511852023-06-14 14:12:59 +080015421 }
15422 };
developer72fb0bb2023-01-11 09:46:29 +080015423
developera3511852023-06-14 14:12:59 +080015424 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015425}
15426
15427INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
15428{
developera3511852023-06-14 14:12:59 +080015429 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015430#ifdef HAL_NETLINK_IMPL
developera3511852023-06-14 14:12:59 +080015431 Netlink nl;
15432 wifi_channelStats_t_loc local[array_size];
15433 char if_name[32];
developer72fb0bb2023-01-11 09:46:29 +080015434
developera3511852023-06-14 14:12:59 +080015435 local[0].array_size = array_size;
developer72fb0bb2023-01-11 09:46:29 +080015436
developera3511852023-06-14 14:12:59 +080015437 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
15438 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015439
developera3511852023-06-14 14:12:59 +080015440 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080015441
developera3511852023-06-14 14:12:59 +080015442 if (nl.id < 0) {
developerc14d83a2023-06-29 20:09:42 +080015443 wifi_debug(DEBUG_ERROR,, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080015444 return -1;
15445 }
developer72fb0bb2023-01-11 09:46:29 +080015446
developera3511852023-06-14 14:12:59 +080015447 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080015448
developera3511852023-06-14 14:12:59 +080015449 if (!msg) {
developerc14d83a2023-06-29 20:09:42 +080015450 wifi_debug(DEBUG_ERROR,, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080015451 nlfree(&nl);
15452 return -2;
15453 }
developer72fb0bb2023-01-11 09:46:29 +080015454
developera3511852023-06-14 14:12:59 +080015455 genlmsg_put(msg,
15456 NL_AUTO_PID,
15457 NL_AUTO_SEQ,
15458 nl.id,
15459 0,
15460 NLM_F_DUMP,
15461 NL80211_CMD_GET_SURVEY,
15462 0);
developer72fb0bb2023-01-11 09:46:29 +080015463
developera3511852023-06-14 14:12:59 +080015464 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
15465 nl_send_auto_complete(nl.socket, msg);
15466 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
15467 nl_recvmsgs(nl.socket, nl.cb);
15468 nlmsg_free(msg);
15469 nlfree(&nl);
15470 //Copying the Values
15471 for(int i=0;i<array_size;i++)
15472 {
15473 input_output_channelStats_array[i].ch_number = local[i].ch_number;
15474 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
15475 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
15476 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
15477 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
15478 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
15479 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
15480 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
15481 }
developer72fb0bb2023-01-11 09:46:29 +080015482#else
developera3511852023-06-14 14:12:59 +080015483 ULONG channel = 0;
15484 int i;
15485 int number_of_channels = array_size;
15486 char buf[512];
developer72fb0bb2023-01-11 09:46:29 +080015487
developera3511852023-06-14 14:12:59 +080015488 if (number_of_channels == 0) {
15489 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
15490 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
15491 return RETURN_ERR;
15492 }
15493 number_of_channels = 1;
15494 input_output_channelStats_array[0].ch_number = channel;
15495 }
developer72fb0bb2023-01-11 09:46:29 +080015496
developera3511852023-06-14 14:12:59 +080015497 for (i = 0; i < number_of_channels; i++) {
developer72fb0bb2023-01-11 09:46:29 +080015498
developera3511852023-06-14 14:12:59 +080015499 input_output_channelStats_array[i].ch_noise = 0;
15500 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
15501 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
15502 input_output_channelStats_array[i].ch_utilization_busy = 0;
15503 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
15504 input_output_channelStats_array[i].ch_utilization_total = 0;
developer72fb0bb2023-01-11 09:46:29 +080015505
developera3511852023-06-14 14:12:59 +080015506 memset(buf, 0, sizeof(buf));
15507 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
15508 return RETURN_ERR;
15509 }
15510 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
15511 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
15512 return RETURN_ERR;
15513 }
developer72fb0bb2023-01-11 09:46:29 +080015514
developera3511852023-06-14 14:12:59 +080015515 // XXX: fake missing 'self' counter which is not available in iw survey output
15516 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
15517 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
developer72fb0bb2023-01-11 09:46:29 +080015518
developera3511852023-06-14 14:12:59 +080015519 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
15520 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
15521 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
15522 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
15523 input_output_channelStats_array[i].ch_utilization_total *= 1000;
developer72fb0bb2023-01-11 09:46:29 +080015524
developera3511852023-06-14 14:12:59 +080015525 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",
15526 __func__,
15527 input_output_channelStats_array[i].ch_number,
15528 input_output_channelStats_array[i].ch_noise,
15529 input_output_channelStats_array[i].ch_utilization_total,
15530 input_output_channelStats_array[i].ch_utilization_busy,
15531 input_output_channelStats_array[i].ch_utilization_busy_rx,
15532 input_output_channelStats_array[i].ch_utilization_busy_tx,
15533 input_output_channelStats_array[i].ch_utilization_busy_self,
15534 input_output_channelStats_array[i].ch_utilization_busy_ext);
15535 }
developer72fb0bb2023-01-11 09:46:29 +080015536#endif
developera3511852023-06-14 14:12:59 +080015537 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15538 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015539}
15540#define HAL_NETLINK_IMPL
15541
15542/* Hostapd events */
15543
15544#ifndef container_of
15545#define offset_of(st, m) ((size_t)&(((st *)0)->m))
15546#define container_of(ptr, type, member) \
developera3511852023-06-14 14:12:59 +080015547 ((type *)((char *)ptr - offset_of(type, member)))
developer72fb0bb2023-01-11 09:46:29 +080015548#endif /* container_of */
15549
15550struct ctrl {
developera3511852023-06-14 14:12:59 +080015551 char sockpath[128];
15552 char sockdir[128];
15553 char bss[IFNAMSIZ];
15554 char reply[4096];
15555 int ssid_index;
15556 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
15557 void (*overrun)(struct ctrl *ctrl);
15558 struct wpa_ctrl *wpa;
15559 unsigned int ovfl;
15560 size_t reply_len;
15561 int initialized;
15562 ev_timer retry;
15563 ev_timer watchdog;
15564 ev_stat stat;
15565 ev_io io;
developer72fb0bb2023-01-11 09:46:29 +080015566};
15567static wifi_newApAssociatedDevice_callback clients_connect_cb;
15568static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
15569static struct ctrl wpa_ctrl[MAX_APS];
15570static int initialized;
15571
15572static unsigned int ctrl_get_drops(struct ctrl *ctrl)
15573{
developera3511852023-06-14 14:12:59 +080015574 char cbuf[256] = {};
15575 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
15576 struct cmsghdr *cmsg;
15577 unsigned int ovfl = ctrl->ovfl;
developer86035662023-06-28 19:21:12 +080015578 unsigned int drop = 0;
developer72fb0bb2023-01-11 09:46:29 +080015579
developer86035662023-06-28 19:21:12 +080015580 if (recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT) < 0)
15581 return drop;
developera3511852023-06-14 14:12:59 +080015582 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
15583 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
15584 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
developer72fb0bb2023-01-11 09:46:29 +080015585
developera3511852023-06-14 14:12:59 +080015586 drop = ovfl - ctrl->ovfl;
15587 ctrl->ovfl = ovfl;
developer72fb0bb2023-01-11 09:46:29 +080015588
developera3511852023-06-14 14:12:59 +080015589 return drop;
developer72fb0bb2023-01-11 09:46:29 +080015590}
15591
15592static void ctrl_close(struct ctrl *ctrl)
15593{
developera3511852023-06-14 14:12:59 +080015594 if (ctrl->io.cb)
15595 ev_io_stop(EV_DEFAULT_ &ctrl->io);
15596 if (ctrl->retry.cb)
15597 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
15598 if (!ctrl->wpa)
15599 return;
developer72fb0bb2023-01-11 09:46:29 +080015600
developera3511852023-06-14 14:12:59 +080015601 wpa_ctrl_detach(ctrl->wpa);
15602 wpa_ctrl_close(ctrl->wpa);
15603 ctrl->wpa = NULL;
15604 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
developer72fb0bb2023-01-11 09:46:29 +080015605}
15606
15607static void ctrl_process(struct ctrl *ctrl)
15608{
developera3511852023-06-14 14:12:59 +080015609 const char *str;
15610 int drops;
15611 int level;
developer72fb0bb2023-01-11 09:46:29 +080015612
developera3511852023-06-14 14:12:59 +080015613 /* Example events:
15614 *
15615 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
15616 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
15617 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
15618 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
15619 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
15620 */
15621 if (!(str = index(ctrl->reply, '>')))
15622 return;
15623 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
15624 return;
developer72fb0bb2023-01-11 09:46:29 +080015625
developera3511852023-06-14 14:12:59 +080015626 str++;
developer72fb0bb2023-01-11 09:46:29 +080015627
developera3511852023-06-14 14:12:59 +080015628 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
15629 if (!(str = index(ctrl->reply, ' ')))
15630 return;
15631 wifi_associated_dev_t sta;
15632 memset(&sta, 0, sizeof(sta));
developer72fb0bb2023-01-11 09:46:29 +080015633
developere75ba632023-06-29 16:03:33 +080015634 if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
15635 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
15636 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]) == EOF) {
15637 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15638 return;
15639 }
developer72fb0bb2023-01-11 09:46:29 +080015640
developera3511852023-06-14 14:12:59 +080015641 sta.cli_Active=true;
developer72fb0bb2023-01-11 09:46:29 +080015642
developera3511852023-06-14 14:12:59 +080015643 (clients_connect_cb)(ctrl->ssid_index, &sta);
15644 goto handled;
15645 }
developer72fb0bb2023-01-11 09:46:29 +080015646
developera3511852023-06-14 14:12:59 +080015647 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
15648 if (!(str = index(ctrl->reply, ' ')))
15649 return;
developer72fb0bb2023-01-11 09:46:29 +080015650
developera3511852023-06-14 14:12:59 +080015651 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
15652 goto handled;
15653 }
developer72fb0bb2023-01-11 09:46:29 +080015654
developera3511852023-06-14 14:12:59 +080015655 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
15656 printf("CTRL_WPA: handle TERMINATING event\n");
15657 goto retry;
15658 }
developer72fb0bb2023-01-11 09:46:29 +080015659
developera3511852023-06-14 14:12:59 +080015660 if (strncmp("AP-DISABLED", str, 11) == 0) {
15661 printf("CTRL_WPA: handle AP-DISABLED\n");
15662 goto retry;
15663 }
developer72fb0bb2023-01-11 09:46:29 +080015664
developera3511852023-06-14 14:12:59 +080015665 printf("Event not supported!!\n");
developer72fb0bb2023-01-11 09:46:29 +080015666
15667handled:
15668
developera3511852023-06-14 14:12:59 +080015669 if ((drops = ctrl_get_drops(ctrl))) {
15670 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
15671 if (ctrl->overrun)
15672 ctrl->overrun(ctrl);
15673 }
developer72fb0bb2023-01-11 09:46:29 +080015674
developera3511852023-06-14 14:12:59 +080015675 return;
developer72fb0bb2023-01-11 09:46:29 +080015676
15677retry:
developera3511852023-06-14 14:12:59 +080015678 printf("WPA_CTRL: closing\n");
15679 ctrl_close(ctrl);
15680 printf("WPA_CTRL: retrying from ctrl prcoess\n");
15681 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
developer72fb0bb2023-01-11 09:46:29 +080015682}
15683
15684static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
15685{
developera3511852023-06-14 14:12:59 +080015686 struct ctrl *ctrl = container_of(io, struct ctrl, io);
15687 int err;
developer72fb0bb2023-01-11 09:46:29 +080015688
developera3511852023-06-14 14:12:59 +080015689 memset(ctrl->reply, 0, sizeof(ctrl->reply));
15690 ctrl->reply_len = sizeof(ctrl->reply) - 1;
15691 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
15692 ctrl->reply[ctrl->reply_len] = 0;
15693 if (err < 0) {
15694 if (errno == EAGAIN || errno == EWOULDBLOCK)
15695 return;
15696 ctrl_close(ctrl);
15697 ev_timer_again(EV_A_ &ctrl->retry);
15698 return;
15699 }
developer72fb0bb2023-01-11 09:46:29 +080015700
developera3511852023-06-14 14:12:59 +080015701 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015702}
15703
15704static int ctrl_open(struct ctrl *ctrl)
15705{
developera3511852023-06-14 14:12:59 +080015706 int fd;
developer72fb0bb2023-01-11 09:46:29 +080015707
developera3511852023-06-14 14:12:59 +080015708 if (ctrl->wpa)
15709 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015710
developera3511852023-06-14 14:12:59 +080015711 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
15712 if (!ctrl->wpa)
15713 goto err;
developer72fb0bb2023-01-11 09:46:29 +080015714
developera3511852023-06-14 14:12:59 +080015715 if (wpa_ctrl_attach(ctrl->wpa) < 0)
15716 goto err_close;
developer72fb0bb2023-01-11 09:46:29 +080015717
developera3511852023-06-14 14:12:59 +080015718 fd = wpa_ctrl_get_fd(ctrl->wpa);
15719 if (fd < 0)
15720 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080015721
developera3511852023-06-14 14:12:59 +080015722 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
15723 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080015724
developera3511852023-06-14 14:12:59 +080015725 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
15726 ev_io_start(EV_DEFAULT_ &ctrl->io);
developer72fb0bb2023-01-11 09:46:29 +080015727
developera3511852023-06-14 14:12:59 +080015728 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015729
15730err_detach:
developera3511852023-06-14 14:12:59 +080015731 wpa_ctrl_detach(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080015732err_close:
developera3511852023-06-14 14:12:59 +080015733 wpa_ctrl_close(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080015734err:
developera3511852023-06-14 14:12:59 +080015735 ctrl->wpa = NULL;
15736 return -1;
developer72fb0bb2023-01-11 09:46:29 +080015737}
15738
15739static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
15740{
developera3511852023-06-14 14:12:59 +080015741 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
developer72fb0bb2023-01-11 09:46:29 +080015742
developera3511852023-06-14 14:12:59 +080015743 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
15744 ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015745}
15746
15747static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
15748{
developera3511852023-06-14 14:12:59 +080015749 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
developer72fb0bb2023-01-11 09:46:29 +080015750
developera3511852023-06-14 14:12:59 +080015751 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
15752 if (ctrl_open(ctrl) == 0) {
15753 printf("WPA_CTRL: retry successful\n");
15754 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
15755 }
developer72fb0bb2023-01-11 09:46:29 +080015756}
15757
15758int ctrl_enable(struct ctrl *ctrl)
15759{
developera3511852023-06-14 14:12:59 +080015760 if (ctrl->wpa)
15761 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015762
developera3511852023-06-14 14:12:59 +080015763 if (!ctrl->stat.cb) {
15764 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
15765 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
15766 }
developer72fb0bb2023-01-11 09:46:29 +080015767
developera3511852023-06-14 14:12:59 +080015768 if (!ctrl->retry.cb) {
15769 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
15770 }
developer72fb0bb2023-01-11 09:46:29 +080015771
developera3511852023-06-14 14:12:59 +080015772 return ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015773}
15774
15775static void
15776ctrl_msg_cb(char *buf, size_t len)
15777{
developera3511852023-06-14 14:12:59 +080015778 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
developer72fb0bb2023-01-11 09:46:29 +080015779
developera3511852023-06-14 14:12:59 +080015780 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
15781 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015782}
15783
15784static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
15785{
developera3511852023-06-14 14:12:59 +080015786 int err;
developer72fb0bb2023-01-11 09:46:29 +080015787
developera3511852023-06-14 14:12:59 +080015788 if (!ctrl->wpa)
15789 return -1;
15790 if (*reply_len < 2)
15791 return -1;
developer72fb0bb2023-01-11 09:46:29 +080015792
developera3511852023-06-14 14:12:59 +080015793 (*reply_len)--;
15794 ctrl->reply_len = sizeof(ctrl->reply);
15795 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
15796 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
15797 if (err < 0)
15798 return err;
developer72fb0bb2023-01-11 09:46:29 +080015799
developera3511852023-06-14 14:12:59 +080015800 if (ctrl->reply_len > *reply_len)
15801 ctrl->reply_len = *reply_len;
developer72fb0bb2023-01-11 09:46:29 +080015802
developera3511852023-06-14 14:12:59 +080015803 *reply_len = ctrl->reply_len;
15804 memcpy(reply, ctrl->reply, *reply_len);
15805 reply[*reply_len - 1] = 0;
15806 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
15807 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015808}
15809
15810static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
15811{
developera3511852023-06-14 14:12:59 +080015812 const char *pong = "PONG";
15813 const char *ping = "PING";
15814 char reply[1024];
15815 size_t len = sizeof(reply);
15816 int err;
15817 ULONG s, snum;
15818 INT ret;
15819 BOOL status;
developer72fb0bb2023-01-11 09:46:29 +080015820
developera3511852023-06-14 14:12:59 +080015821 printf("WPA_CTRL: watchdog cb\n");
developer72fb0bb2023-01-11 09:46:29 +080015822
developera3511852023-06-14 14:12:59 +080015823 ret = wifi_getSSIDNumberOfEntries(&snum);
15824 if (ret != RETURN_OK) {
15825 printf("%s: failed to get SSID count", __func__);
15826 return;
15827 }
developer72fb0bb2023-01-11 09:46:29 +080015828
developera3511852023-06-14 14:12:59 +080015829 if (snum > MAX_APS) {
15830 printf("more ssid than supported! %lu\n", snum);
15831 return;
15832 }
developer72fb0bb2023-01-11 09:46:29 +080015833
developera3511852023-06-14 14:12:59 +080015834 for (s = 0; s < snum; s++) {
15835 if (wifi_getApEnable(s, &status) != RETURN_OK) {
15836 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
15837 continue;
15838 }
15839 if (status == false) continue;
developer72fb0bb2023-01-11 09:46:29 +080015840
developera3511852023-06-14 14:12:59 +080015841 memset(reply, 0, sizeof(reply));
15842 len = sizeof(reply);
15843 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
15844 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
15845 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
15846 continue;
developer72fb0bb2023-01-11 09:46:29 +080015847
developera3511852023-06-14 14:12:59 +080015848 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
15849 ctrl_close(&wpa_ctrl[s]);
15850 printf("WPA_CTRL: ev_timer_again %lu\n", s);
15851 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
15852 }
developer72fb0bb2023-01-11 09:46:29 +080015853}
15854
15855static int init_wpa()
15856{
developer9ce44382023-06-28 11:09:37 +080015857 int ret = 0;
developera3511852023-06-14 14:12:59 +080015858 ULONG s, snum;
developer72fb0bb2023-01-11 09:46:29 +080015859
developera3511852023-06-14 14:12:59 +080015860 ret = wifi_getSSIDNumberOfEntries(&snum);
15861 if (ret != RETURN_OK) {
15862 printf("%s: failed to get SSID count", __func__);
15863 return RETURN_ERR;
15864 }
developer72fb0bb2023-01-11 09:46:29 +080015865
developera3511852023-06-14 14:12:59 +080015866 if (snum > MAX_APS) {
15867 printf("more ssid than supported! %lu\n", snum);
15868 return RETURN_ERR;
15869 }
developer72fb0bb2023-01-11 09:46:29 +080015870
developera3511852023-06-14 14:12:59 +080015871 for (s = 0; s < snum; s++) {
15872 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
developer32f2a182023-06-27 19:50:41 +080015873 ret = snprintf(wpa_ctrl[s].sockpath, sizeof(wpa_ctrl[s].sockpath), "%s%lu", SOCK_PREFIX, s);
15874 if (os_snprintf_error(sizeof(wpa_ctrl[s].sockpath), ret)) {
15875 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15876 return RETURN_ERR;
15877 }
developera3511852023-06-14 14:12:59 +080015878 wpa_ctrl[s].ssid_index = s;
15879 ctrl_enable(&wpa_ctrl[s]);
15880 }
developer72fb0bb2023-01-11 09:46:29 +080015881
developera3511852023-06-14 14:12:59 +080015882 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
15883 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
developer72fb0bb2023-01-11 09:46:29 +080015884
developera3511852023-06-14 14:12:59 +080015885 initialized = 1;
15886 printf("WPA_CTRL: initialized\n");
developer72fb0bb2023-01-11 09:46:29 +080015887
developera3511852023-06-14 14:12:59 +080015888 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015889}
15890
15891void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
15892{
developera3511852023-06-14 14:12:59 +080015893 clients_connect_cb = callback_proc;
15894 if (!initialized)
15895 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080015896}
15897
15898void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
15899{
developera3511852023-06-14 14:12:59 +080015900 clients_disconnect_cb = callback_proc;
15901 if (!initialized)
15902 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080015903}
15904
15905INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
15906{
developera3511852023-06-14 14:12:59 +080015907 // TODO Implement me!
15908 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015909}
15910
15911INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
15912{
developera3511852023-06-14 14:12:59 +080015913 // TODO Implement me!
15914 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015915}
15916
15917INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
15918{
developera3511852023-06-14 14:12:59 +080015919 int i;
15920 int phyId = -1;
15921 char cmd[256] = {0};
15922 char channel_numbers_buf[256] = {0};
15923 char dfs_state_buf[256] = {0};
15924 char line[256] = {0};
15925 const char *ptr;
15926 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +080015927 int res;
developer72fb0bb2023-01-11 09:46:29 +080015928
developera3511852023-06-14 14:12:59 +080015929 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080015930
developera3511852023-06-14 14:12:59 +080015931 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
15932 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080015933
developere40952c2023-06-15 18:46:43 +080015934 res = 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\\|");
15935 if (os_snprintf_error(sizeof(cmd), res)) {
15936 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15937 return RETURN_ERR;
15938 }
developer72fb0bb2023-01-11 09:46:29 +080015939
developera3511852023-06-14 14:12:59 +080015940 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
15941 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
15942 return RETURN_ERR;
15943 }
developer72fb0bb2023-01-11 09:46:29 +080015944
developera3511852023-06-14 14:12:59 +080015945 ptr = channel_numbers_buf;
15946 i = 0;
15947 while ((ptr = get_line_from_str_buf(ptr, line))) {
15948 if (i >= outputMapSize) {
15949 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
15950 return RETURN_ERR;
15951 }
developerd14dff12023-06-28 22:47:44 +080015952 if (sscanf(line, "%d", &outputMap[i].ch_number) != 1) {
15953 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
15954 return RETURN_ERR;
15955 }
developerd1824452023-05-18 12:30:04 +080015956
developera3511852023-06-14 14:12:59 +080015957 memset(cmd, 0, sizeof(cmd));
15958 // Below command should fetch string for DFS state (usable, available or unavailable)
15959 // Example line: "DFS state: usable (for 78930 sec)"
15960 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) {
15961 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
15962 return RETURN_ERR;
15963 }
developer72fb0bb2023-01-11 09:46:29 +080015964
developera3511852023-06-14 14:12:59 +080015965 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
15966 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
15967 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
15968 return RETURN_ERR;
15969 }
developer72fb0bb2023-01-11 09:46:29 +080015970
developera3511852023-06-14 14:12:59 +080015971 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080015972
developera3511852023-06-14 14:12:59 +080015973 if (!strcmp(dfs_state_buf, "usable")) {
15974 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
15975 } else if (!strcmp(dfs_state_buf, "available")) {
15976 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
15977 } else if (!strcmp(dfs_state_buf, "unavailable")) {
15978 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
15979 } else {
15980 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
15981 }
15982 i++;
15983 }
developer40ba1762023-05-13 11:03:49 +080015984
developera3511852023-06-14 14:12:59 +080015985 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +080015986
developera3511852023-06-14 14:12:59 +080015987 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
15988 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015989}
15990
15991INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
15992{
developera3511852023-06-14 14:12:59 +080015993 // TODO Implement me!
15994 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015995}
15996
15997INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
15998{
developer0155a502023-06-19 20:33:57 +080015999 int ret = -1;
16000 char inf_name[IF_NAME_SIZE] = {0};
16001 int if_idx = 0;
16002 struct unl unl_ins;
16003 struct nl_msg *msg = NULL;
16004 struct nlattr * msg_data = NULL;
16005 struct mtk_nl80211_param param;
16006 struct mtk_nl80211_cb_data cb_data;
16007 wdev_ap_metric ap_metric;
16008
16009 /*init mtk nl80211 vendor cmd*/
16010
16011 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
16012 return RETURN_ERR;
16013 if_idx = if_nametoindex(inf_name);
16014 if (!if_idx) {
16015 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
16016 return RETURN_ERR;
16017 }
16018
16019 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STATISTIC;
16020 param.if_type = NL80211_ATTR_IFINDEX;
16021 param.if_idx = if_idx;
16022
16023 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
16024 if (ret) {
16025 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
16026 return RETURN_ERR;
16027 }
16028
16029 /*add mtk vendor cmd data*/
16030
16031 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS, sizeof(wdev_ap_metric), (char *)&ap_metric)) {
16032 wifi_debug(DEBUG_ERROR, "Nla put GET_AP_METRICS attribute error\n");
16033 nlmsg_free(msg);
16034 goto err;
16035 }
16036
16037 /*send mtk nl80211 vendor msg*/
16038 cb_data.out_buf = (char *)output_percentage;
16039 cb_data.out_len = sizeof(wdev_ap_metric);
16040 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_metrics, &cb_data);
16041 if (ret) {
16042 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
16043 goto err;
16044 }
16045
16046 /*deinit mtk nl80211 vendor msg*/
16047 mtk_nl80211_deint(&unl_ins);
16048 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
16049 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16050
developera3511852023-06-14 14:12:59 +080016051 return RETURN_OK;
developer0155a502023-06-19 20:33:57 +080016052err:
16053 mtk_nl80211_deint(&unl_ins);
16054 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
16055 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016056}
16057
developer0155a502023-06-19 20:33:57 +080016058
developer72fb0bb2023-01-11 09:46:29 +080016059INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
16060{
developera3511852023-06-14 14:12:59 +080016061 // TODO Implement me!
16062 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016063}
16064
16065INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
16066{
developera3511852023-06-14 14:12:59 +080016067 // TODO API refrence Implementaion is present on RPI hal
16068 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016069}
16070
16071INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
16072{
developera3511852023-06-14 14:12:59 +080016073 ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080016074
developera3511852023-06-14 14:12:59 +080016075 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16076 if(txpwr_pcntg == NULL)
developerdaf24792023-06-06 11:40:04 +080016077 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016078
developera1255e42023-05-13 17:45:02 +080016079 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
16080 *txpwr_pcntg = pwr_percentage;
developera3511852023-06-14 14:12:59 +080016081 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16082 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016083}
16084
16085INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
16086{
developera3511852023-06-14 14:12:59 +080016087 // TODO precac feature.
16088 struct params params[2] = {0};
16089 char config_file[128] = {0};
16090 BOOL dfs_enable = false;
16091 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080016092 int res;
developer72fb0bb2023-01-11 09:46:29 +080016093
developera3511852023-06-14 14:12:59 +080016094 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16095 band = wifi_index_to_band(radioIndex);
16096 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080016097
developera3511852023-06-14 14:12:59 +080016098 if (dfs_enable == false) {
16099 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
16100 return RETURN_ERR;
16101 }
16102 params[0].name = "DfsZeroWaitDefault";
16103 params[0].value = enable?"1":"0";
16104 params[1].name = "DfsDedicatedZeroWait";
16105 params[1].value = enable?"1":"0";
developere40952c2023-06-15 18:46:43 +080016106 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16107 if (os_snprintf_error(sizeof(config_file), res)) {
16108 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16109 return RETURN_ERR;
16110 }
developera3511852023-06-14 14:12:59 +080016111 wifi_datfileWrite(config_file, params, 2);
16112 wifi_reloadAp(radioIndex);
16113 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080016114
developera3511852023-06-14 14:12:59 +080016115 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16116 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016117}
16118
16119INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
16120{
developera3511852023-06-14 14:12:59 +080016121 char config_file[128] = {0};
16122 char buf1[32] = {0};
16123 char buf2[32] = {0};
16124 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080016125 int res;
developer72fb0bb2023-01-11 09:46:29 +080016126
developera3511852023-06-14 14:12:59 +080016127 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16128 if (NULL == enable || NULL == precac)
16129 return RETURN_ERR;
16130 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080016131 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16132 if (os_snprintf_error(sizeof(config_file), res)) {
16133 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16134 return RETURN_ERR;
16135 }
developera3511852023-06-14 14:12:59 +080016136 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
16137 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
16138 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
16139 *enable = true;
16140 else
16141 *enable = false;
developer72fb0bb2023-01-11 09:46:29 +080016142
developera3511852023-06-14 14:12:59 +080016143 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080016144
developera3511852023-06-14 14:12:59 +080016145 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16146 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016147}
16148
16149INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
16150{
developera3511852023-06-14 14:12:59 +080016151 *supported = TRUE;
16152 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016153}
16154
16155INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
16156{
developer863a4a62023-06-06 16:55:59 +080016157 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016158 wifi_band band = band_invalid;
16159 char ofdmabuf[32] = {'\0'};
16160 char mimobuf[32] = {'\0'};
16161 char new_ofdmabuf[32] = {'\0'};
16162 char new_mimobuf[32] = {'\0'};
16163 struct params params[2];
developera1255e42023-05-13 17:45:02 +080016164 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
16165 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
16166 UCHAR bss_cnt = 0;
16167 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080016168 int res;
developer72fb0bb2023-01-11 09:46:29 +080016169
developera3511852023-06-14 14:12:59 +080016170 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +080016171 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
16172 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
16173 printf("%s:mu_type input Error", __func__);
16174 return RETURN_ERR;
16175 }
developera3511852023-06-14 14:12:59 +080016176 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080016177 if (band == band_invalid) {
16178 printf("%s:Band Error\n", __func__);
16179 return RETURN_ERR;
16180 }
developere40952c2023-06-15 18:46:43 +080016181 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16182 if (os_snprintf_error(sizeof(dat_file), res)) {
16183 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16184 return RETURN_ERR;
16185 }
16186
developera1255e42023-05-13 17:45:02 +080016187 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080016188 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
16189 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080016190 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
16191 get_bssnum_byindex(radio_index, &bss_cnt);
16192 val_cnt = 2*bss_cnt - 1;
16193 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
16194 if ((val_cnt >= sizeof(new_ofdmabuf))
16195 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080016196 printf("%s:bss cnt Error", __func__);
developera1255e42023-05-13 17:45:02 +080016197 return RETURN_ERR;
16198 }
16199 /*translate set value*/
16200 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
16201 strncpy(new_ofdmabuf, str_zero, val_cnt);
16202 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016203 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080016204 strncpy(new_ofdmabuf, str_one, val_cnt);
16205 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016206 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080016207 strncpy(new_ofdmabuf, str_zero, val_cnt);
16208 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080016209 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
developera1255e42023-05-13 17:45:02 +080016210 strncpy(new_ofdmabuf, str_one, val_cnt);
16211 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080016212 }
developera1255e42023-05-13 17:45:02 +080016213 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
16214 /*same value, not operation*/
16215 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
16216 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
16217 printf("%s:Reduntant value\n", __func__);
16218 return RETURN_OK;
16219 }
16220 /*modify dat file to new file*/
16221 params[0].name="MuOfdmaDlEnable";
16222 params[0].value=new_ofdmabuf;
16223 params[1].name="MuMimoDlEnable";
16224 params[1].value=new_mimobuf;
16225 wifi_datfileWrite(dat_file, params, 2);
16226 /*hostapd control restarp ap to take effect on these new value*/
16227 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080016228 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16229 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016230}
16231
16232INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
16233{
developer5a333cf2023-06-06 18:18:50 +080016234 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016235 wifi_band band = band_invalid;
16236 char ofdmabuf[32] = {'\0'};
16237 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080016238 char *token = NULL;
developerc14d83a2023-06-29 20:09:42 +080016239 long int ofdma = 0;
16240 long int mimo = 0;
developere40952c2023-06-15 18:46:43 +080016241 int res;
developer72fb0bb2023-01-11 09:46:29 +080016242
developera3511852023-06-14 14:12:59 +080016243 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016244
developera3511852023-06-14 14:12:59 +080016245 if (mu_type == NULL)
16246 return RETURN_ERR;
16247 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080016248 if (band == band_invalid) {
16249 printf("%s:Band Error\n", __func__);
16250 return RETURN_ERR;
16251 }
developere40952c2023-06-15 18:46:43 +080016252 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16253 if (os_snprintf_error(sizeof(dat_file), res)) {
16254 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16255 return RETURN_ERR;
16256 }
developera1255e42023-05-13 17:45:02 +080016257 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080016258 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
16259 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080016260
developera1255e42023-05-13 17:45:02 +080016261 token = strtok(ofdmabuf, ";");
developerd14dff12023-06-28 22:47:44 +080016262 if (token == NULL) {
16263 wifi_debug(DEBUG_ERROR, "strtok fail\n");
16264 return RETURN_ERR;
16265 }
developerc14d83a2023-06-29 20:09:42 +080016266 if (hal_strtol(token, 10, &ofdma) < 0) {
16267 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080016268 }
developerc14d83a2023-06-29 20:09:42 +080016269
developera1255e42023-05-13 17:45:02 +080016270 token = strtok(mimobuf, ";");
developer37646972023-06-29 10:58:43 +080016271 if (token == NULL) {
16272 wifi_debug(DEBUG_ERROR, "Unexpected strtok fail\n");
16273 return RETURN_ERR;
16274 }
developerc14d83a2023-06-29 20:09:42 +080016275
16276 if (hal_strtol(token, 10, &mimo) < 0) {
16277 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +080016278 }
developerc14d83a2023-06-29 20:09:42 +080016279
developera1255e42023-05-13 17:45:02 +080016280 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
16281 if ((ofdma == 1) && (mimo == 1))
16282 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
16283 else if ((ofdma == 0) && (mimo == 1))
16284 *mu_type = WIFI_DL_MU_TYPE_MIMO;
16285 else if ((ofdma == 1) && (mimo == 0))
16286 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
16287 else
16288 *mu_type = WIFI_DL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080016289 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16290 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016291}
16292
16293INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
16294{
developera3511852023-06-14 14:12:59 +080016295 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developer863a4a62023-06-06 16:55:59 +080016296 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016297 wifi_band band = band_invalid;
16298 char ofdmabuf[32] = {'\0'};
16299 char mimobuf[32] = {'\0'};
16300 char new_ofdmabuf[32] = {'\0'};
16301 char new_mimobuf[32] = {'\0'};
16302 struct params params[2];
developera1255e42023-05-13 17:45:02 +080016303 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
16304 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
16305 UCHAR bss_cnt = 0;
16306 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080016307 int res;
developer72fb0bb2023-01-11 09:46:29 +080016308
developera3511852023-06-14 14:12:59 +080016309 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16310 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080016311 if (band == band_invalid) {
16312 printf("%s:Band Error\n", __func__);
16313 return RETURN_ERR;
16314 }
16315 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
16316 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
16317 printf("%s:mu_type input Error\n", __func__);
16318 return RETURN_ERR;
16319 }
developere40952c2023-06-15 18:46:43 +080016320 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16321 if (os_snprintf_error(sizeof(dat_file), res)) {
16322 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16323 return RETURN_ERR;
16324 }
developera1255e42023-05-13 17:45:02 +080016325 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080016326 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
16327 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080016328 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
16329 get_bssnum_byindex(radio_index, &bss_cnt);
16330 val_cnt = 2*bss_cnt - 1;
16331 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
16332 if ((val_cnt >= sizeof(new_ofdmabuf))
16333 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080016334 printf("%s:bss cnt Error\n", __func__);
developera1255e42023-05-13 17:45:02 +080016335 return RETURN_ERR;
16336 }
16337 /*translate set value*/
16338 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
16339 strncpy(new_ofdmabuf, str_zero, val_cnt);
16340 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016341 }
developera1255e42023-05-13 17:45:02 +080016342 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
16343 strncpy(new_ofdmabuf, str_one, val_cnt);
16344 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016345 }
developera1255e42023-05-13 17:45:02 +080016346 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
16347 /*same value, not operation*/
16348 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
16349 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
16350 printf("%s:Reduntant value\n", __func__);
16351 return RETURN_OK;
16352 }
16353 /*modify dat file to new file*/
16354 params[0].name="MuOfdmaUlEnable";
16355 params[0].value=new_ofdmabuf;
16356 params[1].name="MuMimoUlEnable";
16357 params[1].value=new_mimobuf;
16358 wifi_datfileWrite(dat_file, params, 2);
16359 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080016360 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16361 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016362}
16363
16364INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
16365{
developer863a4a62023-06-06 16:55:59 +080016366 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016367 wifi_band band = band_invalid;
16368 char ofdmabuf[32] = {'\0'};
16369 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080016370 char *token = NULL;
16371 UCHAR ofdma = 0;
16372 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080016373 int res;
developerc14d83a2023-06-29 20:09:42 +080016374 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080016375
developera3511852023-06-14 14:12:59 +080016376 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016377
developera3511852023-06-14 14:12:59 +080016378 if (mu_type == NULL)
16379 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080016380 band = wifi_index_to_band(radio_index);
16381 if (band == band_invalid) {
16382 printf("%s:Band Error", __func__);
16383 return RETURN_ERR;
16384 }
developere40952c2023-06-15 18:46:43 +080016385 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16386 if (os_snprintf_error(sizeof(dat_file), res)) {
16387 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16388 return RETURN_ERR;
16389 }
developera1255e42023-05-13 17:45:02 +080016390 /*get current value in dat file*/
16391 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
16392 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080016393
developera1255e42023-05-13 17:45:02 +080016394 token = strtok(ofdmabuf, ";");
developerd14dff12023-06-28 22:47:44 +080016395 if (token == NULL) {
16396 wifi_debug(DEBUG_ERROR, "strtok fail\n");
16397 return RETURN_ERR;
16398 }
developerc14d83a2023-06-29 20:09:42 +080016399
16400 if (hal_strtoul(token, 10, &tmp) < 0) {
16401 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerd14dff12023-06-28 22:47:44 +080016402 return RETURN_ERR;
16403 }
developerc14d83a2023-06-29 20:09:42 +080016404 ofdma = tmp;
developera1255e42023-05-13 17:45:02 +080016405 token = strtok(mimobuf, ";");
developer37646972023-06-29 10:58:43 +080016406 if (token == NULL) {
16407 wifi_debug(DEBUG_ERROR, "strtok fail\n");
16408 return RETURN_ERR;
16409 }
developerc14d83a2023-06-29 20:09:42 +080016410
16411 if (hal_strtoul(token, 10, &tmp) < 0) {
16412 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developer37646972023-06-29 10:58:43 +080016413 return RETURN_ERR;
16414 }
developerc14d83a2023-06-29 20:09:42 +080016415 mimo = tmp;
16416
developera1255e42023-05-13 17:45:02 +080016417 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
16418 if ((ofdma == 1) && (mimo == 0))
16419 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
16420 else
16421 *mu_type = WIFI_UL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080016422 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16423 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016424}
16425
16426
16427INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
16428{
developera3511852023-06-14 14:12:59 +080016429 char cmd[128] = {0};
16430 char buf[256] = {0};
16431 char config_file[64] = {0};
16432 char GI[8] = {0};
16433 UINT mode_map = 0;
16434 FILE *f = NULL;
16435 wifi_band band = band_invalid;
16436 char dat_file[64] = {'\0'};
16437 struct params params[3];
developere40952c2023-06-15 18:46:43 +080016438 int res;
developer72fb0bb2023-01-11 09:46:29 +080016439
developera3511852023-06-14 14:12:59 +080016440 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016441
developera3511852023-06-14 14:12:59 +080016442 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
16443 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
16444 return RETURN_ERR;
16445 }
developera1255e42023-05-13 17:45:02 +080016446 /*sanity check*/
16447 if (((guard_interval == wifi_guard_interval_1600)
16448 || (guard_interval == wifi_guard_interval_3200))
developerdaf24792023-06-06 11:40:04 +080016449 && ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
developera3511852023-06-14 14:12:59 +080016450 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
16451 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080016452 }
developere40952c2023-06-15 18:46:43 +080016453 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16454 if (os_snprintf_error(sizeof(config_file), res)) {
16455 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16456 return RETURN_ERR;
16457 }
developera3511852023-06-14 14:12:59 +080016458 band = wifi_index_to_band(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080016459
developera3511852023-06-14 14:12:59 +080016460 // Hostapd are not supported HE mode GI 1600, 3200 ns.
16461 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
developere40952c2023-06-15 18:46:43 +080016462 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
16463 if (os_snprintf_error(sizeof(cmd), res)) {
16464 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16465 return RETURN_ERR;
16466 }
developera3511852023-06-14 14:12:59 +080016467 _syscmd(cmd, buf, sizeof(buf));
16468 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
16469 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
16470 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080016471 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
16472 if (os_snprintf_error(sizeof(cmd), res)) {
16473 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16474 return RETURN_ERR;
16475 }
developera3511852023-06-14 14:12:59 +080016476 _syscmd(cmd, buf, sizeof(buf));
16477 }
16478 if (band == band_5) {
16479 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
16480 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080016481 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
16482 if (os_snprintf_error(sizeof(cmd), res)) {
16483 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16484 return RETURN_ERR;
16485 }
developera3511852023-06-14 14:12:59 +080016486 _syscmd(cmd, buf, sizeof(buf));
16487 }
16488 }
16489 }
16490 /*wifi_reloadAp(radio_index);
developera1255e42023-05-13 17:45:02 +080016491 caller "wifi_setRadioOperatingParameters" have done this step.
16492 */
developere40952c2023-06-15 18:46:43 +080016493 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16494 if (os_snprintf_error(sizeof(dat_file), res)) {
16495 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16496 return RETURN_ERR;
16497 }
developera3511852023-06-14 14:12:59 +080016498 if (guard_interval == wifi_guard_interval_400) {
developera1255e42023-05-13 17:45:02 +080016499 params[0].name = "HT_GI";
16500 params[0].value = "1";
16501 params[1].name = "VHT_SGI";
16502 params[1].value = "1";
16503 wifi_datfileWrite(dat_file, params, 2);
developer32f2a182023-06-27 19:50:41 +080016504 memcpy(GI, "0.4", 3);
developera1255e42023-05-13 17:45:02 +080016505 } else {
16506 params[0].name = "HT_GI";
16507 params[0].value = "0";
16508 params[1].name = "VHT_SGI";
16509 params[1].value = "0";
16510 /*should enable FIXED_HE_GI_SUPPORT in driver*/
16511 params[2].name = "FgiFltf";
16512 if (guard_interval == wifi_guard_interval_800) {
16513 params[2].value = "800";
developer32f2a182023-06-27 19:50:41 +080016514 memcpy(GI, "0.8", 3);
developera1255e42023-05-13 17:45:02 +080016515 } else if (guard_interval == wifi_guard_interval_1600) {
16516 params[2].value = "1600";
developer32f2a182023-06-27 19:50:41 +080016517 memcpy(GI, "1.6", 3);
developera1255e42023-05-13 17:45:02 +080016518 } else if (guard_interval == wifi_guard_interval_3200) {
16519 params[2].value = "3200";
developer32f2a182023-06-27 19:50:41 +080016520 memcpy(GI, "3.2", 3);
developera1255e42023-05-13 17:45:02 +080016521 } else if (guard_interval == wifi_guard_interval_auto) {
16522 params[2].value = "0";
developer32f2a182023-06-27 19:50:41 +080016523 memcpy(GI, "auto", 4);
developera1255e42023-05-13 17:45:02 +080016524 }
16525 wifi_datfileWrite(dat_file, params, 3);
16526 }
developera3511852023-06-14 14:12:59 +080016527 // Record GI for get GI function
developere40952c2023-06-15 18:46:43 +080016528 res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
16529 if (os_snprintf_error(sizeof(buf), res)) {
16530 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16531 return RETURN_ERR;
16532 }
developera3511852023-06-14 14:12:59 +080016533 f = fopen(buf, "w");
16534 if (f == NULL)
16535 return RETURN_ERR;
16536 fprintf(f, "%s", GI);
developerc14d83a2023-06-29 20:09:42 +080016537 if (fclose(f) == EOF)
16538 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera3511852023-06-14 14:12:59 +080016539 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16540 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016541}
16542
16543INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
16544{
developera3511852023-06-14 14:12:59 +080016545 char buf[32] = {0};
16546 char cmd[64] = {0};
developere40952c2023-06-15 18:46:43 +080016547 int res;
developer72fb0bb2023-01-11 09:46:29 +080016548
developera3511852023-06-14 14:12:59 +080016549 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016550
developera3511852023-06-14 14:12:59 +080016551 if (guard_interval == NULL)
16552 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016553
developere40952c2023-06-15 18:46:43 +080016554 res = snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
16555 if (os_snprintf_error(sizeof(cmd), res)) {
16556 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16557 return RETURN_ERR;
16558 }
developera3511852023-06-14 14:12:59 +080016559 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080016560
developera3511852023-06-14 14:12:59 +080016561 if (strncmp(buf, "0.4", 3) == 0)
16562 *guard_interval = wifi_guard_interval_400;
16563 else if (strncmp(buf, "0.8", 3) == 0)
16564 *guard_interval = wifi_guard_interval_800;
16565 else if (strncmp(buf, "1.6", 3) == 0)
16566 *guard_interval = wifi_guard_interval_1600;
16567 else if (strncmp(buf, "3.2", 3) == 0)
16568 *guard_interval = wifi_guard_interval_3200;
16569 else
16570 *guard_interval = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +080016571
developera3511852023-06-14 14:12:59 +080016572 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16573 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016574}
16575
16576INT wifi_setBSSColor(INT radio_index, UCHAR color)
16577{
developera3511852023-06-14 14:12:59 +080016578 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16579 struct params params = {0};
16580 char config_file[128] = {0};
16581 char bss_color[4] ={0};
developere40952c2023-06-15 18:46:43 +080016582 int res;
developer72fb0bb2023-01-11 09:46:29 +080016583
developera1255e42023-05-13 17:45:02 +080016584 if (color < 1 || color > 63) {
16585 wifi_dbg_printf("color value is err:%d.\n", color);
16586 return RETURN_ERR;
16587 }
developera3511852023-06-14 14:12:59 +080016588 params.name = "he_bss_color";
developere40952c2023-06-15 18:46:43 +080016589 res = snprintf(bss_color, sizeof(bss_color), "%hhu", color);
16590 if (os_snprintf_error(sizeof(bss_color), res)) {
16591 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16592 return RETURN_ERR;
16593 }
developera3511852023-06-14 14:12:59 +080016594 params.value = bss_color;
developer75bd10c2023-06-27 11:34:08 +080016595
16596 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16597 if (os_snprintf_error(sizeof(config_file), res)) {
16598 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16599 return RETURN_ERR;
16600 }
developera3511852023-06-14 14:12:59 +080016601 wifi_hostapdWrite(config_file, &params, 1);
16602 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
developera1255e42023-05-13 17:45:02 +080016603 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080016604
developera3511852023-06-14 14:12:59 +080016605 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16606 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016607}
16608
16609INT wifi_getBSSColor(INT radio_index, UCHAR *color)
16610{
developera3511852023-06-14 14:12:59 +080016611 char config_file[128] = {0};
16612 char buf[64] = {0};
16613 char temp_output[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +080016614 int res;
developerc14d83a2023-06-29 20:09:42 +080016615 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080016616
developera3511852023-06-14 14:12:59 +080016617 wifi_dbg_printf("\nFunc=%s\n", __func__);
16618 if (NULL == color)
16619 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016620
developer75bd10c2023-06-27 11:34:08 +080016621 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16622 if (os_snprintf_error(sizeof(config_file), res)) {
16623 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16624 return RETURN_ERR;
16625 }
developera3511852023-06-14 14:12:59 +080016626 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080016627
developera3511852023-06-14 14:12:59 +080016628 if(strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +080016629 res = snprintf(temp_output, sizeof(temp_output), "%s", buf);
developera3511852023-06-14 14:12:59 +080016630 } else {
developere40952c2023-06-15 18:46:43 +080016631 res = snprintf(temp_output, sizeof(temp_output), "1"); // default value
16632 }
16633 if (os_snprintf_error(sizeof(temp_output), res)) {
16634 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16635 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080016636 }
developer72fb0bb2023-01-11 09:46:29 +080016637
developerc14d83a2023-06-29 20:09:42 +080016638 if (hal_strtoul(temp_output, 10, &tmp) < 0) {
16639 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerd14dff12023-06-28 22:47:44 +080016640 return RETURN_ERR;
16641 }
developerc14d83a2023-06-29 20:09:42 +080016642 *color = tmp;
developera3511852023-06-14 14:12:59 +080016643 wifi_dbg_printf("\noutput_string=%s\n", color);
developer72fb0bb2023-01-11 09:46:29 +080016644
developera3511852023-06-14 14:12:59 +080016645 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016646}
16647
16648/* multi-psk support */
16649INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
16650{
developera3511852023-06-14 14:12:59 +080016651 char cmd[256];
16652 char interface_name[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080016653 int res;
developer72fb0bb2023-01-11 09:46:29 +080016654
developera3511852023-06-14 14:12:59 +080016655 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16656 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016657
developer75bd10c2023-06-27 11:34:08 +080016658 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
developera3511852023-06-14 14:12:59 +080016659 interface_name,
16660 mac[0],
16661 mac[1],
16662 mac[2],
16663 mac[3],
16664 mac[4],
16665 mac[5]
16666 );
developer75bd10c2023-06-27 11:34:08 +080016667 if (os_snprintf_error(sizeof(cmd), res)) {
16668 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16669 return RETURN_ERR;
16670 }
developera3511852023-06-14 14:12:59 +080016671 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
16672 _syscmd(cmd, key->wifi_keyId, 64);
developer72fb0bb2023-01-11 09:46:29 +080016673
16674
developera3511852023-06-14 14:12:59 +080016675 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016676}
16677
16678INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
16679{
developera3511852023-06-14 14:12:59 +080016680 char interface_name[16] = {0};
16681 FILE *fd = NULL;
16682 char fname[100];
16683 char cmd[128] = {0};
16684 char out[64] = {0};
16685 wifi_key_multi_psk_t * key = NULL;
developer75bd10c2023-06-27 11:34:08 +080016686 int res, ret;
developere40952c2023-06-15 18:46:43 +080016687
developera3511852023-06-14 14:12:59 +080016688 if(keysNumber < 0)
16689 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016690
developere40952c2023-06-15 18:46:43 +080016691 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
16692 if (os_snprintf_error(sizeof(fname), res)) {
16693 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16694 return RETURN_ERR;
16695 }
developera3511852023-06-14 14:12:59 +080016696 fd = fopen(fname, "w");
16697 if (!fd) {
16698 return RETURN_ERR;
16699 }
16700 key= (wifi_key_multi_psk_t *) keys;
16701 for(int i=0; i<keysNumber; ++i, key++) {
developer75bd10c2023-06-27 11:34:08 +080016702 ret = fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
16703 if (ret < 0)
16704 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developera3511852023-06-14 14:12:59 +080016705 }
developerd14dff12023-06-28 22:47:44 +080016706 if (fclose(fd) != 0) {
16707 wifi_debug(DEBUG_ERROR, "fclose fail\n");
16708 return RETURN_ERR;
16709 }
developer72fb0bb2023-01-11 09:46:29 +080016710
developera3511852023-06-14 14:12:59 +080016711 //reload file
16712 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16713 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080016714 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
16715
16716 if (os_snprintf_error(sizeof(cmd), res)) {
16717 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16718 return RETURN_ERR;
16719 }
developera3511852023-06-14 14:12:59 +080016720 _syscmd(cmd, out, 64);
16721 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016722}
16723
16724INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
16725{
developera3511852023-06-14 14:12:59 +080016726 FILE *fd = NULL;
16727 char fname[100];
16728 char * line = NULL;
16729 char * pos = NULL;
16730 size_t len = 0;
16731 ssize_t read = 0;
16732 INT ret = RETURN_OK;
16733 wifi_key_multi_psk_t *keys_it = NULL;
developere40952c2023-06-15 18:46:43 +080016734 int res;
developer72fb0bb2023-01-11 09:46:29 +080016735
developera3511852023-06-14 14:12:59 +080016736 if (keysNumber < 1) {
16737 return RETURN_ERR;
16738 }
developer72fb0bb2023-01-11 09:46:29 +080016739
developere40952c2023-06-15 18:46:43 +080016740 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
16741 if (os_snprintf_error(sizeof(fname), res)) {
16742 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16743 return RETURN_ERR;
16744 }
developera3511852023-06-14 14:12:59 +080016745 fd = fopen(fname, "r");
16746 if (!fd) {
16747 return RETURN_ERR;
16748 }
developer72fb0bb2023-01-11 09:46:29 +080016749
developera3511852023-06-14 14:12:59 +080016750 if (keys == NULL) {
16751 ret = RETURN_ERR;
16752 goto close;
16753 }
developer72fb0bb2023-01-11 09:46:29 +080016754
developera3511852023-06-14 14:12:59 +080016755 keys_it = keys;
16756 while ((read = getline(&line, &len, fd)) != -1) {
16757 //Strip trailing new line if present
16758 if (read > 0 && line[read-1] == '\n') {
16759 line[read-1] = '\0';
16760 }
developer72fb0bb2023-01-11 09:46:29 +080016761
developera3511852023-06-14 14:12:59 +080016762 if(strcmp(line,"keyid=")) {
developer37646972023-06-29 10:58:43 +080016763 if (sscanf(line, "keyid=%63s", keys_it->wifi_keyId) == EOF)
16764 continue;
developera3511852023-06-14 14:12:59 +080016765 if (!(pos = index(line, ' '))) {
16766 ret = RETURN_ERR;
16767 goto close;
16768 }
16769 pos++;
16770 //Here should be 00:00:00:00:00:00
16771 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
16772 printf("Not supported MAC: %s\n", pos);
16773 }
16774 if (!(pos = index(pos, ' '))) {
16775 ret = RETURN_ERR;
16776 goto close;
16777 }
16778 pos++;
developer72fb0bb2023-01-11 09:46:29 +080016779
developera3511852023-06-14 14:12:59 +080016780 //The rest is PSK
developere40952c2023-06-15 18:46:43 +080016781 res = snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
16782 if (os_snprintf_error(sizeof(keys_it->wifi_psk), res)) {
16783 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080016784 if (fclose(fd) == EOF)
16785 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
16786
developere40952c2023-06-15 18:46:43 +080016787 return RETURN_ERR;
16788 }
16789
developera3511852023-06-14 14:12:59 +080016790 keys_it++;
developer72fb0bb2023-01-11 09:46:29 +080016791
developera3511852023-06-14 14:12:59 +080016792 if(--keysNumber <= 0)
developer72fb0bb2023-01-11 09:46:29 +080016793 break;
developera3511852023-06-14 14:12:59 +080016794 }
16795 }
developer72fb0bb2023-01-11 09:46:29 +080016796
16797close:
developera3511852023-06-14 14:12:59 +080016798 free(line);
developer37646972023-06-29 10:58:43 +080016799 if (fclose(fd) == EOF)
16800 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera3511852023-06-14 14:12:59 +080016801 return ret;
developer72fb0bb2023-01-11 09:46:29 +080016802}
16803/* end of multi-psk support */
16804
16805INT wifi_setNeighborReports(UINT apIndex,
developera3511852023-06-14 14:12:59 +080016806 UINT numNeighborReports,
16807 wifi_NeighborReport_t *neighborReports)
developer72fb0bb2023-01-11 09:46:29 +080016808{
developera3511852023-06-14 14:12:59 +080016809 char cmd[256] = { 0 };
16810 char hex_bssid[13] = { 0 };
16811 char bssid[18] = { 0 };
16812 char nr[100] = { 0 };
16813 char ssid[32];
16814 char hex_ssid[32];
16815 char interface_name[16] = {0};
16816 INT ret;
developere40952c2023-06-15 18:46:43 +080016817 int res;
developerd14dff12023-06-28 22:47:44 +080016818 unsigned char hex_ssid_len;
developer72fb0bb2023-01-11 09:46:29 +080016819
developera3511852023-06-14 14:12:59 +080016820 /*rmeove all neighbors*/
16821 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
16822 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16823 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080016824 res = snprintf(cmd, sizeof(cmd),
16825 "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
16826 interface_name, interface_name);
16827
developer75bd10c2023-06-27 11:34:08 +080016828 if (os_snprintf_error(sizeof(cmd), res)) {
16829 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16830 return RETURN_ERR;
16831 }
developera3511852023-06-14 14:12:59 +080016832 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080016833
developera3511852023-06-14 14:12:59 +080016834 for(unsigned int i = 0; i < numNeighborReports; i++)
16835 {
16836 memset(ssid, 0, sizeof(ssid));
16837 ret = wifi_getSSIDName(apIndex, ssid);
16838 if (ret != RETURN_OK)
16839 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016840
developera3511852023-06-14 14:12:59 +080016841 memset(hex_ssid, 0, sizeof(hex_ssid));
developerd14dff12023-06-28 22:47:44 +080016842 hex_ssid_len = sizeof(hex_ssid);
16843 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 ) {
16844 res = snprintf(hex_ssid + k, hex_ssid_len, "%02x", ssid[j]);
16845
16846 if (os_snprintf_error(hex_ssid_len, res)) {
16847 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16848 return RETURN_ERR;
16849 }
16850 hex_ssid_len = sizeof(hex_ssid) - strlen(hex_ssid);
16851 }
developer72fb0bb2023-01-11 09:46:29 +080016852
developere40952c2023-06-15 18:46:43 +080016853 res = snprintf(hex_bssid, sizeof(hex_bssid),
developera3511852023-06-14 14:12:59 +080016854 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
16855 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
developere40952c2023-06-15 18:46:43 +080016856 if (os_snprintf_error(sizeof(hex_bssid), res)) {
16857 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16858 return RETURN_ERR;
16859 }
16860 res = snprintf(bssid, sizeof(bssid),
developera3511852023-06-14 14:12:59 +080016861 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
16862 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
developere40952c2023-06-15 18:46:43 +080016863 if (os_snprintf_error(sizeof(bssid), res)) {
16864 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16865 return RETURN_ERR;
16866 }
developer72fb0bb2023-01-11 09:46:29 +080016867
developere40952c2023-06-15 18:46:43 +080016868 res = snprintf(nr, sizeof(nr),
developera3511852023-06-14 14:12:59 +080016869 "%s" // bssid
16870 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
16871 "%02hhx" // operclass
16872 "%02hhx" // channel
16873 "%02hhx", // phy_mode
16874 hex_bssid,
16875 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
16876 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
16877 neighborReports[i].opClass,
16878 neighborReports[i].channel,
16879 neighborReports[i].phyTable);
developere40952c2023-06-15 18:46:43 +080016880 if (os_snprintf_error(sizeof(nr), res)) {
16881 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16882 return RETURN_ERR;
16883 }
developer72fb0bb2023-01-11 09:46:29 +080016884
developere40952c2023-06-15 18:46:43 +080016885 res = snprintf(cmd, sizeof(cmd),
developera3511852023-06-14 14:12:59 +080016886 "hostapd_cli set_neighbor "
16887 "%s " // bssid
16888 "ssid=%s " // ssid
16889 "nr=%s " // nr
16890 "-i %s",
16891 bssid,hex_ssid,nr, interface_name);
developere40952c2023-06-15 18:46:43 +080016892 if (os_snprintf_error(sizeof(cmd), res)) {
16893 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16894 return RETURN_ERR;
16895 }
developer72fb0bb2023-01-11 09:46:29 +080016896
developera3511852023-06-14 14:12:59 +080016897 if (WEXITSTATUS(system(cmd)) != 0)
16898 {
16899 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
16900 }
16901 }
developer72fb0bb2023-01-11 09:46:29 +080016902
developera3511852023-06-14 14:12:59 +080016903 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016904}
16905
16906INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
16907{
developera3511852023-06-14 14:12:59 +080016908 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016909}
16910
16911#ifdef _WIFI_HAL_TEST_
16912int main(int argc,char **argv)
16913{
developera3511852023-06-14 14:12:59 +080016914 int index;
16915 INT ret=0;
16916 char buf[1024]="";
developer72fb0bb2023-01-11 09:46:29 +080016917
developera3511852023-06-14 14:12:59 +080016918 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16919 if(argc<3)
16920 {
16921 if(argc==2)
16922 {
16923 if(!strcmp(argv[1], "init"))
16924 return wifi_init();
16925 if(!strcmp(argv[1], "reset"))
16926 return wifi_reset();
16927 if(!strcmp(argv[1], "wifi_getHalVersion"))
16928 {
16929 char buffer[64];
16930 if(wifi_getHalVersion(buffer)==RETURN_OK)
16931 printf("Version: %s\n", buffer);
16932 else
16933 printf("Error in wifi_getHalVersion\n");
16934 return RETURN_OK;
16935 }
16936 }
16937 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
16938 exit(-1);
16939 }
developer72fb0bb2023-01-11 09:46:29 +080016940
developera3511852023-06-14 14:12:59 +080016941 index = atoi(argv[2]);
16942 if(strstr(argv[1], "wifi_getApName")!=NULL)
16943 {
16944 wifi_getApName(index,buf);
16945 printf("Ap name is %s \n",buf);
16946 return 0;
16947 }
developerfead3972023-05-25 20:15:02 +080016948 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080016949 {
developerfead3972023-05-25 20:15:02 +080016950 UINT pureMode = atoi(argv[3]);
16951
developera3511852023-06-14 14:12:59 +080016952 wifi_setRadioMode(index, NULL, pureMode);
16953 printf("Ap SET Radio mode 0x%x\n", pureMode);
16954 return 0;
16955 }
16956 if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
16957 unsigned char enable = atoi(argv[3]);
16958 if (enable)
16959 wifi_setRadioAutoBlockAckEnable(index, TRUE);
16960 else
16961 wifi_setRadioAutoBlockAckEnable(index, FALSE);
16962 printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
16963 }
developera39cfb22023-06-20 16:28:17 +080016964 if(strstr(argv[1], "wifi_setRadioTrafficStatsRadioStatisticsEnable")!=NULL)
16965 {
16966 wifi_setRadioTrafficStatsRadioStatisticsEnable(index, TRUE);
16967 printf("Ap SET wifi_setRadioTrafficStatsRadioStatisticsEnable\n");
16968 return 0;
16969 }
16970 if(strstr(argv[1], "wifi_setRadioTrafficStatsMeasure")!=NULL)
16971 {
16972 wifi_radioTrafficStatsMeasure_t input = {30, 200};
16973
16974 wifi_setRadioTrafficStatsMeasure(index, &input);
16975 printf("Ap SET wifi_setRadioTrafficStatsMeasure\n");
16976 return 0;
16977 }
developerfead3972023-05-25 20:15:02 +080016978 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
developera3511852023-06-14 14:12:59 +080016979 {
developerfead3972023-05-25 20:15:02 +080016980 ULONG TransmitPower = atoi(argv[3]);
16981
developera3511852023-06-14 14:12:59 +080016982 wifi_setRadioTransmitPower(index, TransmitPower);
16983 printf("Ap SET TransmitPower %lu\n", TransmitPower);
16984 return 0;
16985 }
developerfead3972023-05-25 20:15:02 +080016986 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
developera3511852023-06-14 14:12:59 +080016987 {
developerfead3972023-05-25 20:15:02 +080016988 INT TransmitPower = atoi(argv[3]);
16989
developera3511852023-06-14 14:12:59 +080016990 wifi_setApManagementFramePowerControl(index, TransmitPower);
16991 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
16992 return 0;
16993 }
developerfead3972023-05-25 20:15:02 +080016994 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
developera3511852023-06-14 14:12:59 +080016995 {
developerfead3972023-05-25 20:15:02 +080016996 CHAR *bandwith = argv[3];
16997
developera3511852023-06-14 14:12:59 +080016998 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
16999 printf("Ap SET bw %s\n", bandwith);
17000 return 0;
17001 }
developerfead3972023-05-25 20:15:02 +080017002 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
developera3511852023-06-14 14:12:59 +080017003 {
17004 wifi_factoryResetRadio(index);
17005 printf("wifi_factoryResetRadio ok!\n");
17006 return 0;
17007 }
developerfead3972023-05-25 20:15:02 +080017008 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
developera3511852023-06-14 14:12:59 +080017009 {
17010 ULONG rst_cnt;
17011 wifi_getRadioResetCount(index, &rst_cnt);
17012 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
17013 return 0;
17014 }
developer2edaf012023-05-24 14:24:53 +080017015 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080017016 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080017017 {
17018 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17019 exit(-1);
17020 }
developer49b17232023-05-19 16:35:19 +080017021 wifi_addApAclDevice(index, argv[3]);
17022 return 0;
17023 }
developer2edaf012023-05-24 14:24:53 +080017024 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
17025 wifi_getApAclDevices(index, buf, 1024);
17026 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080017027 return 0;
17028 }
developer2edaf012023-05-24 14:24:53 +080017029 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
17030 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080017031 {
17032 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17033 exit(-1);
17034 }
developer2edaf012023-05-24 14:24:53 +080017035 wifi_delApAclDevice(index, argv[3]);
17036 return 0;
17037 }
17038 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
17039 wifi_delApAclDevices(index);
17040 return 0;
17041 }
17042 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
developer863a4a62023-06-06 16:55:59 +080017043 UINT acl_num = 0;
developer2edaf012023-05-24 14:24:53 +080017044 wifi_getApAclDeviceNum(index, &acl_num);
17045 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
17046 return 0;
17047 }
17048 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
17049 wifi_getApDenyAclDevices(index, buf, 1024);
17050 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
17051 return 0;
17052 }
17053 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
17054 int filter_mode = 0;
17055 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080017056 {
17057 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17058 exit(-1);
17059 }
developer2edaf012023-05-24 14:24:53 +080017060 filter_mode = atoi(argv[3]);
17061 wifi_setApMacAddressControlMode(index,filter_mode);
17062 return 0;
17063 }
developer5cd4c862023-05-26 09:34:42 +080017064 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
17065 BOOL output_bool = 0;
17066 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
17067 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
17068 return 0;
17069 }
17070 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
17071 BOOL output_bool = 0;
17072 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
17073 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
17074 return 0;
17075 }
17076
17077 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
17078 int filter_mode = 0;
17079 wifi_getApMacAddressControlMode(index, &filter_mode);
17080 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
17081 return 0;
17082 }
17083 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
17084 int enable = 0;
17085 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080017086 {
17087 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17088 exit(-1);
17089 }
developer5cd4c862023-05-26 09:34:42 +080017090 enable = (BOOL)atoi(argv[3]);
17091 wifi_setRadioIGMPSnoopingEnable(index, enable);
17092 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
17093 return 0;
17094 }
developer326d4232023-06-15 16:45:30 +080017095 if (strncmp(argv[1], "wifi_setRadioDCSEnable(", strlen(argv[1])) == 0) {
17096 int enable = 0;
17097 if(argc <= 3 )
17098 {
17099 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17100 exit(-1);
17101 }
17102 enable = (BOOL)atoi(argv[3]);
17103 wifi_setRadioDCSEnable(index, enable);
17104 wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
17105 return 0;
17106 }
17107 if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod(", strlen(argv[1])) == 0) {
17108 ULONG period = 0;
developer5cd4c862023-05-26 09:34:42 +080017109
developer326d4232023-06-15 16:45:30 +080017110 wifi_getRadioAutoChannelRefreshPeriod(index, &period);
17111 wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
17112 return 0;
17113 }
17114 if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod(", strlen(argv[1])) == 0) {
17115 ULONG period = 0;
17116
17117 period = (ULONG)atoi(argv[3]);
17118 wifi_setRadioDfsRefreshPeriod(index, period);
17119 wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
17120 return 0;
17121 }
17122 if (strncmp(argv[1], "wifi_setRadioDCSChannelPool(", strlen(argv[1])) == 0) {
17123 char pool[256] = {'\0'};
17124
developerc14d83a2023-06-29 20:09:42 +080017125 strncpy(pool, argv[3], strlen(argv[3]));
developer326d4232023-06-15 16:45:30 +080017126 wifi_setRadioDCSChannelPool(index, pool);
17127 wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
17128 return 0;
17129 }
17130 if (strncmp(argv[1], "wifi_getRadioDCSChannelPool(", strlen(argv[1])) == 0) {
17131 char pool[256] = {'\0'};
17132
17133 wifi_getRadioDCSChannelPool(index, pool);
17134 wifi_debug(DEBUG_NOTICE, "Get DCSChannelPool: %s\n", pool);
17135 return 0;
17136 }
developer5cd4c862023-05-26 09:34:42 +080017137 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
17138 BOOL out_status = 0;
17139 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
17140 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
17141 return 0;
17142 }
developer121a8e72023-05-22 09:19:39 +080017143
developer95c045d2023-05-24 19:26:28 +080017144 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
17145 int enable = 0;
17146 if(argc <= 3)
17147 {
17148 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17149 exit(-1);
17150 }
17151 enable = atoi(argv[3]);
17152 wifi_setApWmmEnable(index,enable);
17153 return 0;
17154 }
developerc1aa6532023-06-09 09:37:01 +080017155 if (strncmp(argv[1], "wifi_pushSsidAdvertisementEnable", strlen(argv[1])) == 0) {
17156 int enable = 0;
17157 if(argc <= 3)
17158 {
17159 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17160 exit(-1);
17161 }
17162 enable = atoi(argv[3]);
17163 wifi_pushSsidAdvertisementEnable(index,enable);
17164 return 0;
17165 }
developer56fbedb2023-05-30 16:47:05 +080017166 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
17167 wifi_down();
17168 return 0;
17169 }
developer95c045d2023-05-24 19:26:28 +080017170
developer56fbedb2023-05-30 16:47:05 +080017171 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
17172 BOOL enable = 0;
17173
17174 wifi_getRadioStatus(index, &enable);
17175 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
17176 return 0;
17177 }
developer333c1eb2023-05-31 14:59:39 +080017178
developer95c045d2023-05-24 19:26:28 +080017179 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
17180 BOOL enable = 0;
17181
17182 wifi_getApWMMCapability(index, &enable);
17183 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
17184 return 0;
17185 }
17186
17187 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
17188 BOOL enable = 0;
17189
17190 wifi_getApWmmEnable(index, &enable);
17191 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
17192 return 0;
17193 }
17194
developer2edaf012023-05-24 14:24:53 +080017195 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
17196 int filter_mode = 0;
17197 wifi_getApMacAddressControlMode(index, &filter_mode);
17198 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
17199 return 0;
17200 }
developer0f10c772023-05-16 21:43:39 +080017201 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080017202 {
developer863a4a62023-06-06 16:55:59 +080017203 UINT mode = 0;
developer0f10c772023-05-16 21:43:39 +080017204
developera3511852023-06-14 14:12:59 +080017205 wifi_getRadioMode(index, buf, &mode);
17206 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
17207 return 0;
17208 }
17209 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
17210 {
17211 BOOL b = FALSE;
17212 BOOL *output_bool = &b;
17213 wifi_getRadioAutoChannelEnable(index,output_bool);
17214 printf("Channel enabled = %d \n",b);
17215 return 0;
17216 }
17217 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
17218 {
17219 wifi_getApWpaEncryptionMode(index,buf);
17220 printf("encryption enabled = %s\n",buf);
17221 return 0;
17222 }
17223 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
17224 {
17225 BOOL b = FALSE;
17226 BOOL *output_bool = &b;
17227 wifi_getApSsidAdvertisementEnable(index,output_bool);
17228 printf("advertisment enabled = %d\n",b);
17229 return 0;
17230 }
17231 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
17232 {
17233 if(argc <= 3 )
17234 {
17235 printf("Insufficient arguments \n");
17236 exit(-1);
17237 }
developer72fb0bb2023-01-11 09:46:29 +080017238
developera3511852023-06-14 14:12:59 +080017239 char sta[20] = {'\0'};
17240 ULLONG handle= 0;
developerc14d83a2023-06-29 20:09:42 +080017241 strncpy(sta,argv[3], strlen(argv[3]));
developera3511852023-06-14 14:12:59 +080017242 mac_address_t st;
developer72fb0bb2023-01-11 09:46:29 +080017243 mac_addr_aton(st,sta);
17244
developera3511852023-06-14 14:12:59 +080017245 wifi_associated_dev_tid_stats_t tid_stats;
17246 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
17247 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
17248 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);
17249 }
developer72fb0bb2023-01-11 09:46:29 +080017250
developera3511852023-06-14 14:12:59 +080017251 if(strstr(argv[1], "getApEnable")!=NULL) {
17252 BOOL enable;
17253 ret=wifi_getApEnable(index, &enable);
17254 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
17255 }
17256 else if(strstr(argv[1], "setApEnable")!=NULL) {
17257 BOOL enable = atoi(argv[3]);
17258 ret=wifi_setApEnable(index, enable);
17259 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
17260 }
17261 else if(strstr(argv[1], "getApStatus")!=NULL) {
17262 char status[64];
17263 ret=wifi_getApStatus(index, status);
17264 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
17265 }
17266 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
17267 {
17268 wifi_getSSIDNameStatus(index,buf);
17269 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
17270 return 0;
17271 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
17272 wifi_resetApVlanCfg(index);
17273 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
17274 return 0;
17275 }
17276 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
17277 wifi_ssidTrafficStats2_t stats={0};
17278 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
17279 printf("%s %d: returns %d\n", argv[1], index, ret);
17280 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
17281 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
17282 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
17283 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
17284 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
17285 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
17286 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
17287 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
17288 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
17289 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
17290 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
17291 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
17292 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
17293 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
17294 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
17295 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
17296 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
17297 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
17298 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
17299 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
17300 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
17301 }
17302 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
17303 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
17304 UINT array_size=0;
17305 UINT i=0;
17306 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
17307 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
17308 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
17309 printf(" neighbor %d:\n", i);
17310 printf(" ap_SSID =%s\n", pt->ap_SSID);
17311 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
17312 printf(" ap_Mode =%s\n", pt->ap_Mode);
17313 printf(" ap_Channel =%d\n", pt->ap_Channel);
17314 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
17315 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
17316 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
17317 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
17318 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
17319 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
17320 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
17321 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
17322 printf(" ap_Noise =%d\n", pt->ap_Noise);
17323 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
17324 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
17325 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
17326 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
17327 }
17328 if(neighbor_ap_array)
17329 free(neighbor_ap_array); //make sure to free the list
17330 }
17331 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
17332 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
17333 UINT array_size=0;
17334 UINT i=0;
17335 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
17336 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
17337 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
17338 printf(" associated_dev %d:\n", i);
17339 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
17340 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
17341 printf(" cli_SNR =%d\n", pt->cli_SNR);
17342 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
17343 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
17344 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
17345 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
17346 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
17347 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
17348 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
17349 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
17350 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
17351 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
17352 }
17353 if(associated_dev_array)
17354 free(associated_dev_array); //make sure to free the list
17355 }
developer72fb0bb2023-01-11 09:46:29 +080017356
developera3511852023-06-14 14:12:59 +080017357 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
17358 {
developer72fb0bb2023-01-11 09:46:29 +080017359#define MAX_ARRAY_SIZE 64
developera3511852023-06-14 14:12:59 +080017360 int i, array_size;
17361 char *p, *ch_str;
17362 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
developer72fb0bb2023-01-11 09:46:29 +080017363
developera3511852023-06-14 14:12:59 +080017364 if(argc != 5)
17365 {
17366 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
17367 exit(-1);
17368 }
17369 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
developer72fb0bb2023-01-11 09:46:29 +080017370
developera3511852023-06-14 14:12:59 +080017371 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
17372 {
17373 strtok_r(ch_str, ",", &p);
17374 input_output_channelStats_array[i].ch_number = atoi(ch_str);
17375 }
17376 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
17377 if(!array_size)
17378 array_size=1;//Need to print current channel statistics
17379 for(i=0; i<array_size; i++)
17380 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
17381 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
17382 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
17383 input_output_channelStats_array[i].ch_number,\
17384 input_output_channelStats_array[i].ch_noise,\
17385 input_output_channelStats_array[i].ch_utilization_busy_rx,\
17386 input_output_channelStats_array[i].ch_utilization_busy_tx,\
17387 input_output_channelStats_array[i].ch_utilization_busy,\
17388 input_output_channelStats_array[i].ch_utilization_busy_ext,\
17389 input_output_channelStats_array[i].ch_utilization_total);
17390 }
developer72fb0bb2023-01-11 09:46:29 +080017391
developera3511852023-06-14 14:12:59 +080017392 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
17393 {
17394 if(argc <= 3 )
17395 {
17396 printf("Insufficient arguments \n");
17397 exit(-1);
17398 }
17399 char mac_addr[20] = {'\0'};
17400 wifi_device_t output_struct;
17401 int dev_index = atoi(argv[3]);
developer72fb0bb2023-01-11 09:46:29 +080017402
developera3511852023-06-14 14:12:59 +080017403 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
17404 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
17405 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);
17406 }
developer72fb0bb2023-01-11 09:46:29 +080017407
developera3511852023-06-14 14:12:59 +080017408 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
17409 {
17410 if (argc <= 3)
17411 {
17412 printf("Insufficient arguments\n");
17413 exit(-1);
17414 }
17415 char args[256];
17416 wifi_NeighborReport_t *neighborReports;
developer72fb0bb2023-01-11 09:46:29 +080017417
developera3511852023-06-14 14:12:59 +080017418 neighborReports = calloc(argc - 2, sizeof(neighborReports));
17419 if (!neighborReports)
17420 {
17421 printf("Failed to allocate memory");
17422 exit(-1);
17423 }
developer72fb0bb2023-01-11 09:46:29 +080017424
developera3511852023-06-14 14:12:59 +080017425 for (int i = 3; i < argc; ++i)
17426 {
17427 char *val;
17428 int j = 0;
developerc14d83a2023-06-29 20:09:42 +080017429 unsigned long tmp;
developera3511852023-06-14 14:12:59 +080017430 memset(args, 0, sizeof(args));
17431 strncpy(args, argv[i], sizeof(args));
17432 val = strtok(args, ";");
17433 while (val != NULL)
17434 {
17435 if (j == 0)
17436 {
17437 mac_addr_aton(neighborReports[i - 3].bssid, val);
17438 } else if (j == 1)
17439 {
developerc14d83a2023-06-29 20:09:42 +080017440 if (hal_strtoul(val, 16, &tmp) < 0) {
17441 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
17442 return RETURN_ERR;
17443 }
17444 neighborReports[i - 3].info = tmp;
developera3511852023-06-14 14:12:59 +080017445 } else if (j == 2)
17446 {
developerc14d83a2023-06-29 20:09:42 +080017447 if (hal_strtoul(val, 16, &tmp) < 0) {
17448 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
17449 return RETURN_ERR;
17450 }
17451 neighborReports[i - 3].opClass = tmp;
17452
developera3511852023-06-14 14:12:59 +080017453 } else if (j == 3)
17454 {
developerc14d83a2023-06-29 20:09:42 +080017455 if (hal_strtoul(val, 16, &tmp) < 0) {
17456 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
17457 return RETURN_ERR;
17458 }
17459 neighborReports[i - 3].channel = tmp;
developera3511852023-06-14 14:12:59 +080017460 } else if (j == 4)
17461 {
developerc14d83a2023-06-29 20:09:42 +080017462 if (hal_strtoul(val, 16, &tmp) < 0) {
17463 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
17464 return RETURN_ERR;
17465 }
17466 neighborReports[i - 3].phyTable = tmp;
developera3511852023-06-14 14:12:59 +080017467 } else {
17468 printf("Insufficient arguments]n\n");
17469 exit(-1);
17470 }
17471 val = strtok(NULL, ";");
17472 j++;
17473 }
17474 }
developer72fb0bb2023-01-11 09:46:29 +080017475
developera3511852023-06-14 14:12:59 +080017476 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
17477 if (ret != RETURN_OK)
17478 {
17479 printf("wifi_setNeighborReports ret = %d", ret);
17480 exit(-1);
17481 }
17482 }
17483 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
17484 {
17485 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
17486 printf("%s.\n", buf);
17487 else
17488 printf("Error returned\n");
17489 }
17490 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
17491 {
17492 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
17493 printf("%s.\n", buf);
17494 else
17495 printf("Error returned\n");
17496 }
17497 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
17498 {
17499 if (argc <= 2)
17500 {
17501 printf("Insufficient arguments\n");
17502 exit(-1);
17503 }
17504 char buf[64]= {'\0'};
17505 wifi_getRadioOperatingChannelBandwidth(index,buf);
17506 printf("Current bandwidth is %s \n",buf);
17507 return 0;
17508 }
17509 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
17510 {
17511 if (argc <= 5)
17512 {
17513 printf("Insufficient arguments\n");
17514 exit(-1);
17515 }
17516 UINT channel = atoi(argv[3]);
17517 UINT width = atoi(argv[4]);
17518 UINT beacon = atoi(argv[5]);
17519 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
17520 printf("Result = %d", ret);
17521 }
developercc5cbfb2023-06-13 18:29:52 +080017522 if(strstr(argv[1],"wifi_getApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080017523 {
developercc5cbfb2023-06-13 18:29:52 +080017524 char br_name[64], ip[64], subset[64] = {0};
17525 wifi_getApBridgeInfo(0, br_name, ip, subset);
17526 printf("wifi_getApBridgeInfo br_name = %s, ip = %s, subset = %s\n", br_name, ip, subset);
developera3511852023-06-14 14:12:59 +080017527 }
developercc5cbfb2023-06-13 18:29:52 +080017528 if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
developera3511852023-06-14 14:12:59 +080017529 {
developercc5cbfb2023-06-13 18:29:52 +080017530 int enable = atoi(argv[3]);
17531 wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
17532 printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
developera3511852023-06-14 14:12:59 +080017533 }
developercc5cbfb2023-06-13 18:29:52 +080017534 if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080017535 {
developercc5cbfb2023-06-13 18:29:52 +080017536 wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
17537 printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
developera3511852023-06-14 14:12:59 +080017538 }
developer72fb0bb2023-01-11 09:46:29 +080017539
developer6e578302023-06-21 10:11:16 +080017540 if(strstr(argv[1], "wifi_getATMCapable")!=NULL)
17541 {
17542 BOOL b = FALSE;
17543 BOOL *output_bool = &b;
17544 wifi_getATMCapable(output_bool);
17545 printf("ATM capable = %d \n",b);
17546 return 0;
17547 }
17548 if (strncmp(argv[1], "wifi_setATMEnable", strlen(argv[1])) == 0) {
17549 int enable = 0;
17550 if(argc <= 3)
17551 {
17552 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17553 exit(-1);
17554 }
17555 enable = atoi(argv[3]);
17556 wifi_setATMEnable(enable);
17557 return 0;
17558 }
17559 if (strncmp(argv[1], "wifi_getATMEnable", strlen(argv[1])) == 0) {
17560 BOOL b = FALSE;
17561 BOOL *output_bool = &b;
17562 wifi_getATMEnable(output_bool);
17563 printf("ATM enable = %d \n", b);
17564 return 0;
17565 }
17566 if (strncmp(argv[1], "wifi_setApATMAirTimePercent", strlen(argv[1])) == 0) {
17567 unsigned int percent = 0;
17568 if(argc <= 3)
17569 {
17570 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17571 exit(-1);
17572 }
17573 percent = atoi(argv[3]);
17574 wifi_setApATMAirTimePercent(index, percent);
17575 return 0;
17576 }
17577 if (strncmp(argv[1], "wifi_getApATMAirTimePercent", strlen(argv[1])) == 0) {
17578 unsigned int percent = 0;
17579 unsigned int *output = &percent;
17580
17581 wifi_getApATMAirTimePercent(index, output);
17582 printf("ATM percent = %d \n", percent);
17583 return 0;
17584 }
developer82533be2023-06-28 17:21:01 +080017585 if (strstr(argv[1],"setGF")!=NULL)
17586 {
17587 BOOL enable = atoi(argv[3]);
17588 if((ret=wifi_setRadio11nGreenfieldEnable(index, enable))==RETURN_OK)
17589 printf("wifi_setRadio11nGreenfieldEnable success\n");
17590 else
17591 printf("wifi_setRadio11nGreenfieldEnable Error\n");
17592 }
17593 if (strstr(argv[1],"setVID")!=NULL)
17594 {
17595 INT vid = atoi(argv[3]);
17596 if((ret=wifi_setApVlanID(index, vid))==RETURN_OK)
17597 printf("wifi_setApVlanID success.\n");
17598 else
17599 printf("wifi_setApVlanID Error\n");
developerd14dff12023-06-28 22:47:44 +080017600 }
17601 if (strncmp(argv[1], "wifi_getApATMSta", strlen(argv[1])) == 0) {
17602 UCHAR outbuf[256]={0};
17603
17604 wifi_getApATMSta(index, outbuf, sizeof(outbuf));
17605 printf("sta air time percent is %s \n", outbuf);
17606 return 0;
17607 }
developera3511852023-06-14 14:12:59 +080017608 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17609 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017610}
17611
17612#endif
17613
17614#ifdef WIFI_HAL_VERSION_3
17615
developer32f2a182023-06-27 19:50:41 +080017616INT BitMapToTransmitRates(UINT bitMap, char *BasicRate, unsigned long size)
developer72fb0bb2023-01-11 09:46:29 +080017617{
developera3511852023-06-14 14:12:59 +080017618 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer32f2a182023-06-27 19:50:41 +080017619 if (bitMap & WIFI_BITRATE_1MBPS) {
17620 if ((size - strlen(BasicRate)) <= 2)
17621 return RETURN_ERR;
17622 strncat(BasicRate, "1,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17623 }
17624 if (bitMap & WIFI_BITRATE_2MBPS) {
17625 if ((size - strlen(BasicRate)) <= 2)
17626 return RETURN_ERR;
17627 strncat(BasicRate, "2,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17628 }
17629 if (bitMap & WIFI_BITRATE_5_5MBPS) {
17630 if ((size - strlen(BasicRate)) <= 4)
17631 return RETURN_ERR;
17632 strncat(BasicRate, "5.5,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17633 }
17634 if (bitMap & WIFI_BITRATE_6MBPS) {
17635 if ((size - strlen(BasicRate)) <= 2)
17636 return RETURN_ERR;
17637 strncat(BasicRate, "6,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17638 }
17639 if (bitMap & WIFI_BITRATE_9MBPS) {
17640 if ((size - strlen(BasicRate)) <= 2)
17641 return RETURN_ERR;
17642 strncat(BasicRate, "9,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17643 }
17644 if (bitMap & WIFI_BITRATE_11MBPS) {
17645 if ((size - strlen(BasicRate)) <= 3)
17646 return RETURN_ERR;
17647 strncat(BasicRate, "11,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17648 }
17649 if (bitMap & WIFI_BITRATE_12MBPS) {
17650 if ((size - strlen(BasicRate)) <= 3)
17651 return RETURN_ERR;
17652 strncat(BasicRate, "12,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17653 }
17654 if (bitMap & WIFI_BITRATE_18MBPS) {
17655 if ((size - strlen(BasicRate)) <= 3)
17656 return RETURN_ERR;
17657 strncat(BasicRate, "18,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17658 }
17659 if (bitMap & WIFI_BITRATE_24MBPS) {
17660 if ((size - strlen(BasicRate)) <= 3)
17661 return RETURN_ERR;
17662 strncat(BasicRate, "24,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17663 }
17664 if (bitMap & WIFI_BITRATE_36MBPS) {
17665 if ((size - strlen(BasicRate)) <= 3)
17666 return RETURN_ERR;
17667 strncat(BasicRate, "36,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17668 }
17669 if (bitMap & WIFI_BITRATE_48MBPS) {
17670 if ((size - strlen(BasicRate)) <= 3)
17671 return RETURN_ERR;
17672 strncat(BasicRate, "48,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17673 }
17674 if (bitMap & WIFI_BITRATE_54MBPS) {
17675 if ((size - strlen(BasicRate)) <= 3)
17676 return RETURN_ERR;
17677 strncat(BasicRate, "54,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17678 }
developera3511852023-06-14 14:12:59 +080017679 if (strlen(BasicRate) != 0) // remove last comma
17680 BasicRate[strlen(BasicRate) - 1] = '\0';
17681 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17682 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017683}
17684
17685INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
17686{
developera3511852023-06-14 14:12:59 +080017687 UINT BitMap = 0;
17688 char *rate;
developer72fb0bb2023-01-11 09:46:29 +080017689
developera3511852023-06-14 14:12:59 +080017690 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17691 rate = strtok(BasicRatesList, ",");
17692 while(rate != NULL)
17693 {
17694 if (strcmp(rate, "1") == 0)
17695 BitMap |= WIFI_BITRATE_1MBPS;
17696 else if (strcmp(rate, "2") == 0)
17697 BitMap |= WIFI_BITRATE_2MBPS;
17698 else if (strcmp(rate, "5.5") == 0)
17699 BitMap |= WIFI_BITRATE_5_5MBPS;
17700 else if (strcmp(rate, "6") == 0)
17701 BitMap |= WIFI_BITRATE_6MBPS;
17702 else if (strcmp(rate, "9") == 0)
17703 BitMap |= WIFI_BITRATE_9MBPS;
17704 else if (strcmp(rate, "11") == 0)
17705 BitMap |= WIFI_BITRATE_11MBPS;
17706 else if (strcmp(rate, "12") == 0)
17707 BitMap |= WIFI_BITRATE_12MBPS;
17708 else if (strcmp(rate, "18") == 0)
17709 BitMap |= WIFI_BITRATE_18MBPS;
17710 else if (strcmp(rate, "24") == 0)
17711 BitMap |= WIFI_BITRATE_24MBPS;
17712 else if (strcmp(rate, "36") == 0)
17713 BitMap |= WIFI_BITRATE_36MBPS;
17714 else if (strcmp(rate, "48") == 0)
17715 BitMap |= WIFI_BITRATE_48MBPS;
17716 else if (strcmp(rate, "54") == 0)
17717 BitMap |= WIFI_BITRATE_54MBPS;
17718 rate = strtok(NULL, ",");
17719 }
17720 *basicRateBitMap = BitMap;
17721 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17722 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017723}
17724
17725// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
17726INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
17727{
developera3511852023-06-14 14:12:59 +080017728 char buf[128] = {0};
17729 int bandwidth = 20;
17730 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080017731 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developera3511852023-06-14 14:12:59 +080017732 wifi_radio_operationParam_t current_param;
developer72fb0bb2023-01-11 09:46:29 +080017733
developera3511852023-06-14 14:12:59 +080017734 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017735
developera3511852023-06-14 14:12:59 +080017736 multiple_set = TRUE;
17737 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017738 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingParameters return error.\n");
developera3511852023-06-14 14:12:59 +080017739 return RETURN_ERR;
17740 }
17741 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
17742 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017743 wifi_debug(DEBUG_ERROR, "wifi_setRadioAutoChannelEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017744 return RETURN_ERR;
17745 }
17746 drv_dat_change = TRUE;
17747 }
17748 if (current_param.channelWidth != operationParam->channelWidth ||
17749 current_param.channel != operationParam->channel ||
17750 current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
17751 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
17752 bandwidth = 20;
17753 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
17754 bandwidth = 40;
17755 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
17756 bandwidth = 80;
17757 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
17758 bandwidth = 160;
developer72fb0bb2023-01-11 09:46:29 +080017759
developera3511852023-06-14 14:12:59 +080017760 if (operationParam->autoChannelEnabled) {
17761 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017762 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developera3511852023-06-14 14:12:59 +080017763 return RETURN_ERR;
17764 }
17765 } else {
17766 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017767 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developera3511852023-06-14 14:12:59 +080017768 return RETURN_ERR;
17769 }
17770 }
developer56fbedb2023-05-30 16:47:05 +080017771 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017772 }
17773 if (current_param.variant != operationParam->variant) {
17774 // Two different definition bit map, so need to check every bit.
17775 if (operationParam->variant & WIFI_80211_VARIANT_A)
17776 set_mode |= WIFI_MODE_A;
17777 if (operationParam->variant & WIFI_80211_VARIANT_B)
17778 set_mode |= WIFI_MODE_B;
17779 if (operationParam->variant & WIFI_80211_VARIANT_G)
17780 set_mode |= WIFI_MODE_G;
17781 if (operationParam->variant & WIFI_80211_VARIANT_N)
17782 set_mode |= WIFI_MODE_N;
17783 if (operationParam->variant & WIFI_80211_VARIANT_AC)
17784 set_mode |= WIFI_MODE_AC;
17785 if (operationParam->variant & WIFI_80211_VARIANT_AX)
17786 set_mode |= WIFI_MODE_AX;
17787 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
17788 memset(buf, 0, sizeof(buf));
17789 drv_dat_change = TRUE;
17790 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017791 wifi_debug(DEBUG_ERROR, "wifi_setRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080017792 return RETURN_ERR;
17793 }
17794 }
17795 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer56fbedb2023-05-30 16:47:05 +080017796 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017797 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017798 wifi_debug(DEBUG_ERROR, "wifi_setApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017799 return RETURN_ERR;
17800 }
17801 }
17802 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer56fbedb2023-05-30 16:47:05 +080017803 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017804 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017805 wifi_debug(DEBUG_ERROR, "wifi_setRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080017806 return RETURN_ERR;
17807 }
17808 }
17809 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer56fbedb2023-05-30 16:47:05 +080017810 hapd_conf_change = TRUE;
developer32f2a182023-06-27 19:50:41 +080017811 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080017812 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017813 wifi_debug(DEBUG_ERROR, "wifi_setRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017814 return RETURN_ERR;
17815 }
17816 }
17817 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer56fbedb2023-05-30 16:47:05 +080017818 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017819 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017820 wifi_debug(DEBUG_ERROR, "wifi_setRadioFragmentationThreshold return error.\n");
developera3511852023-06-14 14:12:59 +080017821 return RETURN_ERR;
17822 }
17823 }
17824 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080017825 hapd_conf_change = TRUE;
17826 drv_dat_change = TRUE;
17827 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017828 wifi_debug(DEBUG_ERROR, "wifi_setGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017829 return RETURN_ERR;
17830 }
17831 }
17832 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080017833 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017834 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017835 wifi_debug(DEBUG_ERROR, "wifi_setRadioTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080017836 return RETURN_ERR;
17837 }
17838 }
17839 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
developer56fbedb2023-05-30 16:47:05 +080017840 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017841 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017842 wifi_debug(DEBUG_ERROR, "wifi_setApRtsThreshold return error.\n");
developera3511852023-06-14 14:12:59 +080017843 return RETURN_ERR;
17844 }
17845 }
17846 if (current_param.obssCoex != operationParam->obssCoex) {
developer56fbedb2023-05-30 16:47:05 +080017847 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017848 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017849 wifi_debug(DEBUG_ERROR, "wifi_setRadioObssCoexistenceEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017850 return RETURN_ERR;
17851 }
17852 }
17853 if (current_param.stbcEnable != operationParam->stbcEnable) {
developer56fbedb2023-05-30 16:47:05 +080017854 hapd_conf_change = TRUE;
17855 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017856 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017857 wifi_debug(DEBUG_ERROR, "wifi_setRadioSTBCEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017858 return RETURN_ERR;
17859 }
17860 }
17861 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
17862 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017863 wifi_debug(DEBUG_ERROR, "wifi_setRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017864 return RETURN_ERR;
17865 }
17866 }
developer72fb0bb2023-01-11 09:46:29 +080017867
developera3511852023-06-14 14:12:59 +080017868 /* only down/up interface when dat file has been changed,
17869 * if enable is true, then restart the radio.
17870 */
17871 if (drv_dat_change == TRUE) {
17872 wifi_setRadioEnable(index, FALSE);
developer56fbedb2023-05-30 16:47:05 +080017873 if (operationParam->enable == TRUE)
developera3511852023-06-14 14:12:59 +080017874 wifi_setRadioEnable(index, TRUE);
17875 } else if (hapd_conf_change == TRUE) {
17876 hostapd_raw_remove_bss(index);
17877 if (operationParam->enable == TRUE)
17878 hostapd_raw_add_bss(index);
17879 }
developer56fbedb2023-05-30 16:47:05 +080017880
developera3511852023-06-14 14:12:59 +080017881 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017882
developera3511852023-06-14 14:12:59 +080017883 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017884}
17885
17886INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
17887{
developera3511852023-06-14 14:12:59 +080017888 char band[64] = {0};
17889 char buf[256] = {0};
17890 char config_file[64] = {0};
17891 char cmd[128] = {0};
17892 UINT mode = 0;
17893 BOOL enabled = FALSE;
developer863a4a62023-06-06 16:55:59 +080017894 int dtimPeriod;
developer2f79c922023-06-02 17:33:42 +080017895 UINT beaconInterval;
17896 UINT basicDataTransmitRates;
17897 UINT operationalDataTransmitRates;
17898 wifi_guard_interval_t guardInterval;
17899 UINT transmitPower;
developere40952c2023-06-15 18:46:43 +080017900 int res;
developerc14d83a2023-06-29 20:09:42 +080017901 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080017902
developera3511852023-06-14 14:12:59 +080017903 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17904 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080017905
developera3511852023-06-14 14:12:59 +080017906 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
developere40952c2023-06-15 18:46:43 +080017907 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
17908 if (os_snprintf_error(sizeof(config_file), res)) {
17909 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17910 return RETURN_ERR;
17911 }
developera3511852023-06-14 14:12:59 +080017912 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
17913 {
developer75bd10c2023-06-27 11:34:08 +080017914 wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017915 return RETURN_ERR;
17916 }
17917 operationParam->enable = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017918
developera3511852023-06-14 14:12:59 +080017919 memset(band, 0, sizeof(band));
17920 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
17921 {
developer75bd10c2023-06-27 11:34:08 +080017922 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingFrequencyBand return error.\n");
developera3511852023-06-14 14:12:59 +080017923 return RETURN_ERR;
17924 }
developer72fb0bb2023-01-11 09:46:29 +080017925
developera3511852023-06-14 14:12:59 +080017926 if (!strcmp(band, "2.4GHz"))
17927 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
17928 else if (!strcmp(band, "5GHz"))
17929 operationParam->band = WIFI_FREQUENCY_5_BAND;
17930 else if (!strcmp(band, "6GHz"))
17931 operationParam->band = WIFI_FREQUENCY_6_BAND;
17932 else
17933 {
developer75bd10c2023-06-27 11:34:08 +080017934 wifi_debug(DEBUG_ERROR, "cannot decode band for radio index %d ('%s')\n", index, band);
developera3511852023-06-14 14:12:59 +080017935 }
developer72fb0bb2023-01-11 09:46:29 +080017936
developera3511852023-06-14 14:12:59 +080017937 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
17938 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
17939 operationParam->channel = 0;
17940 operationParam->autoChannelEnabled = TRUE;
17941 } else {
developerc14d83a2023-06-29 20:09:42 +080017942 if (hal_strtoul(buf, 10, &tmp) < 0) {
17943 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
17944 return RETURN_ERR;
17945 }
17946 operationParam->channel = tmp;
17947
developera3511852023-06-14 14:12:59 +080017948 operationParam->autoChannelEnabled = FALSE;
17949 }
developer72fb0bb2023-01-11 09:46:29 +080017950
developera3511852023-06-14 14:12:59 +080017951 memset(buf, 0, sizeof(buf));
17952 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017953 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
developera3511852023-06-14 14:12:59 +080017954 return RETURN_ERR;
17955 }
17956 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
17957 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
17958 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
17959 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
17960 else
17961 {
developer75bd10c2023-06-27 11:34:08 +080017962 wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", buf);
developera3511852023-06-14 14:12:59 +080017963 return false;
17964 }
developer72fb0bb2023-01-11 09:46:29 +080017965
developera3511852023-06-14 14:12:59 +080017966 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017967 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080017968 return RETURN_ERR;
17969 }
17970 // Two different definition bit map, so need to check every bit.
17971 if (mode & WIFI_MODE_A)
17972 operationParam->variant |= WIFI_80211_VARIANT_A;
17973 if (mode & WIFI_MODE_B)
17974 operationParam->variant |= WIFI_80211_VARIANT_B;
17975 if (mode & WIFI_MODE_G)
17976 operationParam->variant |= WIFI_80211_VARIANT_G;
17977 if (mode & WIFI_MODE_N)
17978 operationParam->variant |= WIFI_80211_VARIANT_N;
17979 if (mode & WIFI_MODE_AC)
17980 operationParam->variant |= WIFI_80211_VARIANT_AC;
17981 if (mode & WIFI_MODE_AX)
17982 operationParam->variant |= WIFI_80211_VARIANT_AX;
17983 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017984 wifi_debug(DEBUG_ERROR, "wifi_getRadioDCSEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017985 return RETURN_ERR;
17986 }
17987 if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017988 wifi_debug(DEBUG_ERROR, "wifi_getApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017989 return RETURN_ERR;
17990 }
developer2f79c922023-06-02 17:33:42 +080017991 operationParam->dtimPeriod = dtimPeriod;
developera3511852023-06-14 14:12:59 +080017992 if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017993 wifi_debug(DEBUG_ERROR, "wifi_getRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080017994 return RETURN_ERR;
17995 }
developer2f79c922023-06-02 17:33:42 +080017996 operationParam->beaconInterval = beaconInterval;
developer72fb0bb2023-01-11 09:46:29 +080017997
developera3511852023-06-14 14:12:59 +080017998 memset(buf, 0, sizeof(buf));
17999 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080018000 wifi_debug(DEBUG_ERROR, "wifi_getRadioSupportedDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080018001 return RETURN_ERR;
18002 }
18003 TransmitRatesToBitMap(buf, &basicDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080018004 operationParam->basicDataTransmitRates = basicDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080018005
developera3511852023-06-14 14:12:59 +080018006 memset(buf, 0, sizeof(buf));
18007 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080018008 wifi_debug(DEBUG_ERROR, "wifi_getRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080018009 return RETURN_ERR;
18010 }
18011 TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080018012 operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080018013
developera3511852023-06-14 14:12:59 +080018014 memset(buf, 0, sizeof(buf));
18015 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +080018016 if (hal_strtoul(buf, 10, &tmp) < 0) {
18017 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
18018 }
18019 operationParam->fragmentationThreshold = tmp;
developer72fb0bb2023-01-11 09:46:29 +080018020
developera3511852023-06-14 14:12:59 +080018021 if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080018022 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080018023 return RETURN_ERR;
18024 }
developer2f79c922023-06-02 17:33:42 +080018025 operationParam->guardInterval = guardInterval;
18026
developera3511852023-06-14 14:12:59 +080018027 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080018028 wifi_debug(DEBUG_ERROR, "wifi_getRadioPercentageTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080018029 return RETURN_ERR;
18030 }
developer2f79c922023-06-02 17:33:42 +080018031 operationParam->transmitPower = transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080018032
developera3511852023-06-14 14:12:59 +080018033 memset(buf, 0, sizeof(buf));
18034 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
18035 if (strcmp(buf, "-1") == 0) {
18036 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
18037 operationParam->ctsProtection = FALSE;
18038 } else {
developerc14d83a2023-06-29 20:09:42 +080018039 if (hal_strtoul(buf, 10, &tmp) < 0) {
18040 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
18041 }
18042 operationParam->rtsThreshold = tmp;
developera3511852023-06-14 14:12:59 +080018043 operationParam->ctsProtection = TRUE;
18044 }
developer72fb0bb2023-01-11 09:46:29 +080018045
developera3511852023-06-14 14:12:59 +080018046 memset(buf, 0, sizeof(buf));
18047 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
18048 if (strcmp(buf, "0") == 0)
18049 operationParam->obssCoex = FALSE;
18050 else
18051 operationParam->obssCoex = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018052
developere40952c2023-06-15 18:46:43 +080018053 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
18054 if (os_snprintf_error(sizeof(cmd), res)) {
18055 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18056 return RETURN_ERR;
18057 }
developera3511852023-06-14 14:12:59 +080018058 _syscmd(cmd, buf, sizeof(buf));
18059 if (strlen(buf) != 0)
18060 operationParam->stbcEnable = TRUE;
18061 else
18062 operationParam->stbcEnable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018063
developera3511852023-06-14 14:12:59 +080018064 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080018065 wifi_debug(DEBUG_ERROR, "wifi_getRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080018066 return RETURN_ERR;
18067 }
developer72fb0bb2023-01-11 09:46:29 +080018068
developera3511852023-06-14 14:12:59 +080018069 // Below value is hardcoded
developer72fb0bb2023-01-11 09:46:29 +080018070
developera3511852023-06-14 14:12:59 +080018071 operationParam->numSecondaryChannels = 0;
18072 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
18073 operationParam->channelSecondary[i] = 0;
18074 }
18075 operationParam->csa_beacon_count = 15;
18076 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
developer72fb0bb2023-01-11 09:46:29 +080018077
developera3511852023-06-14 14:12:59 +080018078 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18079 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018080}
18081
18082static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
18083{
developera3511852023-06-14 14:12:59 +080018084 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +080018085
developera3511852023-06-14 14:12:59 +080018086 wifi_getMaxRadioNumber(&max_radio_num);
18087 if (radioIndex >= max_radio_num) {
developer75bd10c2023-06-27 11:34:08 +080018088 wifi_debug(DEBUG_ERROR, "Wrong radio index (%d)\n", radioIndex);
developera3511852023-06-14 14:12:59 +080018089 return RETURN_ERR;
18090 }
developer72fb0bb2023-01-11 09:46:29 +080018091
developera3511852023-06-14 14:12:59 +080018092 return (arrayIndex * max_radio_num) + radioIndex;
developer72fb0bb2023-01-11 09:46:29 +080018093}
18094
developer96b38512023-02-22 11:17:45 +080018095static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
18096{
developera3511852023-06-14 14:12:59 +080018097 int max_radio_num = 0;
developer96b38512023-02-22 11:17:45 +080018098
developera3511852023-06-14 14:12:59 +080018099 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
developer96b38512023-02-22 11:17:45 +080018100 return -1;
18101
developera3511852023-06-14 14:12:59 +080018102 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080018103 if(max_radio_num == 0){
18104 return RETURN_ERR;
18105 }
developera3511852023-06-14 14:12:59 +080018106 (*radioIndex) = vapIndex % max_radio_num;
18107 (*arrayIndex) = vapIndex / max_radio_num;
developer96b38512023-02-22 11:17:45 +080018108
developera3511852023-06-14 14:12:59 +080018109 return 0;
developer96b38512023-02-22 11:17:45 +080018110}
18111
18112
developer72fb0bb2023-01-11 09:46:29 +080018113wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
developera3511852023-06-14 14:12:59 +080018114 if (strncmp(beaconRate, "1Mbps", 5) == 0)
18115 return WIFI_BITRATE_1MBPS;
18116 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
18117 return WIFI_BITRATE_2MBPS;
18118 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
18119 return WIFI_BITRATE_5_5MBPS;
18120 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
18121 return WIFI_BITRATE_6MBPS;
18122 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
18123 return WIFI_BITRATE_9MBPS;
18124 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
18125 return WIFI_BITRATE_11MBPS;
18126 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
18127 return WIFI_BITRATE_12MBPS;
18128 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
18129 return WIFI_BITRATE_18MBPS;
18130 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
18131 return WIFI_BITRATE_24MBPS;
18132 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
18133 return WIFI_BITRATE_36MBPS;
18134 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
18135 return WIFI_BITRATE_48MBPS;
18136 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
18137 return WIFI_BITRATE_54MBPS;
18138 return WIFI_BITRATE_DEFAULT;
developer72fb0bb2023-01-11 09:46:29 +080018139}
18140
developer32f2a182023-06-27 19:50:41 +080018141struct beacon_rate_2_string {
18142 wifi_bitrate_t beacon;
18143 char beacon_str[8];
18144};
18145
18146struct beacon_rate_2_string br2str[12] = {
18147 {WIFI_BITRATE_1MBPS, "1Mbps"},
18148 {WIFI_BITRATE_2MBPS, "2Mbps"},
18149 {WIFI_BITRATE_5_5MBPS, "5.5Mbps"},
18150 {WIFI_BITRATE_6MBPS, "6Mbps"},
18151 {WIFI_BITRATE_9MBPS, "9Mbps"},
18152 {WIFI_BITRATE_11MBPS, "11Mbps"},
18153 {WIFI_BITRATE_12MBPS, "12Mbps"},
18154 {WIFI_BITRATE_18MBPS, "18Mbps"},
18155 {WIFI_BITRATE_24MBPS, "24Mbps"},
18156 {WIFI_BITRATE_36MBPS, "36Mbps"},
18157 {WIFI_BITRATE_48MBPS, "48Mbps"},
18158 {WIFI_BITRATE_54MBPS, "54Mbps"}
18159};
18160
18161INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str, unsigned long str_size)
developer72fb0bb2023-01-11 09:46:29 +080018162{
developer32f2a182023-06-27 19:50:41 +080018163 int i;
18164 unsigned long len;
18165
18166 for (i = 0; i < (sizeof(br2str)/sizeof(br2str[0])); i++) {
18167 if (beacon == br2str[i].beacon) {
18168 len = strlen(br2str[i].beacon_str);
18169 if (len >= str_size)
18170 return RETURN_ERR;
18171 memcpy(beacon_str, br2str[i].beacon_str, len);
18172 beacon_str[len] = '\0';
18173 break;
18174 }
18175 }
developera3511852023-06-14 14:12:59 +080018176 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018177}
18178
18179INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
18180{
developera3511852023-06-14 14:12:59 +080018181 INT mode = 0;
18182 INT ret = -1;
18183 UINT output = 0;
18184 int i = 0;
18185 int vap_index = 0;
18186 BOOL enabled = FALSE;
18187 char buf[32] = {0};
18188 wifi_vap_security_t security = {0};
developere40952c2023-06-15 18:46:43 +080018189 int res;
developer72fb0bb2023-01-11 09:46:29 +080018190
developera3511852023-06-14 14:12:59 +080018191 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
18192 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080018193
developera3511852023-06-14 14:12:59 +080018194 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
18195 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +080018196 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
developera3511852023-06-14 14:12:59 +080018197 return RETURN_ERR;
18198 }
developerfde01262023-05-22 15:15:24 +080018199
developera3511852023-06-14 14:12:59 +080018200 map->num_vaps = atoi(buf);
18201 if (map->num_vaps <= 0) {
developer75bd10c2023-06-27 11:34:08 +080018202 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
developera3511852023-06-14 14:12:59 +080018203 return RETURN_ERR;
18204 }
developerfde01262023-05-22 15:15:24 +080018205
developera3511852023-06-14 14:12:59 +080018206 for (i = 0; i < map->num_vaps; i++)
18207 {
18208 map->vap_array[i].radio_index = index;
developer72fb0bb2023-01-11 09:46:29 +080018209
developera3511852023-06-14 14:12:59 +080018210 vap_index = array_index_to_vap_index(index, i);
18211 if (vap_index < 0)
18212 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018213
developer9ce44382023-06-28 11:09:37 +080018214 strncpy(map->vap_array[i].bridge_name, BRIDGE_NAME,sizeof(map->vap_array[i].bridge_name) - 1);
18215 map->vap_array[i].bridge_name[sizeof(map->vap_array[i].bridge_name) - 1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080018216
developera3511852023-06-14 14:12:59 +080018217 map->vap_array[i].vap_index = vap_index;
developer72fb0bb2023-01-11 09:46:29 +080018218
developera3511852023-06-14 14:12:59 +080018219 memset(buf, 0, sizeof(buf));
18220 ret = wifi_getApName(vap_index, buf);
18221 if (ret != RETURN_OK) {
18222 printf("%s: wifi_getApName return error\n", __func__);
18223 return RETURN_ERR;
18224 }
developere40952c2023-06-15 18:46:43 +080018225 res = snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
18226 if (os_snprintf_error(sizeof(map->vap_array[i].vap_name), res)) {
18227 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18228 return RETURN_ERR;
18229 }
developer72fb0bb2023-01-11 09:46:29 +080018230
developera3511852023-06-14 14:12:59 +080018231 memset(buf, 0, sizeof(buf));
18232 ret = wifi_getSSIDName(vap_index, buf);
18233 if (ret != RETURN_OK) {
18234 printf("%s: wifi_getSSIDName return error\n", __func__);
18235 return RETURN_ERR;
18236 }
developere40952c2023-06-15 18:46:43 +080018237 res = snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
18238 if (os_snprintf_error(sizeof(map->vap_array[i].u.bss_info.ssid), res)) {
18239 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18240 return RETURN_ERR;
18241 }
developer72fb0bb2023-01-11 09:46:29 +080018242
developera3511852023-06-14 14:12:59 +080018243 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080018244
developera3511852023-06-14 14:12:59 +080018245 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
18246 if (ret != RETURN_OK) {
18247 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
18248 return RETURN_ERR;
18249 }
18250 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080018251
developera3511852023-06-14 14:12:59 +080018252 ret = wifi_getApIsolationEnable(vap_index, &enabled);
18253 if (ret != RETURN_OK) {
18254 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
18255 return RETURN_ERR;
18256 }
18257 map->vap_array[i].u.bss_info.isolation = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018258
developera3511852023-06-14 14:12:59 +080018259 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
18260 if (ret != RETURN_OK) {
18261 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
18262 return RETURN_ERR;
18263 }
18264 map->vap_array[i].u.bss_info.bssMaxSta = output;
developer72fb0bb2023-01-11 09:46:29 +080018265
developera3511852023-06-14 14:12:59 +080018266 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
18267 if (ret != RETURN_OK) {
18268 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
18269 return RETURN_ERR;
18270 }
18271 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018272
developera3511852023-06-14 14:12:59 +080018273 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
18274 if (ret != RETURN_OK) {
18275 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
18276 return RETURN_ERR;
18277 }
18278 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018279
developera3511852023-06-14 14:12:59 +080018280 ret = wifi_getApSecurity(vap_index, &security);
18281 if (ret != RETURN_OK) {
18282 printf("%s: wifi_getApSecurity return error\n", __func__);
18283 return RETURN_ERR;
18284 }
18285 map->vap_array[i].u.bss_info.security = security;
developer72fb0bb2023-01-11 09:46:29 +080018286
developera3511852023-06-14 14:12:59 +080018287 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
18288 if (ret != RETURN_OK) {
18289 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
18290 return RETURN_ERR;
18291 }
18292 if (mode == 0)
18293 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
18294 else
18295 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
18296 if (mode == 1)
18297 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
18298 else if (mode == 2)
18299 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
developer72fb0bb2023-01-11 09:46:29 +080018300
developera3511852023-06-14 14:12:59 +080018301 ret = wifi_getApWmmEnable(vap_index, &enabled);
18302 if (ret != RETURN_OK) {
18303 printf("%s: wifi_getApWmmEnable return error\n", __func__);
18304 return RETURN_ERR;
18305 }
18306 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018307
developera3511852023-06-14 14:12:59 +080018308 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
18309 if (ret != RETURN_OK) {
18310 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
18311 return RETURN_ERR;
18312 }
18313 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018314
developera3511852023-06-14 14:12:59 +080018315 memset(buf, 0, sizeof(buf));
18316 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
18317 if (ret != RETURN_OK) {
18318 printf("%s: wifi_getApBeaconRate return error\n", __func__);
18319 return RETURN_ERR;
18320 }
18321 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
developer72fb0bb2023-01-11 09:46:29 +080018322
developera3511852023-06-14 14:12:59 +080018323 memset(buf, 0, sizeof(buf));
18324 ret = wifi_getBaseBSSID(vap_index, buf);
18325 if (ret != RETURN_OK) {
18326 printf("%s: wifi_getBaseBSSID return error\n", __func__);
18327 return RETURN_ERR;
18328 }
developer5b2f10c2023-05-25 17:02:21 +080018329 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
18330 printf("%s: hwaddr_aton2 fail\n", __func__);
developera3511852023-06-14 14:12:59 +080018331 return RETURN_ERR;
developer5b2f10c2023-05-25 17:02:21 +080018332 }
developer72fb0bb2023-01-11 09:46:29 +080018333
developera3511852023-06-14 14:12:59 +080018334 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
18335 if (ret != RETURN_OK) {
developerc14d83a2023-06-29 20:09:42 +080018336 wifi_debug(DEBUG_ERROR, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
developera3511852023-06-14 14:12:59 +080018337 return RETURN_ERR;
18338 }
18339 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018340
developera3511852023-06-14 14:12:59 +080018341 // TODO: wps, noack
18342 }
18343 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18344 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018345}
18346
developer47cc27a2023-05-17 23:09:58 +080018347void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080018348{
developera3511852023-06-14 14:12:59 +080018349 char if_name[16] = {0};
18350 char cmd[128] = {0};
18351 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080018352 int res;
developer72fb0bb2023-01-11 09:46:29 +080018353
developera3511852023-06-14 14:12:59 +080018354 *enable = FALSE;
18355 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
18356 return;
developer72fb0bb2023-01-11 09:46:29 +080018357
developere40952c2023-06-15 18:46:43 +080018358 res = snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
18359 if (os_snprintf_error(sizeof(cmd), res)) {
18360 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18361 return;
18362 }
developera3511852023-06-14 14:12:59 +080018363 _syscmd(cmd, buf, sizeof(buf));
18364 if (strlen(buf) > 0)
18365 *enable = TRUE;
18366 return;
developer72fb0bb2023-01-11 09:46:29 +080018367}
18368
developer56fbedb2023-05-30 16:47:05 +080018369int hostapd_manage_bss(INT apIndex, BOOL enable)
18370{
18371 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080018372 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer56fbedb2023-05-30 16:47:05 +080018373 char cmd[MAX_CMD_SIZE] = {0};
18374 char buf[MAX_BUF_SIZE] = {0};
18375 BOOL status = FALSE;
18376 int max_radio_num = 0;
18377 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080018378 int res;
developer56fbedb2023-05-30 16:47:05 +080018379
18380 wifi_getApEnable(apIndex, &status);
18381
18382 wifi_getMaxRadioNumber(&max_radio_num);
18383 if (enable == status)
18384 return RETURN_OK;
18385
18386 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
18387 return RETURN_ERR;
18388
18389 if (enable == TRUE) {
18390 int radioIndex = apIndex % max_radio_num;
18391 phyId = radio_index_to_phy(radioIndex);
developerc14d83a2023-06-29 20:09:42 +080018392 wifi_debug(DEBUG_ERROR, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080018393 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
18394 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18395 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18396 return RETURN_ERR;
18397 }
18398 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
18399 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18400 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18401 return RETURN_ERR;
18402 }
developer56fbedb2023-05-30 16:47:05 +080018403 _syscmd(cmd, buf, sizeof(buf));
18404 } else {
developerc14d83a2023-06-29 20:09:42 +080018405 wifi_debug(DEBUG_ERROR, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080018406 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
18407 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18408 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18409 return RETURN_ERR;
18410 }
developer56fbedb2023-05-30 16:47:05 +080018411 _syscmd(cmd, buf, sizeof(buf));
18412 }
developere40952c2023-06-15 18:46:43 +080018413 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer56fbedb2023-05-30 16:47:05 +080018414 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +080018415 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18416 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18417 return RETURN_ERR;
18418 }
developer56fbedb2023-05-30 16:47:05 +080018419 _syscmd(cmd, buf, sizeof(buf));
18420 //Wait for wifi up/down to apply
18421 return RETURN_OK;
18422}
18423
18424int hostapd_raw_add_bss(int apIndex)
18425{
18426 return hostapd_manage_bss(apIndex, TRUE);
18427}
18428
18429int hostapd_raw_remove_bss(int apIndex)
18430{
18431 return hostapd_manage_bss(apIndex, FALSE);
18432}
18433
18434int hostapd_raw_restart_bss(int apIndex)
developer333c1eb2023-05-31 14:59:39 +080018435{
developerdaf24792023-06-06 11:40:04 +080018436 int ret = 0;
18437
18438 ret = hostapd_raw_remove_bss(apIndex);
18439 if(ret != RETURN_OK)
18440 return RETURN_ERR;
18441
18442 ret = hostapd_raw_add_bss(apIndex);
18443 if(ret != RETURN_OK)
18444 return RETURN_ERR;
18445
18446 return RETURN_OK;
developer56fbedb2023-05-30 16:47:05 +080018447}
18448
developer72fb0bb2023-01-11 09:46:29 +080018449INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
18450{
developera3511852023-06-14 14:12:59 +080018451 unsigned int i;
18452 wifi_vap_info_t *vap_info = NULL;
18453 int acl_mode;
18454 int ret = 0;
18455 char buf[256] = {0};
18456 char cmd[128] = {0};
18457 char config_file[64] = {0};
18458 char psk_file[64] = {0};
18459 BOOL enable = FALSE;
18460 int band_idx;
developere40952c2023-06-15 18:46:43 +080018461 int res;
developere740c2a2023-05-23 18:34:32 +080018462
developer72fb0bb2023-01-11 09:46:29 +080018463
developera3511852023-06-14 14:12:59 +080018464 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
18465 printf("Entering %s index = %d\n", __func__, (int)index);
18466 for (i = 0; i < map->num_vaps; i++)
18467 {
18468 multiple_set = TRUE;
18469 vap_info = &map->vap_array[i];
developer72fb0bb2023-01-11 09:46:29 +080018470
developera3511852023-06-14 14:12:59 +080018471 // Check vap status file to enable multiple ap if the system boot.
18472 checkVapStatus(vap_info->vap_index, &enable);
18473 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
18474 continue;
developer72fb0bb2023-01-11 09:46:29 +080018475
developer75bd10c2023-06-27 11:34:08 +080018476 wifi_debug(DEBUG_ERROR, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
developer72fb0bb2023-01-11 09:46:29 +080018477
developera3511852023-06-14 14:12:59 +080018478 band_idx = radio_index_to_band(index);
developere40952c2023-06-15 18:46:43 +080018479 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
18480 if (os_snprintf_error(sizeof(config_file), res)) {
18481 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18482 return RETURN_ERR;
18483 }
developer9ce44382023-06-28 11:09:37 +080018484 if(band_idx >= 0 && band_idx < sizeof(wifi_band_str)/sizeof(wifi_band_str[0])){
18485 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
18486 } else{
18487 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18488 return RETURN_ERR;
18489 }
developere40952c2023-06-15 18:46:43 +080018490 if (os_snprintf_error(sizeof(cmd), res)) {
18491 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18492 return RETURN_ERR;
18493 }
developera3511852023-06-14 14:12:59 +080018494 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080018495
developera3511852023-06-14 14:12:59 +080018496 struct params params[3];
18497 params[0].name = "interface";
18498 params[0].value = vap_info->vap_name;
developere40952c2023-06-15 18:46:43 +080018499 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
18500 if (os_snprintf_error(sizeof(psk_file), res)) {
18501 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18502 return RETURN_ERR;
18503 }
developera3511852023-06-14 14:12:59 +080018504 params[1].name = "wpa_psk_file";
18505 params[1].value = psk_file;
18506 params[2].name = "ssid";
18507 params[2].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080018508
developer37646972023-06-29 10:58:43 +080018509 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
18510 if (os_snprintf_error(sizeof(config_file), res)) {
18511 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18512 return RETURN_ERR;
18513 }
developera3511852023-06-14 14:12:59 +080018514 wifi_hostapdWrite(config_file, params, 3);
developer72fb0bb2023-01-11 09:46:29 +080018515
developere40952c2023-06-15 18:46:43 +080018516 res = snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
18517 if (os_snprintf_error(sizeof(cmd), res)) {
18518 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18519 return RETURN_ERR;
18520 }
developera3511852023-06-14 14:12:59 +080018521 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080018522
developera3511852023-06-14 14:12:59 +080018523 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
18524 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018525 wifi_debug(DEBUG_ERROR,"wifi_setSSIDName return error\n");
developera3511852023-06-14 14:12:59 +080018526 return RETURN_ERR;
18527 }
developer72fb0bb2023-01-11 09:46:29 +080018528
developera3511852023-06-14 14:12:59 +080018529 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
18530 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018531 wifi_debug(DEBUG_ERROR, "wifi_setApSsidAdvertisementEnable return error\n");
developera3511852023-06-14 14:12:59 +080018532 return RETURN_ERR;
18533 }
developer72fb0bb2023-01-11 09:46:29 +080018534
developera3511852023-06-14 14:12:59 +080018535 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
18536 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018537 wifi_debug(DEBUG_ERROR, "wifi_setApIsolationEnable return error\n");
developera3511852023-06-14 14:12:59 +080018538 return RETURN_ERR;
18539 }
developer72fb0bb2023-01-11 09:46:29 +080018540
developera3511852023-06-14 14:12:59 +080018541 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
18542 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018543 wifi_debug(DEBUG_ERROR, "wifi_setApMaxAssociatedDevices return error\n");
developera3511852023-06-14 14:12:59 +080018544 return RETURN_ERR;
18545 }
developer72fb0bb2023-01-11 09:46:29 +080018546
developera3511852023-06-14 14:12:59 +080018547 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
18548 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018549 wifi_debug(DEBUG_ERROR, "wifi_setBSSTransitionActivation return error\n");
developera3511852023-06-14 14:12:59 +080018550 return RETURN_ERR;
18551 }
developer72fb0bb2023-01-11 09:46:29 +080018552
developera3511852023-06-14 14:12:59 +080018553 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
18554 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018555 wifi_debug(DEBUG_ERROR, "wifi_setNeighborReportActivation return error\n");
developera3511852023-06-14 14:12:59 +080018556 return RETURN_ERR;
18557 }
developer72fb0bb2023-01-11 09:46:29 +080018558
developera3511852023-06-14 14:12:59 +080018559 if (vap_info->u.bss_info.mac_filter_enable == false){
18560 acl_mode = 0;
18561 }else {
18562 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
18563 acl_mode = 2;
developere40952c2023-06-15 18:46:43 +080018564 res = snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
18565 if (os_snprintf_error(sizeof(cmd), res)) {
18566 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18567 return RETURN_ERR;
18568 }
developera3511852023-06-14 14:12:59 +080018569 _syscmd(cmd, buf, sizeof(buf));
18570 }else{
18571 acl_mode = 1;
18572 }
18573 }
developer72fb0bb2023-01-11 09:46:29 +080018574
developera3511852023-06-14 14:12:59 +080018575 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
18576 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018577 wifi_debug(DEBUG_ERROR, "wifi_setApWmmEnable return error\n");
developera3511852023-06-14 14:12:59 +080018578 return RETURN_ERR;
18579 }
developer72fb0bb2023-01-11 09:46:29 +080018580
developera3511852023-06-14 14:12:59 +080018581 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
18582 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018583 wifi_debug(DEBUG_ERROR, "wifi_setApWmmUapsdEnable return error\n");
developera3511852023-06-14 14:12:59 +080018584 return RETURN_ERR;
18585 }
developer72fb0bb2023-01-11 09:46:29 +080018586
developera3511852023-06-14 14:12:59 +080018587 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080018588 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080018589 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
18590 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018591 wifi_debug(DEBUG_ERROR, "wifi_setApBeaconRate return error\n");
developera3511852023-06-14 14:12:59 +080018592 return RETURN_ERR;
18593 }
developer72fb0bb2023-01-11 09:46:29 +080018594
developera3511852023-06-14 14:12:59 +080018595 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
18596 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018597 wifi_debug(DEBUG_ERROR, "wifi_setRadioIGMPSnoopingEnable\n");
developera3511852023-06-14 14:12:59 +080018598 return RETURN_ERR;
18599 }
developer72fb0bb2023-01-11 09:46:29 +080018600
developera3511852023-06-14 14:12:59 +080018601 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
18602 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018603 wifi_debug(DEBUG_ERROR, "wifi_setApSecurity return error\n");
developera3511852023-06-14 14:12:59 +080018604 return RETURN_ERR;
18605 }
developer333c1eb2023-05-31 14:59:39 +080018606
developer56fbedb2023-05-30 16:47:05 +080018607 hostapd_raw_restart_bss(vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080018608
developera3511852023-06-14 14:12:59 +080018609 multiple_set = FALSE;
developer23e71282023-01-18 10:25:19 +080018610
developera3511852023-06-14 14:12:59 +080018611 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
18612 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
18613 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018614 wifi_debug(DEBUG_ERROR, "wifi_setApMacAddressControlMode return error\n");
developera3511852023-06-14 14:12:59 +080018615 return RETURN_ERR;
18616 }
developer72fb0bb2023-01-11 09:46:29 +080018617
developera3511852023-06-14 14:12:59 +080018618 // TODO mgmtPowerControl, interworking, wps
18619 }
18620 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18621 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018622}
18623
18624int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
18625{
developera3511852023-06-14 14:12:59 +080018626 char *token, *next;
18627 const char s[2] = ",";
18628 int count =0;
developer72fb0bb2023-01-11 09:46:29 +080018629
developera3511852023-06-14 14:12:59 +080018630 /* get the first token */
18631 token = strtok_r(pchannels, s, &next);
developer72fb0bb2023-01-11 09:46:29 +080018632
developera3511852023-06-14 14:12:59 +080018633 /* walk through other tokens */
18634 while( token != NULL && count < MAX_CHANNELS) {
18635 chlistptr->channels_list[count++] = atoi(token);
18636 token = strtok_r(NULL, s, &next);
18637 }
developer72fb0bb2023-01-11 09:46:29 +080018638
developera3511852023-06-14 14:12:59 +080018639 return count;
developer72fb0bb2023-01-11 09:46:29 +080018640}
18641
18642static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
18643{
developera3511852023-06-14 14:12:59 +080018644 INT status;
18645 wifi_channels_list_t *chlistp;
18646 CHAR output_string[64];
18647 CHAR pchannels[128];
18648 CHAR interface_name[16] = {0};
18649 wifi_band band;
developere40952c2023-06-15 18:46:43 +080018650 int res;
developer72fb0bb2023-01-11 09:46:29 +080018651
developera3511852023-06-14 14:12:59 +080018652 if(rcap == NULL)
18653 {
18654 return RETURN_ERR;
18655 }
developer72fb0bb2023-01-11 09:46:29 +080018656
developera3511852023-06-14 14:12:59 +080018657 rcap->numSupportedFreqBand = 1;
18658 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080018659
developera3511852023-06-14 14:12:59 +080018660 if (band == band_2_4)
18661 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
18662 else if (band == band_5)
18663 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
18664 else if (band == band_6)
18665 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
developer72fb0bb2023-01-11 09:46:29 +080018666
developera3511852023-06-14 14:12:59 +080018667 chlistp = &(rcap->channel_list[0]);
18668 memset(pchannels, 0, sizeof(pchannels));
developer72fb0bb2023-01-11 09:46:29 +080018669
developera3511852023-06-14 14:12:59 +080018670 /* possible number of radio channels */
18671 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
18672 {
18673 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
18674 }
18675 /* Number of channels and list*/
18676 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
developer72fb0bb2023-01-11 09:46:29 +080018677
developera3511852023-06-14 14:12:59 +080018678 /* autoChannelSupported */
18679 /* always ON with wifi_getRadioAutoChannelSupported */
18680 rcap->autoChannelSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018681
developera3511852023-06-14 14:12:59 +080018682 /* DCSSupported */
18683 /* always ON with wifi_getRadioDCSSupported */
18684 rcap->DCSSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018685
developera3511852023-06-14 14:12:59 +080018686 /* zeroDFSSupported - TBD */
18687 rcap->zeroDFSSupported = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018688
developera3511852023-06-14 14:12:59 +080018689 /* Supported Country List*/
18690 memset(output_string, 0, sizeof(output_string));
18691 status = wifi_getRadioCountryCode(radioIndex, output_string);
18692 if( status != 0 ) {
18693 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
18694 return RETURN_ERR;
18695 } else {
18696 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
18697 }
18698 if(!strcmp(output_string,"US")){
18699 rcap->countrySupported[0] = wifi_countrycode_US;
18700 rcap->countrySupported[1] = wifi_countrycode_CA;
18701 } else if (!strcmp(output_string,"CA")) {
18702 rcap->countrySupported[0] = wifi_countrycode_CA;
18703 rcap->countrySupported[1] = wifi_countrycode_US;
18704 } else {
18705 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
18706 }
developer72fb0bb2023-01-11 09:46:29 +080018707
developera3511852023-06-14 14:12:59 +080018708 rcap->numcountrySupported = 2;
developer72fb0bb2023-01-11 09:46:29 +080018709
developera3511852023-06-14 14:12:59 +080018710 /* csi */
18711 rcap->csi.maxDevices = 8;
18712 rcap->csi.soudingFrameSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018713
developer86035662023-06-28 19:21:12 +080018714 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
18715 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
18716 }
developere40952c2023-06-15 18:46:43 +080018717 res = snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
18718 if (os_snprintf_error(sizeof(interface_name), res)) {
18719 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18720 return RETURN_ERR;
18721 }
developer72fb0bb2023-01-11 09:46:29 +080018722
developera3511852023-06-14 14:12:59 +080018723 /* channelWidth - all supported bandwidths */
18724 int i=0;
18725 rcap->channelWidth[i] = 0;
18726 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
18727 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
18728 WIFI_CHANNELBANDWIDTH_40MHZ);
developer72fb0bb2023-01-11 09:46:29 +080018729
developera3511852023-06-14 14:12:59 +080018730 }
18731 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
18732 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
18733 WIFI_CHANNELBANDWIDTH_40MHZ |
18734 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
18735 }
developer72fb0bb2023-01-11 09:46:29 +080018736
18737
developera3511852023-06-14 14:12:59 +080018738 /* mode - all supported variants */
18739 // rcap->mode[i] = WIFI_80211_VARIANT_H;
18740 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
18741 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
18742 }
18743 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
18744 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
18745 }
18746 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
18747 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
18748 }
18749 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
18750 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
developer72fb0bb2023-01-11 09:46:29 +080018751
developera3511852023-06-14 14:12:59 +080018752 /* supportedBitRate - all supported bitrates */
18753 rcap->supportedBitRate[i] = 0;
18754 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
18755 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
18756 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
18757 }
18758 else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
18759 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
18760 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
18761 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
18762 }
developer72fb0bb2023-01-11 09:46:29 +080018763
18764
developera3511852023-06-14 14:12:59 +080018765 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
18766 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
18767 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
18768 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
18769 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
18770 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
18771 rcap->cipherSupported = 0;
18772 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
18773 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
developer72fb0bb2023-01-11 09:46:29 +080018774
developera3511852023-06-14 14:12:59 +080018775 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018776}
18777
18778INT wifi_getHalCapability(wifi_hal_capability_t *cap)
18779{
developera3511852023-06-14 14:12:59 +080018780 INT status = 0, radioIndex = 0;
18781 char output[MAX_BUF_SIZE] = {0};
18782 int iter = 0;
18783 unsigned int j = 0;
developer9ce44382023-06-28 11:09:37 +080018784 int max_num_radios = 0;
developera3511852023-06-14 14:12:59 +080018785 wifi_interface_name_idex_map_t *iface_info = NULL;
developer72fb0bb2023-01-11 09:46:29 +080018786
developera3511852023-06-14 14:12:59 +080018787 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018788
developera3511852023-06-14 14:12:59 +080018789 memset(cap, 0, sizeof(wifi_hal_capability_t));
developer72fb0bb2023-01-11 09:46:29 +080018790
developera3511852023-06-14 14:12:59 +080018791 /* version */
18792 cap->version.major = WIFI_HAL_MAJOR_VERSION;
18793 cap->version.minor = WIFI_HAL_MINOR_VERSION;
developer72fb0bb2023-01-11 09:46:29 +080018794
developera3511852023-06-14 14:12:59 +080018795 /* number of radios platform property */
18796 wifi_getMaxRadioNumber(&max_num_radios);
18797 cap->wifi_prop.numRadios = max_num_radios;
developer72fb0bb2023-01-11 09:46:29 +080018798
developera3511852023-06-14 14:12:59 +080018799 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
18800 {
18801 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
18802 if (status != 0) {
18803 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
18804 return RETURN_ERR;
18805 }
developer72fb0bb2023-01-11 09:46:29 +080018806
developera3511852023-06-14 14:12:59 +080018807 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
18808 {
18809 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
18810 {
18811 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
18812 return RETURN_ERR;
18813 }
18814 iface_info = &cap->wifi_prop.interface_map[iter];
18815 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
18816 iface_info->rdk_radio_index = radioIndex;
18817 memset(output, 0, sizeof(output));
18818 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
18819 {
18820 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
18821 }
18822 // TODO: bridge name
18823 // TODO: vlan id
18824 // TODO: primary
18825 iface_info->index = array_index_to_vap_index(radioIndex, j);
18826 memset(output, 0, sizeof(output));
18827 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
18828 {
18829 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
18830 }
18831 iter++;
18832 }
18833 }
developer72fb0bb2023-01-11 09:46:29 +080018834
developera3511852023-06-14 14:12:59 +080018835 cap->BandSteeringSupported = FALSE;
18836 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18837 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018838}
18839
18840INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
18841{
developera3511852023-06-14 14:12:59 +080018842 struct params h_config={0};
18843 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018844 int res;
developer72fb0bb2023-01-11 09:46:29 +080018845
developera3511852023-06-14 14:12:59 +080018846 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018847
developera3511852023-06-14 14:12:59 +080018848 h_config.name = "okc";
18849 h_config.value = okc_enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018850
developere40952c2023-06-15 18:46:43 +080018851 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18852 if (os_snprintf_error(sizeof(config_file), res)) {
18853 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18854 return RETURN_ERR;
18855 }
developera3511852023-06-14 14:12:59 +080018856 wifi_hostapdWrite(config_file, &h_config, 1);
18857 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018858
developera3511852023-06-14 14:12:59 +080018859 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18860 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018861}
18862
18863INT wifi_setSAEMFP(int ap_index, BOOL enable)
18864{
developera3511852023-06-14 14:12:59 +080018865 struct params h_config={0};
18866 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018867 int res;
developer72fb0bb2023-01-11 09:46:29 +080018868
developera3511852023-06-14 14:12:59 +080018869 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018870
developera3511852023-06-14 14:12:59 +080018871 h_config.name = "sae_require_mfp";
18872 h_config.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018873
developere40952c2023-06-15 18:46:43 +080018874 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18875 if (os_snprintf_error(sizeof(config_file), res)) {
18876 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18877 return RETURN_ERR;
18878 }
developera3511852023-06-14 14:12:59 +080018879 wifi_hostapdWrite(config_file, &h_config, 1);
18880 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018881
developera3511852023-06-14 14:12:59 +080018882 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18883 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018884}
18885
18886INT wifi_setSAEpwe(int ap_index, int sae_pwe)
18887{
developera3511852023-06-14 14:12:59 +080018888 struct params h_config={0};
18889 char config_file[64] = {0};
18890 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080018891 int res;
developer72fb0bb2023-01-11 09:46:29 +080018892
developera3511852023-06-14 14:12:59 +080018893 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018894
developera3511852023-06-14 14:12:59 +080018895 h_config.name = "sae_pwe";
developere40952c2023-06-15 18:46:43 +080018896 res = snprintf(buf, sizeof(buf), "%d", sae_pwe);
18897 if (os_snprintf_error(sizeof(buf), res)) {
18898 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18899 return RETURN_ERR;
18900 }
18901
developera3511852023-06-14 14:12:59 +080018902 h_config.value = buf;
developer72fb0bb2023-01-11 09:46:29 +080018903
developere40952c2023-06-15 18:46:43 +080018904 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18905 if (os_snprintf_error(sizeof(config_file), res)) {
18906 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18907 return RETURN_ERR;
18908 }
developera3511852023-06-14 14:12:59 +080018909 wifi_hostapdWrite(config_file, &h_config, 1);
18910 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018911
developera3511852023-06-14 14:12:59 +080018912 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18913 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018914}
18915
18916INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
18917{
developera3511852023-06-14 14:12:59 +080018918 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
18919 struct params h_config={0};
18920 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018921 int res;
developer72fb0bb2023-01-11 09:46:29 +080018922
developera3511852023-06-14 14:12:59 +080018923 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018924
developera3511852023-06-14 14:12:59 +080018925 h_config.name = "wpa_disable_eapol_key_retries";
18926 h_config.value = disable_EAPOL_retries?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018927
developere40952c2023-06-15 18:46:43 +080018928 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18929 if (os_snprintf_error(sizeof(config_file), res)) {
18930 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18931 return RETURN_ERR;
18932 }
developera3511852023-06-14 14:12:59 +080018933 wifi_hostapdWrite(config_file, &h_config, 1);
18934 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018935
developera3511852023-06-14 14:12:59 +080018936 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18937 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018938}
18939
18940INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
18941{
developera3511852023-06-14 14:12:59 +080018942 char buf[128] = {0};
18943 char config_file[128] = {0};
18944 char cmd[MAX_CMD_SIZE] = {0};
18945 char password[65] = {0};
18946 char mfp[32] = {0};
18947 char wpa_mode[32] = {0};
18948 BOOL okc_enable = FALSE;
18949 BOOL sae_MFP = FALSE;
18950 BOOL disable_EAPOL_retries = TRUE;
18951 int sae_pwe = 0;
18952 struct params params = {0};
18953 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080018954 int res;
developer72fb0bb2023-01-11 09:46:29 +080018955
developera3511852023-06-14 14:12:59 +080018956 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018957
developera3511852023-06-14 14:12:59 +080018958 multiple_set = TRUE;
developer37646972023-06-29 10:58:43 +080018959 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18960 if (os_snprintf_error(sizeof(config_file), res)) {
18961 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18962 return RETURN_ERR;
18963 }
developera3511852023-06-14 14:12:59 +080018964 if (security->mode == wifi_security_mode_none) {
developer9ce44382023-06-28 11:09:37 +080018965 strncpy(wpa_mode, "None",sizeof(wpa_mode) - 1);
18966 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18967 } else if (security->mode == wifi_security_mode_wpa_personal) {
18968 strncpy(wpa_mode, "WPA-Personal",sizeof(wpa_mode) - 1);
18969 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18970 } else if (security->mode == wifi_security_mode_wpa2_personal){
18971 strncpy(wpa_mode, "WPA2-Personal",sizeof(wpa_mode) - 1);
18972 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18973 } else if (security->mode == wifi_security_mode_wpa_wpa2_personal){
18974 strncpy(wpa_mode, "WPA-WPA2-Personal",sizeof(wpa_mode) - 1);
18975 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18976 } else if (security->mode == wifi_security_mode_wpa_enterprise){
18977 strncpy(wpa_mode, "WPA-Enterprise",sizeof(wpa_mode) - 1);
18978 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18979 } else if (security->mode == wifi_security_mode_wpa2_enterprise){
18980 strncpy(wpa_mode, "WPA2-Enterprise",sizeof(wpa_mode) - 1);
18981 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18982 } else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise){
18983 strncpy(wpa_mode, "WPA-WAP2-Enterprise",sizeof(wpa_mode) - 1);
18984 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18985 } else if (security->mode == wifi_security_mode_wpa3_personal) {
18986 strncpy(wpa_mode, "WPA3-Personal",sizeof(wpa_mode) - 1);
18987 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018988 okc_enable = TRUE;
18989 sae_MFP = TRUE;
18990 sae_pwe = 2;
18991 disable_EAPOL_retries = FALSE;
18992 } else if (security->mode == wifi_security_mode_wpa3_transition) {
developer9ce44382023-06-28 11:09:37 +080018993 strncpy(wpa_mode, "WPA3-Personal-Transition",sizeof(wpa_mode) - 1);
18994 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018995 okc_enable = TRUE;
18996 sae_MFP = TRUE;
18997 sae_pwe = 2;
18998 disable_EAPOL_retries = FALSE;
18999 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
developer9ce44382023-06-28 11:09:37 +080019000 strncpy(wpa_mode, "WPA3-Enterprise",sizeof(wpa_mode) - 1);
19001 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080019002 sae_MFP = TRUE;
19003 sae_pwe = 2;
19004 disable_EAPOL_retries = FALSE;
19005 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer9ce44382023-06-28 11:09:37 +080019006 strncpy(wpa_mode, "OWE",sizeof(wpa_mode) - 1);
19007 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080019008 sae_MFP = TRUE;
19009 sae_pwe = 2;
19010 disable_EAPOL_retries = FALSE;
19011 }
developer72fb0bb2023-01-11 09:46:29 +080019012
developera3511852023-06-14 14:12:59 +080019013 band = wifi_index_to_band(ap_index);
19014 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
developerc14d83a2023-06-29 20:09:42 +080019015 wifi_debug(DEBUG_ERROR, "%s: 6G band must set with wpa3.\n", __func__);
developera3511852023-06-14 14:12:59 +080019016 return RETURN_ERR;
19017 }
developer72fb0bb2023-01-11 09:46:29 +080019018
developera3511852023-06-14 14:12:59 +080019019 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
19020 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
19021 wifi_setSAEMFP(ap_index, sae_MFP);
19022 wifi_setSAEpwe(ap_index, sae_pwe);
19023 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
developer72fb0bb2023-01-11 09:46:29 +080019024
developera3511852023-06-14 14:12:59 +080019025 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
19026 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) {
19027 int key_len = strlen(security->u.key.key);
19028 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
19029 if (key_len == 64) { // set wpa_psk
19030 strncpy(password, security->u.key.key, 64); // 64 characters
19031 password[64] = '\0';
19032 wifi_setApSecurityPreSharedKey(ap_index, password);
developere40952c2023-06-15 18:46:43 +080019033 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
19034 if (os_snprintf_error(sizeof(cmd), res)) {
19035 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19036 return RETURN_ERR;
19037 }
developera3511852023-06-14 14:12:59 +080019038 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
19039 strncpy(password, security->u.key.key, 63);
19040 password[63] = '\0';
19041 wifi_setApSecurityKeyPassphrase(ap_index, password);
developere40952c2023-06-15 18:46:43 +080019042 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
developer9ce44382023-06-28 11:09:37 +080019043 if (os_snprintf_error(sizeof(cmd), res)) {
19044 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19045 return RETURN_ERR;
19046 }
developera3511852023-06-14 14:12:59 +080019047 } else
19048 return RETURN_ERR;
19049 _syscmd(cmd, buf, sizeof(buf));
19050 }
19051 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
19052 params.name = "sae_password";
19053 params.value = security->u.key.key;
19054 wifi_hostapdWrite(config_file, &params, 1);
19055 } else { // remove sae_password
developere40952c2023-06-15 18:46:43 +080019056 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
19057 if (os_snprintf_error(sizeof(cmd), res)) {
19058 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19059 return RETURN_ERR;
19060 }
developera3511852023-06-14 14:12:59 +080019061 _syscmd(cmd, buf, sizeof(buf));
19062 }
19063 }
developer72fb0bb2023-01-11 09:46:29 +080019064
developera3511852023-06-14 14:12:59 +080019065 if (security->mode != wifi_security_mode_none) {
19066 memset(&params, 0, sizeof(params));
19067 params.name = "wpa_pairwise";
19068 if (security->encr == wifi_encryption_tkip)
19069 params.value = "TKIP";
19070 else if (security->encr == wifi_encryption_aes)
19071 params.value = "CCMP";
19072 else if (security->encr == wifi_encryption_aes_tkip)
19073 params.value = "TKIP CCMP";
19074 wifi_hostapdWrite(config_file, &params, 1);
19075 }
developer72fb0bb2023-01-11 09:46:29 +080019076
developer9ce44382023-06-28 11:09:37 +080019077 if (security->mfp == wifi_mfp_cfg_disabled){
19078 strncpy(mfp,"Disabled",sizeof(mfp)-1);
19079 mfp[sizeof(mfp)-1] = '\0';
19080 } else if (security->mfp == wifi_mfp_cfg_optional){
19081 strncpy(mfp,"Optional",sizeof(mfp)-1);
19082 mfp[sizeof(mfp)-1] = '\0';
19083 } else if (security->mfp == wifi_mfp_cfg_required){
19084 strncpy(mfp,"Required",sizeof(mfp)-1);
19085 mfp[sizeof(mfp)-1] = '\0';
19086 }
developera3511852023-06-14 14:12:59 +080019087 wifi_setApSecurityMFPConfig(ap_index, mfp);
developer72fb0bb2023-01-11 09:46:29 +080019088
developera3511852023-06-14 14:12:59 +080019089 memset(&params, 0, sizeof(params));
19090 params.name = "transition_disable";
19091 if (security->wpa3_transition_disable == TRUE)
19092 params.value = "0x01";
19093 else
19094 params.value = "0x00";
19095 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080019096
developera3511852023-06-14 14:12:59 +080019097 memset(&params, 0, sizeof(params));
19098 params.name = "wpa_group_rekey";
developere40952c2023-06-15 18:46:43 +080019099 res = snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
19100 if (os_snprintf_error(sizeof(buf), res)) {
19101 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19102 return RETURN_ERR;
19103 }
developera3511852023-06-14 14:12:59 +080019104 params.value = buf;
19105 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080019106
developera3511852023-06-14 14:12:59 +080019107 memset(&params, 0, sizeof(params));
19108 params.name = "wpa_strict_rekey";
19109 params.value = security->strict_rekey?"1":"0";
19110 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080019111
developera3511852023-06-14 14:12:59 +080019112 memset(&params, 0, sizeof(params));
19113 params.name = "wpa_pairwise_update_count";
19114 if (security->eapol_key_retries == 0)
19115 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developere40952c2023-06-15 18:46:43 +080019116 res = snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
19117 if (os_snprintf_error(sizeof(buf), res)) {
19118 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19119 return RETURN_ERR;
19120 }
developera3511852023-06-14 14:12:59 +080019121 params.value = buf;
19122 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080019123
developera3511852023-06-14 14:12:59 +080019124 memset(&params, 0, sizeof(params));
19125 params.name = "disable_pmksa_caching";
19126 params.value = security->disable_pmksa_caching?"1":"0";
19127 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080019128
developera3511852023-06-14 14:12:59 +080019129 if (multiple_set == FALSE) {
19130 wifi_setApEnable(ap_index, FALSE);
19131 wifi_setApEnable(ap_index, TRUE);
19132 }
developer72fb0bb2023-01-11 09:46:29 +080019133
developera3511852023-06-14 14:12:59 +080019134 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080019135
developera3511852023-06-14 14:12:59 +080019136 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019137}
19138
19139INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
19140{
developera3511852023-06-14 14:12:59 +080019141 char buf[256] = {0};
19142 char config_file[128] = {0};
developer86035662023-06-28 19:21:12 +080019143 long int disable = 0;
19144 long int tmp;
developera3511852023-06-14 14:12:59 +080019145 bool set_sae = FALSE;
developere75ba632023-06-29 16:03:33 +080019146 int res;
developer72fb0bb2023-01-11 09:46:29 +080019147
developera3511852023-06-14 14:12:59 +080019148 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere75ba632023-06-29 16:03:33 +080019149 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
19150 if (os_snprintf_error(sizeof(config_file), res)) {
19151 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19152 return RETURN_ERR;
19153 }
developera3511852023-06-14 14:12:59 +080019154 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
19155 security->mode = wifi_security_mode_none;
19156 if (strlen(buf) != 0) {
19157 if (!strcmp(buf, "WPA-Personal"))
19158 security->mode = wifi_security_mode_wpa_personal;
19159 else if (!strcmp(buf, "WPA2-Personal"))
19160 security->mode = wifi_security_mode_wpa2_personal;
19161 else if (!strcmp(buf, "WPA-WPA2-Personal"))
19162 security->mode = wifi_security_mode_wpa_wpa2_personal;
19163 else if (!strcmp(buf, "WPA-Enterprise"))
19164 security->mode = wifi_security_mode_wpa_enterprise;
19165 else if (!strcmp(buf, "WPA2-Enterprise"))
19166 security->mode = wifi_security_mode_wpa2_enterprise;
19167 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
19168 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
19169 else if (!strcmp(buf, "WPA3-Personal"))
19170 security->mode = wifi_security_mode_wpa3_personal;
19171 else if (!strcmp(buf, "WPA3-Personal-Transition"))
19172 security->mode = wifi_security_mode_wpa3_transition;
19173 else if (!strcmp(buf, "WPA3-Enterprise"))
19174 security->mode = wifi_security_mode_wpa3_enterprise;
19175 else if (!strcmp(buf, "OWE"))
19176 security->mode = wifi_security_mode_enhanced_open;
19177 }
developer72fb0bb2023-01-11 09:46:29 +080019178
developera3511852023-06-14 14:12:59 +080019179 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
19180 if (security->mode == wifi_security_mode_none)
19181 security->encr = wifi_encryption_none;
19182 else {
19183 if (strcmp(buf, "TKIP") == 0)
19184 security->encr = wifi_encryption_tkip;
19185 else if (strcmp(buf, "CCMP") == 0)
19186 security->encr = wifi_encryption_aes;
19187 else
19188 security->encr = wifi_encryption_aes_tkip;
19189 }
developer72fb0bb2023-01-11 09:46:29 +080019190
developera3511852023-06-14 14:12:59 +080019191 if (security->mode != wifi_security_mode_none) {
19192 memset(buf, 0, sizeof(buf));
19193 // wpa3 can use one or both configs as password, so we check sae_password first.
19194 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
19195 if (strlen(buf) != 0) {
19196 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
19197 security->u.key.type = wifi_security_key_type_sae;
19198 set_sae = TRUE;
19199 strncpy(security->u.key.key, buf, sizeof(buf));
19200 }
19201 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
19202 if (strlen(buf) != 0){
19203 if (set_sae == TRUE)
19204 security->u.key.type = wifi_security_key_type_psk_sae;
19205 else if (strlen(buf) == 64)
19206 security->u.key.type = wifi_security_key_type_psk;
19207 else
19208 security->u.key.type = wifi_security_key_type_pass;
19209 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
19210 }
19211 security->u.key.key[255] = '\0';
19212 }
developer72fb0bb2023-01-11 09:46:29 +080019213
developera3511852023-06-14 14:12:59 +080019214 memset(buf, 0, sizeof(buf));
19215 wifi_getApSecurityMFPConfig(ap_index, buf);
19216 if (strcmp(buf, "Disabled") == 0)
19217 security->mfp = wifi_mfp_cfg_disabled;
19218 else if (strcmp(buf, "Optional") == 0)
19219 security->mfp = wifi_mfp_cfg_optional;
19220 else if (strcmp(buf, "Required") == 0)
19221 security->mfp = wifi_mfp_cfg_required;
developer72fb0bb2023-01-11 09:46:29 +080019222
developera3511852023-06-14 14:12:59 +080019223 memset(buf, 0, sizeof(buf));
19224 security->wpa3_transition_disable = FALSE;
19225 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
developer3de255a2023-06-29 10:35:45 +080019226 if (strlen(buf) == 0)
19227 disable = 0;
19228 else {
19229 if (hal_strtol(buf, 16, &disable) < 0) {
19230 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19231 return RETURN_ERR;
19232 }
developer86035662023-06-28 19:21:12 +080019233 }
developera3511852023-06-14 14:12:59 +080019234 if (disable != 0)
19235 security->wpa3_transition_disable = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080019236
developera3511852023-06-14 14:12:59 +080019237 memset(buf, 0, sizeof(buf));
19238 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
19239 if (strlen(buf) == 0)
19240 security->rekey_interval = 86400;
developer86035662023-06-28 19:21:12 +080019241 else {
19242 if (hal_strtol(buf, 10, &tmp) < 0) {
19243 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19244 return RETURN_ERR;
19245 }
19246 security->rekey_interval = tmp;
19247 }
developer72fb0bb2023-01-11 09:46:29 +080019248
developera3511852023-06-14 14:12:59 +080019249 memset(buf, 0, sizeof(buf));
19250 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
19251 if (strlen(buf) == 0)
19252 security->strict_rekey = 1;
developer86035662023-06-28 19:21:12 +080019253 else {
19254 if (hal_strtol(buf, 10, &tmp) < 0) {
19255 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19256 return RETURN_ERR;
19257 }
19258 security->strict_rekey = tmp;
19259 }
developer72fb0bb2023-01-11 09:46:29 +080019260
developera3511852023-06-14 14:12:59 +080019261 memset(buf, 0, sizeof(buf));
19262 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
19263 if (strlen(buf) == 0)
19264 security->eapol_key_retries = 4;
developer86035662023-06-28 19:21:12 +080019265 else {
19266 if (hal_strtol(buf, 10, &tmp) < 0) {
19267 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19268 return RETURN_ERR;
19269 }
19270 security->eapol_key_retries = tmp;
19271 }
developer72fb0bb2023-01-11 09:46:29 +080019272
developera3511852023-06-14 14:12:59 +080019273 memset(buf, 0, sizeof(buf));
19274 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
19275 if (strlen(buf) == 0)
19276 security->disable_pmksa_caching = FALSE;
developer86035662023-06-28 19:21:12 +080019277 else {
19278 if (hal_strtol(buf, 10, &(tmp)) < 0) {
19279 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19280 return RETURN_ERR;
19281 }
19282 security->disable_pmksa_caching = tmp ? TRUE : FALSE;
19283 }
developera3511852023-06-14 14:12:59 +080019284 /* TODO
19285 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
19286 */
19287 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
19288 security->eap_identity_req_timeout = 0;
19289 security->eap_identity_req_retries = 0;
19290 security->eap_req_timeout = 0;
19291 security->eap_req_retries = 0;
19292 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
19293 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019294}
19295
19296#endif /* WIFI_HAL_VERSION_3 */
19297
19298#ifdef WIFI_HAL_VERSION_3_PHASE2
19299INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
19300{
developera3511852023-06-14 14:12:59 +080019301 char interface_name[16] = {0};
19302 char cmd[128] = {0};
19303 char buf[128] = {0};
19304 char *mac_addr = NULL;
19305 BOOL status = FALSE;
19306 size_t len = 0;
developer72fb0bb2023-01-11 09:46:29 +080019307
developera3511852023-06-14 14:12:59 +080019308 if(ap_index > MAX_APS)
19309 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080019310
developera3511852023-06-14 14:12:59 +080019311 *output_numDevices = 0;
19312 wifi_getApEnable(ap_index, &status);
19313 if (status == FALSE)
19314 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019315
developera3511852023-06-14 14:12:59 +080019316 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
19317 return RETURN_ERR;
19318 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
19319 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080019320
developera3511852023-06-14 14:12:59 +080019321 mac_addr = strtok(buf, "\n");
19322 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
19323 *output_numDevices = i + 1;
developerc14d83a2023-06-29 20:09:42 +080019324 wifi_debug(DEBUG_ERROR,, "mac_addr: %s\n", mac_addr);
developera3511852023-06-14 14:12:59 +080019325 addr_ptr = output_deviceMacAddressArray[i];
19326 mac_addr_aton(addr_ptr, mac_addr);
19327 mac_addr = strtok(NULL, "\n");
19328 }
developer72fb0bb2023-01-11 09:46:29 +080019329
developera3511852023-06-14 14:12:59 +080019330 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019331}
19332#else
19333INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
19334{
developera3511852023-06-14 14:12:59 +080019335 char interface_name[16] = {0};
19336 char cmd[128];
19337 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +080019338 int res;
developer72fb0bb2023-01-11 09:46:29 +080019339
developera3511852023-06-14 14:12:59 +080019340 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
19341 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080019342
developera3511852023-06-14 14:12:59 +080019343 output_buf[0] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080019344
developera3511852023-06-14 14:12:59 +080019345 wifi_getApEnable(ap_index,&status);
19346 if (!status)
19347 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019348
developera3511852023-06-14 14:12:59 +080019349 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
19350 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080019351 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
19352 if (os_snprintf_error(sizeof(cmd), res)) {
19353 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19354 return RETURN_ERR;
19355 }
19356
developera3511852023-06-14 14:12:59 +080019357 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080019358
developera3511852023-06-14 14:12:59 +080019359 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019360}
19361#endif
19362
19363INT wifi_getProxyArp(INT apIndex, BOOL *enable)
19364{
developera3511852023-06-14 14:12:59 +080019365 char output[16]={'\0'};
19366 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080019367 int res;
developer72fb0bb2023-01-11 09:46:29 +080019368
developera3511852023-06-14 14:12:59 +080019369 if (!enable)
19370 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080019371
developer75bd10c2023-06-27 11:34:08 +080019372 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
19373 if (os_snprintf_error(sizeof(config_file), res)) {
19374 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19375 return RETURN_ERR;
19376 }
developera3511852023-06-14 14:12:59 +080019377 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080019378
developera3511852023-06-14 14:12:59 +080019379 if (strlen(output) == 0)
19380 *enable = FALSE;
19381 else if (strncmp(output, "1", 1) == 0)
19382 *enable = TRUE;
19383 else
19384 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080019385
developera3511852023-06-14 14:12:59 +080019386 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
19387 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019388}
19389
19390INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
19391{
developera3511852023-06-14 14:12:59 +080019392 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
19393 return RETURN_ERR;
19394 *output_enable=TRUE;
19395 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019396}
19397
19398INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
19399{
developera3511852023-06-14 14:12:59 +080019400 char cmd[128] = {0};
19401 char buf[128] = {0};
19402 char line[128] = {0};
19403 FILE *f = NULL;
19404 int index = 0;
19405 int exp = 0;
19406 int mantissa = 0;
19407 int duration = 0;
19408 int radio_index = 0;
19409 int max_radio_num = 0;
19410 uint twt_wake_interval = 0;
19411 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +080019412 int res;
developerc14d83a2023-06-29 20:09:42 +080019413 unsigned long tmp_u, tmp_l;
developer75bd10c2023-06-27 11:34:08 +080019414
developera3511852023-06-14 14:12:59 +080019415 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080019416
developera3511852023-06-14 14:12:59 +080019417 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080019418 if(max_radio_num == 0){
19419 return RETURN_ERR;
19420 }
developera3511852023-06-14 14:12:59 +080019421 radio_index = ap_index % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +080019422
developera3511852023-06-14 14:12:59 +080019423 phyId = radio_index_to_phy(radio_index);
developer75bd10c2023-06-27 11:34:08 +080019424
19425 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
19426 if (os_snprintf_error(sizeof(cmd), res)) {
19427 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19428 return RETURN_ERR;
19429 }
developera3511852023-06-14 14:12:59 +080019430 _syscmd(cmd, buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +080019431 if (hal_strtoul(buf, 10, &tmp_u) < 0) {
19432 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
19433 return RETURN_ERR;
19434 }
19435 *numSessionReturned = tmp_u - 1;
19436
developera3511852023-06-14 14:12:59 +080019437 if (*numSessionReturned > maxNumberSessions)
19438 *numSessionReturned = maxNumberSessions;
19439 else if (*numSessionReturned < 1) {
19440 *numSessionReturned = 0;
19441 return RETURN_OK;
19442 }
developer72fb0bb2023-01-11 09:46:29 +080019443
developer75bd10c2023-06-27 11:34:08 +080019444 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
19445 if (os_snprintf_error(sizeof(cmd), res)) {
19446 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19447 return RETURN_ERR;
19448 }
developera3511852023-06-14 14:12:59 +080019449 if ((f = popen(cmd, "r")) == NULL) {
19450 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
19451 return RETURN_ERR;
19452 }
developer72fb0bb2023-01-11 09:46:29 +080019453
developera3511852023-06-14 14:12:59 +080019454 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
19455 while((fgets(line, sizeof(line), f)) != NULL) {
19456 char *tmp = NULL;
developer9ce44382023-06-28 11:09:37 +080019457 size_t len = strlen(line);
19458 strncpy(buf, line,len);
19459 buf[len] = '\0';
developera3511852023-06-14 14:12:59 +080019460 tmp = strtok(buf, " ");
developerd14dff12023-06-28 22:47:44 +080019461 if (tmp == NULL)
19462 break;
developerc14d83a2023-06-29 20:09:42 +080019463
19464 if (hal_strtoul(tmp, 10, &tmp_u) < 0) {
19465 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
19466 }
19467 twtSessions[index].numDevicesInSession = tmp_u;
developera3511852023-06-14 14:12:59 +080019468 tmp = strtok(NULL, " ");
developerd14dff12023-06-28 22:47:44 +080019469 if (tmp == NULL)
19470 break;
developerc14d83a2023-06-29 20:09:42 +080019471
19472 if (hal_strtoul(tmp, 10, &tmp_u) < 0) {
19473 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
19474 }
19475 twtSessions[index].twtParameters.operation.flowID = tmp_u;
developera3511852023-06-14 14:12:59 +080019476 tmp = strtok(NULL, " ");
19477 if (strstr(tmp, "t")) {
19478 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
19479 }
19480 if (strstr(tmp, "a")) {
19481 twtSessions[index].twtParameters.operation.announced = TRUE;
19482 }
19483 tmp = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080019484 if (tmp == NULL)
19485 continue;
developerc14d83a2023-06-29 20:09:42 +080019486
19487 if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
19488 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
19489 }
19490 exp = tmp_l;
19491
developera3511852023-06-14 14:12:59 +080019492 tmp = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080019493 if (tmp == NULL)
19494 continue;
developerc14d83a2023-06-29 20:09:42 +080019495 if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
19496 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
19497 return RETURN_ERR;
19498 }
19499 mantissa = tmp_l;
19500
developera3511852023-06-14 14:12:59 +080019501 tmp = strtok(NULL, " ");
developerc14d83a2023-06-29 20:09:42 +080019502
19503 if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
19504 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
19505 return RETURN_ERR;
19506 }
19507 duration = tmp_l;
developer72fb0bb2023-01-11 09:46:29 +080019508
developera3511852023-06-14 14:12:59 +080019509 // only implicit supported
19510 twtSessions[index].twtParameters.operation.implicit = TRUE;
19511 // only individual agreement supported
19512 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
developer72fb0bb2023-01-11 09:46:29 +080019513
developera3511852023-06-14 14:12:59 +080019514 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
19515 twt_wake_interval = mantissa * (1 << exp);
19516 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
19517 // Overflow handling
19518 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
19519 } else {
19520 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
19521 }
19522 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
19523 index++;
19524 }
developer72fb0bb2023-01-11 09:46:29 +080019525
developera3511852023-06-14 14:12:59 +080019526 pclose(f);
19527 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
19528 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019529}
developercc5cbfb2023-06-13 18:29:52 +080019530
19531INT wifi_enableGreylistAccessControl(BOOL enable)
19532{
19533 char inf_name[IFNAMSIZ] = {0};
19534 int if_idx, ret = 0;
19535 struct nl_msg *msg = NULL;
19536 struct nlattr * msg_data = NULL;
19537 struct mtk_nl80211_param param;
19538 struct unl unl_ins;
19539 unsigned short apIndex = 0;
19540
19541 for (apIndex = 0; apIndex < MAX_APS; apIndex++) {
19542 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
19543 continue;
19544
19545 if_idx = if_nametoindex(inf_name);
19546 if (!if_idx) {
19547 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
19548 continue;
19549 }
19550
19551 /*init mtk nl80211 vendor cmd*/
19552 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
19553 param.if_type = NL80211_ATTR_IFINDEX;
19554 param.if_idx = if_idx;
19555 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
19556 if (ret) {
19557 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
19558 return RETURN_ERR;
19559 }
19560
19561 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, enable == FALSE ? 0 : 1)) {
19562 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
19563 nlmsg_free(msg);
19564 mtk_nl80211_deint(&unl_ins);
19565 continue;
19566 }
19567
19568 /*send mtk nl80211 vendor msg*/
19569 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
19570 if (ret) {
19571 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
19572 mtk_nl80211_deint(&unl_ins);
19573 continue;
19574 }
19575 /*deinit mtk nl80211 vendor msg*/
19576 mtk_nl80211_deint(&unl_ins);
19577 wifi_debug(DEBUG_NOTICE, " %s cmd success.\n", inf_name);
19578 }
19579
19580 return RETURN_OK;
19581}