blob: 93fead0a2acf738c80aa78f8f14e0a2b14fbd300 [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>
developer33f13ba2023-07-12 16:19:06 +080075#include "secure_wrapper.h"
developercc5cbfb2023-06-13 18:29:52 +080076
developer72fb0bb2023-01-11 09:46:29 +080077#define MAC_ALEN 6
78
79#define MAX_BUF_SIZE 256
80#define MAX_CMD_SIZE 256
developerb149d9d2023-06-06 16:14:22 +080081#define MAX_SUB_CMD_SIZE 200
82
developer72fb0bb2023-01-11 09:46:29 +080083#define IF_NAME_SIZE 16
developera19a38f2023-11-27 19:30:48 +080084#define MAX_SSID_NAME_LEN 33
developer72fb0bb2023-01-11 09:46:29 +080085#define CONFIG_PREFIX "/nvram/hostapd"
86#define ACL_PREFIX "/nvram/hostapd-acl"
87#define DENY_PREFIX "/nvram/hostapd-deny"
88//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
89#define SOCK_PREFIX "/var/run/hostapd/wifi"
90#define VAP_STATUS_FILE "/nvram/vap-status"
91#define ESSID_FILE "/tmp/essid"
92#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
93#define CHANNEL_STATS_FILE "/tmp/channel_stats"
94#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
95#define VLAN_FILE "/nvram/hostapd.vlan"
96#define PSK_FILE "/nvram/hostapd"
97#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080098#define POWER_PERCENTAGE "/tmp/POWER"
99#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
100/*LOGAN_DAT_FILE: may be different on customer's platform.*/
developerc7adba42023-07-14 10:58:45 +0800101#ifdef WIFI_7992
102#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7992.b"
103#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7992.b"
104#else
developera1255e42023-05-13 17:45:02 +0800105#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +0800106#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developerc7adba42023-07-14 10:58:45 +0800107#endif
developera1255e42023-05-13 17:45:02 +0800108
developer9635f402023-12-25 19:48:21 +0800109#define SSID_ENABLE_CONFIG "/nvram/enable_ssid"
110
developer72fb0bb2023-01-11 09:46:29 +0800111#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +0800112#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +0800113
developer72fb0bb2023-01-11 09:46:29 +0800114#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +0800115#define BASE_PHY_INDEX 1
116#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +0800117
118/*
119 MAX_APS - Number of all AP available in system
120 2x Home AP
121 2x Backhaul AP
122 2x Guest AP
123 2x Secure Onboard AP
124 2x Service AP
125
126*/
127
developerbb9b20f2023-10-17 18:46:37 +0800128#define LOGAN_MAX_NUM_VAP_PER_RADIO (MAX_NUM_VAP_PER_RADIO > 16 ? 16 : MAX_NUM_VAP_PER_RADIO)
129#define MAX_APS MAX_NUM_RADIOS * LOGAN_MAX_NUM_VAP_PER_RADIO
developer7e4a2a62023-04-06 19:56:03 +0800130
131#define PREFIX_WIFI2G "ra"
132#define PREFIX_WIFI5G "rai"
133#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800134
developer47cc27a2023-05-17 23:09:58 +0800135#define PREFIX_SSID_2G "RDKB_2G"
136#define PREFIX_SSID_5G "RDKB_5G"
137#define PREFIX_SSID_6G "RDKB_6G"
developera73adb82023-11-13 14:09:37 +0800138#define PREFIX_SSID_MLD "MLD_GROUP"
139
developer47cc27a2023-05-17 23:09:58 +0800140
developer72fb0bb2023-01-11 09:46:29 +0800141#ifndef RADIO_PREFIX
142#define RADIO_PREFIX "wlan"
143#endif
144
145#define MAX_ASSOCIATED_STA_NUM 2007
146
147//Uncomment to enable debug logs
148//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800149enum {
150 DEBUG_OFF = 0,
151 DEBUG_ERROR = 1,
152 DEBUG_WARN = 2,
153 DEBUG_NOTICE = 3,
154 DEBUG_INFO = 4
155};
156int wifi_debug_level = DEBUG_NOTICE;
157#define wifi_debug(level, fmt, args...) \
158{ \
159 if (level <= wifi_debug_level) \
160 { \
developer2edaf012023-05-24 14:24:53 +0800161 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800162 } \
163}
developer72fb0bb2023-01-11 09:46:29 +0800164
developercd0b70a2023-12-11 11:25:50 +0800165#define wifi_assert(cond) \
166{\
167 if (!(cond)) {\
168 printf("!!!wifi hal assert!!!m %s %d\n", __func__, __LINE__);\
169 }\
170}
171
developer72fb0bb2023-01-11 09:46:29 +0800172#ifdef WIFI_DEBUG
173#define wifi_dbg_printf printf
174#define WIFI_ENTRY_EXIT_DEBUG printf
175#else
developer2f79c922023-06-02 17:33:42 +0800176#define wifi_dbg_printf(format, args...)
177#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
developer72fb0bb2023-01-11 09:46:29 +0800178#endif
179
180#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
181#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
182#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
183#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
184#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
185#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
186#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
187#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
188#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
189#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
190
191#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
192
193#define BW_FNAME "/nvram/bw_file.txt"
194
195#define PS_MAX_TID 16
196
developer96b38512023-02-22 11:17:45 +0800197#define MAX_CARD_INDEX 3
198
developer72fb0bb2023-01-11 09:46:29 +0800199static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
developera3511852023-06-14 14:12:59 +0800200 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
201 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
202 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
203 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
204 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
205 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
206 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
207 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
208 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
209 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
210 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
211 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
212 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
213 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
214 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
215 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
developer72fb0bb2023-01-11 09:46:29 +0800216};
217
218typedef unsigned long long u64;
219
220/* Enum to define WiFi Bands */
221typedef enum
222{
developera3511852023-06-14 14:12:59 +0800223 band_invalid = -1,
224 band_2_4 = 0,
225 band_5 = 1,
226 band_6 = 2,
developer72fb0bb2023-01-11 09:46:29 +0800227} wifi_band;
228
developer17038e62023-03-02 14:43:43 +0800229char* wifi_band_str[] = {
developera3511852023-06-14 14:12:59 +0800230 "2G",
231 "5G",
232 "6G",
developer17038e62023-03-02 14:43:43 +0800233};
234
developer72fb0bb2023-01-11 09:46:29 +0800235typedef enum {
developera3511852023-06-14 14:12:59 +0800236 WIFI_MODE_A = 0x01,
237 WIFI_MODE_B = 0x02,
238 WIFI_MODE_G = 0x04,
239 WIFI_MODE_N = 0x08,
240 WIFI_MODE_AC = 0x10,
241 WIFI_MODE_AX = 0x20,
242 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800243} wifi_ieee80211_Mode;
244
developer2f79c922023-06-02 17:33:42 +0800245typedef enum {
developera3511852023-06-14 14:12:59 +0800246 HT_BW_20,
247 HT_BW_40,
developer2f79c922023-06-02 17:33:42 +0800248} ht_config_bw;
developerd1824452023-05-18 12:30:04 +0800249
developer2f79c922023-06-02 17:33:42 +0800250typedef enum {
developera3511852023-06-14 14:12:59 +0800251 VHT_BW_2040,
252 VHT_BW_80,
253 VHT_BW_160,
254 VHT_BW_8080,
developer2f79c922023-06-02 17:33:42 +0800255} vht_config_bw;
developerd1824452023-05-18 12:30:04 +0800256
developer2f79c922023-06-02 17:33:42 +0800257typedef enum {
developera3511852023-06-14 14:12:59 +0800258 EHT_BW_20,
259 EHT_BW_40,
260 EHT_BW_80,
261 EHT_BW_160,
262 EHT_BW_320,
developer2f79c922023-06-02 17:33:42 +0800263} eht_config_bw;
developerd1824452023-05-18 12:30:04 +0800264
developer72fb0bb2023-01-11 09:46:29 +0800265#ifdef WIFI_HAL_VERSION_3
266
267// Return number of elements in array
268#ifndef ARRAY_SIZE
developera3511852023-06-14 14:12:59 +0800269#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
developer72fb0bb2023-01-11 09:46:29 +0800270#endif /* ARRAY_SIZE */
271
272#ifndef ARRAY_AND_SIZE
developera3511852023-06-14 14:12:59 +0800273#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
developer72fb0bb2023-01-11 09:46:29 +0800274#endif /* ARRAY_AND_SIZE */
275
developera3511852023-06-14 14:12:59 +0800276#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
developer72fb0bb2023-01-11 09:46:29 +0800277
278typedef struct {
developera3511852023-06-14 14:12:59 +0800279 int32_t value;
280 int32_t param;
281 intptr_t key;
282 intptr_t data;
developer72fb0bb2023-01-11 09:46:29 +0800283} wifi_secur_list;
284
developer0155a502023-06-19 20:33:57 +0800285typedef struct GNU_PACKED _wdev_extended_ap_metrics {
286 unsigned int uc_tx;
287 unsigned int uc_rx;
288 unsigned int mc_tx;
289 unsigned int mc_rx;
290 unsigned int bc_tx;
291 unsigned int bc_rx;
292} wdev_extended_ap_metric;
293
294typedef struct GNU_PACKED _wdev_ap_metric {
295 unsigned char bssid[6];
296 unsigned char cu;
297 unsigned char ESPI_AC[4][3];
298 wdev_extended_ap_metric ext_ap_metric;
299} wdev_ap_metric;
300
developer6c6ef372023-11-08 10:59:14 +0800301enum mld_type {
302 AP_MLD_SINGLE_LINK,
303 AP_MLD_MULTI_LINK,
304};
305
306struct multi_link_device {
307 unsigned char mld_mac[6];
308 unsigned char mld_index;
309// enum mld_type type;
310 unsigned char affiliated_ap_bitmap[6];
311};
312
313struct mld_configuration {
314 unsigned char valid_mld_bitmap[9];
315 struct multi_link_device mld[66]; /*0,65 - invalid, 1~16 multi-link mld, 17-64 single link mld*/
316};
317struct mld_configuration mld_config;
developer0155a502023-06-19 20:33:57 +0800318
developerc3556192023-12-06 17:59:09 +0800319wifi_hal_capability_t g_hal_cap;
320
developercd0b70a2023-12-11 11:25:50 +0800321static char l1profile[32] = "/etc/wireless/l1profile.dat";
322char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
323char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
324int g_phy_count = 0;
325#define MAX_SSID_LEN 64
326char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
327int radio_band[MAX_NUM_RADIOS];
328
329static void wifi_ParseProfile(void);
330
331static inline int get_runtime_max_radio(void)
332{
333 /*if rumtime maximun radio number is 0, reinit it.*/
334 wifi_assert(g_phy_count);
335 if(g_phy_count== 0)
336 wifi_ParseProfile();
developerc3556192023-12-06 17:59:09 +0800337
developercd0b70a2023-12-11 11:25:50 +0800338 return g_phy_count;
339}
developer72fb0bb2023-01-11 09:46:29 +0800340static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
341static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
developera3511852023-06-14 14:12:59 +0800342wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
343wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
344char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
developer72fb0bb2023-01-11 09:46:29 +0800345static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developerd14dff12023-06-28 22:47:44 +0800346static void wifi_PrepareDefaultHostapdConfigs(bool reset);
developer47cc27a2023-05-17 23:09:58 +0800347static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800348static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800349static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer2f79c922023-06-02 17:33:42 +0800350int hostapd_raw_add_bss(int apIndex);
351int hostapd_raw_remove_bss(int apIndex);
developerd14dff12023-06-28 22:47:44 +0800352INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size);
353
developer86035662023-06-28 19:21:12 +0800354static inline int hal_strtol(char *src, int base, long int *out)
355{
356 long int res = 0;
357 char *end_ptr = NULL;
358
359 errno = 0;
360 res = strtol(src, &end_ptr, base);
361
362 if ((errno == ERANGE && (res == LONG_MIN || res == LONG_MAX))
developer5fbf2ff2023-06-30 10:51:56 +0800363 || (errno != 0 && res == 0) || /*ignore end_ptr!=0 error*/ /**end_ptr != '\0' ||*/src == end_ptr ) {
364 *out = res;
developer86035662023-06-28 19:21:12 +0800365 return -1;
developer5fbf2ff2023-06-30 10:51:56 +0800366 } else
developer86035662023-06-28 19:21:12 +0800367 *out = res;
368
369 return 0;
370}
371
372static inline int hal_strtoul(char *src, int base, unsigned long *out)
373{
374 unsigned long res = 0;
375 char *end_ptr = NULL;
376
377 errno = 0;
378 res = strtoul(src, &end_ptr, base);
379
380 if ((errno == ERANGE && res == ULONG_MAX)
developer5fbf2ff2023-06-30 10:51:56 +0800381 || (errno != 0 && res == 0) || /*ignore end_ptr!=0 error*/ /**end_ptr != '\0' ||*/src == end_ptr ) {
382 *out = res;
developer86035662023-06-28 19:21:12 +0800383 return -1;
developer5fbf2ff2023-06-30 10:51:56 +0800384 } else
developer86035662023-06-28 19:21:12 +0800385 *out = res;
386
387 return 0;
388}
developer47cc27a2023-05-17 23:09:58 +0800389
developercc5cbfb2023-06-13 18:29:52 +0800390static inline int os_snprintf_error(size_t size, int res)
391{
392 return res < 0 || (unsigned int) res >= size;
393}
394
developer49b17232023-05-19 16:35:19 +0800395/*type define the nl80211 call back func*/
396typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
397
398/**
399*struct mtk_nl80211_param
400* init mtk nl80211 using parameters
401* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
402* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
403* @if_idx: the index should match the interface or wiphy.
404* Note: NA
405**/
406struct mtk_nl80211_param {
407 unsigned int sub_cmd;
408 int if_type;
409 int if_idx;
410};
411
412/**
developer121a8e72023-05-22 09:19:39 +0800413*struct mtk_nl80211_cb_data
414* init mtk nl80211 call back parameters
415* @out_buf: store the mtk vendor output msg for wifi hal buffer.
416* @out_len: the output buffer length.
417* Note: NA
418**/
419struct mtk_nl80211_cb_data {
420 char * out_buf;
421 unsigned int out_len;
422};
423
424/**
developer49b17232023-05-19 16:35:19 +0800425*mtk_nl80211_init
426* init mtk nl80211 netlink and init the vendor msg common part.
427* @nl: netlink, just init it.
428* @msg: netlink message will alloc it.
429* the msg send success/fails is not free by app
430* only the nla_put etc api fails should use nlmsg_free.
431* @msg_data: vendor data msg attr pointer.
432* @param: init using interface and sub_cmd parameter.
433*
434*init the netlink context and mtk netlink vendor msg.
435*
436*return:
437* 0: success
438* other: fail
439**/
440
441int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
442 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
443 /*sanity check here*/
444 if (!nl || !param) {
445 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800446 "[%s][%d]:nl(%p) or param(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800447 __func__, __LINE__, nl, param);
448 return -1;
449 }
450 /*if_type check*/
451 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
452 (void)fprintf(stderr,
453 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
454 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
455 return -1;
456 }
457 /*init the nl*/
458 if (unl_genl_init(nl, "nl80211") < 0) {
459 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
460 __func__, __LINE__);
461 return -1;
462 }
463 /*init the msg*/
464 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
465
466 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
developera3511852023-06-14 14:12:59 +0800467 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
468 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
developer49b17232023-05-19 16:35:19 +0800469 (void)fprintf(stderr,
470 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
471 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
472 goto err;
473 }
474
475 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
476 if (!*msg_data) {
477 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
478 __func__, __LINE__);
479 goto err;
480 }
481
482 return 0;
483err:
developer49b17232023-05-19 16:35:19 +0800484 nlmsg_free(*msg);
485 unl_free(nl);
486 return -1;
487}
488
489/**
490*mtk_nl80211_send
491* set the vendor cmd call back and sent the vendor msg.
492* @nl: netlink.
493* @msg: netlink message.
494* @msg_data: vendor data msg attr pointer.
495* @handler: if the msg have call back shoud add the call back func
496* the event msg will handle by the call back func(exp:get cmd)
497* other set it as NULL(exp:set cmd).
498* @arg:call back func arg parameter.
499*add end of the netlink msg, set the call back and send msg
500*
501*return:
502* 0: success
503* other: fail
504**/
505int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
506 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
507 int ret = 0;
508 /*sanity check*/
509 if (!nl || !msg || !msg_data) {
510 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800511 "[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800512 __func__, __LINE__, nl, msg, msg_data);
513 return -1;
514 }
515 /*end the msg attr of vendor data*/
516 nla_nest_end(msg, msg_data);
517 /*send the msg and set call back */
518 ret = unl_genl_request(nl, msg, handler, arg);
519 if (ret)
520 (void)fprintf(stderr, "send nl80211 cmd fails\n");
521 return ret;
522}
523
524/**
525*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800526* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800527* @nl: netlink.
528*
developer2edaf012023-05-24 14:24:53 +0800529*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800530*
531*return:
532* 0: success
533**/
534
535int mtk_nl80211_deint(struct unl *nl) {
536 unl_free(nl);
537 return 0;
538}
539
developer72fb0bb2023-01-11 09:46:29 +0800540wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
541{
developera3511852023-06-14 14:12:59 +0800542 wifi_secur_list *item;
543 int i;
developer72fb0bb2023-01-11 09:46:29 +0800544
developera3511852023-06-14 14:12:59 +0800545 for (item = list,i = 0;i < list_sz; item++, i++) {
546 if ((int)(item->key) == key) {
547 return item;
548 }
549 }
developer72fb0bb2023-01-11 09:46:29 +0800550
developera3511852023-06-14 14:12:59 +0800551 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800552}
553
554char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
555{
developera3511852023-06-14 14:12:59 +0800556 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
developer72fb0bb2023-01-11 09:46:29 +0800557
developera3511852023-06-14 14:12:59 +0800558 if (!item) {
559 return "";
560 }
developer72fb0bb2023-01-11 09:46:29 +0800561
developera3511852023-06-14 14:12:59 +0800562 return (char *)(item->data);
developer72fb0bb2023-01-11 09:46:29 +0800563}
564
565wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
566{
developera3511852023-06-14 14:12:59 +0800567 wifi_secur_list *item;
568 int i;
developer72fb0bb2023-01-11 09:46:29 +0800569
developera3511852023-06-14 14:12:59 +0800570 for (item = list,i = 0;i < list_sz; item++, i++) {
571 if (strcmp((char *)(item->data), str) == 0) {
572 return item;
573 }
574 }
developer72fb0bb2023-01-11 09:46:29 +0800575
developera3511852023-06-14 14:12:59 +0800576 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800577}
578#endif /* WIFI_HAL_VERSION_3 */
579
developer6c6ef372023-11-08 10:59:14 +0800580#define _syscmd_secure(retBuf, retBufSize, fmt, args...) \
581 ({ \
582 FILE *f; \
583 char *ptr = retBuf; \
584 int bufSize = retBufSize, bufbytes = 0, readbytes = 0, cmd_ret = -1; \
585 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); \
586 f = v_secure_popen("r", fmt, ##args); \
587 if(f) { \
588 while(!feof(f)) \
589 { \
590 *ptr = 0; \
591 if(bufSize>=128) { \
592 bufbytes=128; \
593 } else { \
594 bufbytes=bufSize-1; \
595 } \
596 if (fgets(ptr,bufbytes,f) == NULL) \
597 break; \
598 readbytes=strlen(ptr); \
599 if(!readbytes) \
600 break; \
601 bufSize-=readbytes; \
602 ptr += readbytes; \
603 } \
604 cmd_ret = v_secure_pclose(f); \
605 retBuf[retBufSize-1]=0; \
606 } \
607 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); \
608 cmd_ret; \
609 })
610
developerb717e062023-11-17 14:13:19 +0800611typedef enum _RT_802_11_PHY_MODE {
612 PHY_11BG_MIXED = 0,
613 PHY_11B = 1,
614 PHY_11A = 2,
615 PHY_11ABG_MIXED = 3,
616 PHY_11G = 4,
617 PHY_11ABGN_MIXED = 5, /* both band 5 */
618 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
619 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
620 PHY_11AN_MIXED = 8, /* 5G band 8 */
621 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
622 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
623 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
624 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
625 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
626 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
627 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
628 PHY_11AX_24G = 16,
629 PHY_11AX_5G = 17,
630 PHY_11AX_6G = 18,
631 PHY_11AX_24G_6G = 19,
632 PHY_11AX_5G_6G = 20,
633 PHY_11AX_24G_5G_6G = 21,
634 PHY_11BE_24G = 22,
635 PHY_11BE_5G = 23,
636 PHY_11BE_6G = 24,
637 PHY_11BE_24G_6G = 25,
638 PHY_11BE_5G_6G = 26,
639 PHY_11BE_24G_5G_6G = 27,
640 PHY_MODE_MAX,
641} RT_802_11_PHY_MODE;
642
643enum WIFI_MODE {
644 WMODE_INVALID = 0,
645 WMODE_A = 1 << 0,
646 WMODE_B = 1 << 1,
647 WMODE_G = 1 << 2,
648 WMODE_GN = 1 << 3,
649 WMODE_AN = 1 << 4,
650 WMODE_AC = 1 << 5,
651 WMODE_AX_24G = 1 << 6,
652 WMODE_AX_5G = 1 << 7,
653 WMODE_AX_6G = 1 << 8,
654 WMODE_BE_24G = 1 << 9,
655 WMODE_BE_5G = 1 << 10,
656 WMODE_BE_6G = 1 << 11,
657 /*
658 * total types of supported wireless mode,
659 * add this value once yow add new type
660 */
661 WMODE_COMP = 12,
662};
663
664static unsigned int CFG_WMODE_MAP[] = {
665 PHY_11BG_MIXED, (WMODE_B | WMODE_G), /* 0 => B/G mixed */
666 PHY_11B, (WMODE_B), /* 1 => B only */
667 PHY_11A, (WMODE_A), /* 2 => A only */
668 PHY_11ABG_MIXED, (WMODE_A | WMODE_B | WMODE_G), /* 3 => A/B/G mixed */
669 PHY_11G, WMODE_G, /* 4 => G only */
670 PHY_11ABGN_MIXED, (WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN), /* 5 => A/B/G/GN/AN mixed */
671 PHY_11N_2_4G, (WMODE_GN), /* 6 => N in 2.4G band only */
672 PHY_11GN_MIXED, (WMODE_G | WMODE_GN), /* 7 => G/GN, i.e., no CCK mode */
673 PHY_11AN_MIXED, (WMODE_A | WMODE_AN), /* 8 => A/N in 5 band */
674 PHY_11BGN_MIXED, (WMODE_B | WMODE_G | WMODE_GN), /* 9 => B/G/GN mode*/
675 PHY_11AGN_MIXED, (WMODE_G | WMODE_GN | WMODE_A | WMODE_AN), /* 10 => A/AN/G/GN mode, not support B mode */
676 PHY_11N_5G, (WMODE_AN), /* 11 => only N in 5G band */
677 PHY_11VHT_N_ABG_MIXED, (WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN | WMODE_AC), /* 12 => B/G/GN/A/AN/AC mixed*/
678 PHY_11VHT_N_AG_MIXED, (WMODE_G | WMODE_GN | WMODE_A | WMODE_AN | WMODE_AC), /* 13 => G/GN/A/AN/AC mixed, no B mode */
679 PHY_11VHT_N_A_MIXED, (WMODE_A | WMODE_AN | WMODE_AC), /* 14 => A/AC/AN mixed */
680 PHY_11VHT_N_MIXED, (WMODE_AN | WMODE_AC), /* 15 => AC/AN mixed, but no A mode */
681 PHY_11AX_24G, (WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G),
682 PHY_11AX_5G, (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G),
683 PHY_11AX_6G, (WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G),
684 PHY_11AX_24G_6G, (WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_AX_6G),
685 PHY_11AX_5G_6G, (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G),
686 PHY_11AX_24G_5G_6G, (WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_A |
687 WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G),
688 PHY_11BE_24G,
689 (WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_BE_24G),
690 PHY_11BE_5G,
691 (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_BE_5G),
692 PHY_11BE_6G,
693 (WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G | WMODE_BE_6G),
694 PHY_11BE_24G_6G,
695 (WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_AX_6G
696 | WMODE_BE_24G | WMODE_BE_6G),
697 PHY_11BE_5G_6G,
698 (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G
699 | WMODE_BE_5G | WMODE_BE_6G),
700 PHY_11BE_24G_5G_6G,
701 (WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_A
702 | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G
703 | WMODE_BE_24G | WMODE_BE_5G | WMODE_BE_6G),
704
705 PHY_MODE_MAX, WMODE_INVALID /* default phy mode if not match */
706};
707
708#define WMODE_CAP_6G(_x) \
709(((_x) & (WMODE_AX_6G | WMODE_BE_6G)) != 0)
710#define WMODE_CAP_5G(_x) \
711(((_x) & (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_BE_5G)) != 0)
712#define WMODE_CAP_2G(_x) \
713(((_x) & (WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_BE_24G)) != 0)
714
developer9635f402023-12-25 19:48:21 +0800715static BOOL is_main_vap_index(int vap_index);
developerc3556192023-12-06 17:59:09 +0800716static int array_index_to_vap_index(UINT radioIndex, int arrayIndex, int *vap_index);
717static int vap_index_to_radio_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
developer6c6ef372023-11-08 10:59:14 +0800718static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size);
719int hwaddr_aton2(const char *txt, unsigned char *addr);
720static int wifi_GetInterfaceName(int apIndex, char *interface_name);
721INT wifi_getMaxRadioNumber(INT *max_radio_num);
722static int wifi_BandProfileRead(int card_idx,
723 int radio_idx,
724 char *param,
725 char *output,
726 int output_size,
727 char *default_value);
developerc3556192023-12-06 17:59:09 +0800728static int array_index_to_vap_index(UINT radioIndex, int arrayIndex, int *vap_index);
developer6c6ef372023-11-08 10:59:14 +0800729struct params
730{
731 char * name;
732 char * value;
733};
734static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count);
735
developerb57e9a82023-11-22 18:29:55 +0800736int get_bandwidth_handler(struct nl_msg *msg, void *data);
737
738INT mtk_wifi_get_radio_info(
739 INT radioIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, void *output);
740
741
developer6c6ef372023-11-08 10:59:14 +0800742#ifdef WIFI_HAL_VERSION_3
743#define MAX_ML_MLD_CNT 16 /*Max multi-link MLD*/
744//#define MAX_SL_MLD_CNT 48 /*MAX single-link MLD*/
745
746static void mld_set(unsigned char mld_index, unsigned char set)
747{
developerb340de62023-11-22 20:10:05 +0800748 if (set)
749 mld_config.valid_mld_bitmap[mld_index / 8] |= (1 << (mld_index % 8));
750 else
751 mld_config.valid_mld_bitmap[mld_index / 8] &= ~(1 << (mld_index % 8));
developer6c6ef372023-11-08 10:59:14 +0800752}
753
754static unsigned char mld_test(unsigned char mld_index)
755{
756 return mld_config.valid_mld_bitmap[mld_index / 8] & (1 << (mld_index % 8));
757}
758
759static void mld_ap_set(struct multi_link_device *mld, unsigned char ap_index, unsigned char set)
760{
developerb340de62023-11-22 20:10:05 +0800761 if (set)
762 mld->affiliated_ap_bitmap[ap_index / 8] |= (1 << (ap_index % 8));
763 else
764 mld->affiliated_ap_bitmap[ap_index / 8] &= ~(1 << (ap_index % 8));
developer6c6ef372023-11-08 10:59:14 +0800765}
766
767static unsigned char mld_ap_test(struct multi_link_device *mld, unsigned char ap_index)
768{
769 return mld->affiliated_ap_bitmap[ap_index / 8] & (1 << (ap_index % 8));
770}
771
developer8d7c57e2023-11-30 10:49:08 +0800772int ml_info_callback(struct nl_msg *msg, void *data) {
773 struct nlattr *tb[NL80211_ATTR_MAX + 1];
774 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO_ATTR_MAX + 1];
775 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
776 int err = 0;
777
778 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
779 genlmsg_attrlen(gnlh, 0), NULL);
780 if (err < 0){
781 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
782 return err;
783 }
784
785 if (tb[NL80211_ATTR_VENDOR_DATA]) {
786 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO_ATTR_MAX,
787 tb[NL80211_ATTR_VENDOR_DATA], NULL);
788 if (err < 0){
789 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO fails\n");
790 return err;
791 }
792
793 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO]) {
794 if ((size_t)nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO]) !=
795 sizeof(struct bss_mlo_info)) {
796 wifi_debug(DEBUG_ERROR, "wrong mlo info from driver\n");
797 return -1;
798 }
799 memcpy(data, nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO]), sizeof(struct bss_mlo_info));
800 } else
801 return -1;
802 }
803
804 return 0;
805}
806
807static INT eht_mld_nl80211_get_bss_mlo_info(INT apIndex, struct bss_mlo_info *ml_info)
808{
809 char inf_name[IF_NAME_SIZE] = {0};
810 unsigned int if_idx = 0;
811 int ret = -1;
812 struct unl unl_ins;
813 struct nl_msg *msg = NULL;
814 struct nlattr * msg_data = NULL;
815 struct mtk_nl80211_param param;
816
817 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
818 return RETURN_ERR;
819 if_idx = if_nametoindex(inf_name);
820
821 /*init mtk nl80211 vendor cmd*/
822 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_BSS_MLO_INFO;
823 param.if_type = NL80211_ATTR_IFINDEX;
824 param.if_idx = if_idx;
825
826 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
827 if (ret) {
828 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
829 return RETURN_ERR;
830 }
831 /*add mtk vendor cmd data*/
832 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO)) {
833 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO);
834 nlmsg_free(msg);
835 goto err;
836 }
837
838 /*send mtk nl80211 vendor msg*/
839 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, ml_info_callback, (void*)ml_info);
840 if (ret) {
841 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
842 goto err;
843 }
844 /*deinit mtk nl80211 vendor msg*/
845 mtk_nl80211_deint(&unl_ins);
846 wifi_debug(DEBUG_INFO,"send cmd success\n");
847 return RETURN_OK;
848err:
849 mtk_nl80211_deint(&unl_ins);
850 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
851 return RETURN_ERR;
852}
853
developer6c6ef372023-11-08 10:59:14 +0800854static int eht_mld_config_init(void)
855{
developer8d7c57e2023-11-30 10:49:08 +0800856 char config_file[128] = {0}, str_mldgroup[256];
developer6c6ef372023-11-08 10:59:14 +0800857 int res, band, bss_idx;
858 char *token;
859 long mld_index;
860 unsigned char ap_index;
developerc3556192023-12-06 17:59:09 +0800861 int vap_idx;
developer6c6ef372023-11-08 10:59:14 +0800862 struct multi_link_device *mld;
developer8d7c57e2023-11-30 10:49:08 +0800863 BOOL ap_enable = 0;
864 struct bss_mlo_info ml_info;
developer6c6ef372023-11-08 10:59:14 +0800865
developer6c6ef372023-11-08 10:59:14 +0800866 wifi_debug(DEBUG_ERROR, "==========>\n");
867
868 memset(&mld_config, 0, sizeof(mld_config));
developercd0b70a2023-12-11 11:25:50 +0800869 for (band = 0; band < get_runtime_max_radio(); band++) {
developer6c6ef372023-11-08 10:59:14 +0800870 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
871 if (os_snprintf_error(sizeof(config_file), res)) {
872 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer6c6ef372023-11-08 10:59:14 +0800873 return RETURN_ERR;
874 }
875
876 wifi_datfileRead(config_file, "MldGroup", str_mldgroup, sizeof(str_mldgroup));
877 token = strtok(str_mldgroup, ";");
878 bss_idx = 0;
879 while(token != NULL && bss_idx < 16) {
880 if (hal_strtol(token, 10, &mld_index) < 0) {
881 wifi_debug(DEBUG_ERROR, "strtol fail\n");
882 break;
883 }
884
885 if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
886 wifi_debug(DEBUG_ERROR, "invalid mld_index %ld, skip it.\n", mld_index);
887 bss_idx++;
888 token = strtok(NULL, ";");
889 continue;
890 }
891
892 mld_set(mld_index, 1);
developerc3556192023-12-06 17:59:09 +0800893 if (array_index_to_vap_index(band, bss_idx, &vap_idx) != RETURN_OK) {
894 wifi_debug(DEBUG_ERROR, "invalid band %d, bss_idx %d, skip it.\n", band, bss_idx);
895 continue;
896 }
897 ap_index = vap_idx;
developer6c6ef372023-11-08 10:59:14 +0800898 mld = &(mld_config.mld[mld_index]);
899 mld->mld_index = mld_index;
developer6c6ef372023-11-08 10:59:14 +0800900// mld->type = mld_index <= MAX_ML_MLD_CNT ? AP_MLD_MULTI_LINK : AP_MLD_SINGLE_LINK;
901 mld_ap_set(mld, ap_index, 1);
902 bss_idx++;
903 token = strtok(NULL, ";");
904 wifi_debug(DEBUG_ERROR, "mld[%ld] affiliated ap[%d].\n", mld_index, ap_index);
905 }
906 }
907
developer8d7c57e2023-11-30 10:49:08 +0800908 for (ap_index = 0; ap_index < MAX_APS; ap_index++) {
909 if (wifi_getApEnable(ap_index, &ap_enable) != RETURN_OK)
910 continue;
developer6c6ef372023-11-08 10:59:14 +0800911
developer8d7c57e2023-11-30 10:49:08 +0800912 if (!ap_enable)
developer6c6ef372023-11-08 10:59:14 +0800913 continue;
developer6c6ef372023-11-08 10:59:14 +0800914
developer8d7c57e2023-11-30 10:49:08 +0800915 memset(&ml_info, 0, sizeof(ml_info));
916 if (eht_mld_nl80211_get_bss_mlo_info(ap_index, &ml_info) != RETURN_OK) {
917 wifi_debug(DEBUG_ERROR, "fail to get bss[%d] ml info\n", ap_index);
918 continue;
developer6c6ef372023-11-08 10:59:14 +0800919 }
920
developer8d7c57e2023-11-30 10:49:08 +0800921 if (ml_info.mld_grp_idx == 0 || ml_info.mld_grp_idx > MAX_ML_MLD_CNT) {
922 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", ml_info.mld_grp_idx);
923 continue;
developer6c6ef372023-11-08 10:59:14 +0800924 }
925
developer8d7c57e2023-11-30 10:49:08 +0800926 if (!mld_test(ml_info.mld_grp_idx)) {
927 wifi_debug(DEBUG_ERROR, "!!mld(%d) is not obvoiusly config in dat file, skip it.",
928 ml_info.mld_grp_idx);
929 continue;
developer6c6ef372023-11-08 10:59:14 +0800930 }
developer8d7c57e2023-11-30 10:49:08 +0800931 wifi_debug(DEBUG_ERROR, "!Successfully get bss[%d] ml info from driver, mld_grp_idx=%d"
932 "mld_addr=%02x:%02x:%02x:%02x:%02x:%02x\n", ap_index, ml_info.mld_grp_idx,
933 ml_info.addr[0], ml_info.addr[1], ml_info.addr[2], ml_info.addr[3], ml_info.addr[4],
934 ml_info.addr[5]);
935 mld = &(mld_config.mld[ml_info.mld_grp_idx]);
936 memcpy(mld->mld_mac, ml_info.addr, sizeof(mld->mld_mac));
developer6c6ef372023-11-08 10:59:14 +0800937 }
developer6c6ef372023-11-08 10:59:14 +0800938
developer6c6ef372023-11-08 10:59:14 +0800939 return RETURN_OK;
940}
941
942static unsigned char mld_ap_test_all_mlds(unsigned char ap_index)
943{
944 unsigned char mld_index;
945 struct multi_link_device *mld;
946
947 for (mld_index = 1; mld_index <= MAX_ML_MLD_CNT; mld_index++) {
948
949 if (!mld_test(mld_index))
950 continue;
951
952 mld = &(mld_config.mld[mld_index]);
953
954 if (mld_ap_test(mld, ap_index))
955 return mld_index;
956 }
957
958 return 0;
959}
960
961static void mld_info_display(void)
962{
963 unsigned char mld_index, ap_index;
964 struct multi_link_device *mld;
965 char interface_name[IF_NAME_SIZE] = {0};
966
967 wifi_debug(DEBUG_ERROR, "==========>\n");
968 for (mld_index = 1; mld_index <= MAX_ML_MLD_CNT; mld_index++) {
969 if (!mld_test(mld_index))
970 continue;
971
972 mld = &(mld_config.mld[mld_index]);
973
974 printf("MLD[%02d]: %02x:%02x:%02x:%02x:%02x:%02x\n\tAffiliated AP:\n", (int)(mld->mld_index),
975 mld->mld_mac[0], mld->mld_mac[1], mld->mld_mac[2],
976 mld->mld_mac[3], mld->mld_mac[4], mld->mld_mac[5]);
977
978 for (ap_index = 0; ap_index <= MAX_APS; ap_index++) {
979 if (!mld_ap_test(mld, ap_index))
980 continue;
981 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
982 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
983 continue;
984 }
985 printf("\tap[%d] %s\n", (int)ap_index, interface_name);
986 }
987 }
988 wifi_debug(DEBUG_ERROR, "<==========\n");
989}
990
991INT wifi_eht_create_ap_mld(unsigned char mld_index, unsigned char *mac)
992{
993 int res;
994// enum mld_type type;
995 struct multi_link_device *mld;
996
997// if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
998 if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
999 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
1000 return RETURN_ERR;
1001 }
1002
1003 if (mld_test(mld_index)) {
1004 wifi_debug(DEBUG_ERROR, "mld already exist with mld_index %d\n", mld_index);
1005 return RETURN_ERR;
1006 }
1007
1008// type = mld_index <= MAX_ML_MLD_CNT ? AP_MLD_MULTI_LINK : AP_MLD_SINGLE_LINK;
1009
1010 res = v_secure_system("mwctl ra0 set apmld=create:group=%u,addr=%02x:%02x:%02x:%02x:%02x:%02x",
1011 mld_index, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1012
1013 if (res) {
1014 wifi_debug(DEBUG_ERROR, "fail to create mld with mld_index %d\n", mld_index);
1015 return RETURN_ERR;
1016 }
1017
1018 mld_set(mld_index, 1);
1019
1020 mld = &(mld_config.mld[mld_index]);
1021 mld->mld_index = mld_index;
1022 memcpy(mld->mld_mac, mac, sizeof(mld->mld_mac));
1023// mld->type = type;
1024 memset(mld->affiliated_ap_bitmap, 0, sizeof(mld->affiliated_ap_bitmap));
1025
1026 return RETURN_OK;
1027
1028}
1029
1030INT wifi_eht_destroy_ap_mld(unsigned char mld_index)
1031{
1032 int res;
1033 struct multi_link_device *mld;
1034
1035// if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
1036 if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
1037 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
1038 return RETURN_ERR;
1039 }
1040
1041 if (!mld_test(mld_index)) {
1042 wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
1043 return RETURN_ERR;
1044 }
1045
1046 res = v_secure_system("mwctl ra0 set apmld=destroy:group=%u", mld_index);
1047
1048 if (res) {
1049 wifi_debug(DEBUG_ERROR, "fail to destroy mld with mld_index %d\n", mld_index);
1050 return RETURN_ERR;
1051 }
1052
1053 mld_set(mld_index, 0);
1054 mld = &(mld_config.mld[mld_index]);
1055 memset(mld, 0, sizeof(*mld));
1056
1057 return RETURN_OK;
1058}
1059
1060INT wifi_eht_list_ap_mld(unsigned char mld_index[], unsigned char *mld_num)
1061{
1062 unsigned char i, j = 0;
1063
1064// for (i = 1; i <= (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT); i++) {
1065 for (i = 1; i <= MAX_ML_MLD_CNT; i++) {
1066 if (mld_test(i))
1067 mld_index[j++] = i;
1068 }
1069
1070 *mld_num = j;
1071
1072 return RETURN_OK;
1073}
1074
1075INT wifi_eht_add_to_ap_mld(unsigned char mld_index, INT ap_index)
1076{
developerc3556192023-12-06 17:59:09 +08001077 int res, radio1, radio2, bss_idx;
developer6c6ef372023-11-08 10:59:14 +08001078// enum mld_type type;
1079 struct multi_link_device *mld;
1080 char interface_name[IF_NAME_SIZE] = {0};
1081 unsigned char i;
developer6c6ef372023-11-08 10:59:14 +08001082
1083 if (ap_index < 0 || ap_index >= MAX_APS) {
1084 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
1085 return RETURN_ERR;
1086 }
1087
1088 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
1089 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
1090 return RETURN_ERR;
1091 }
1092
1093// if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
1094 if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
1095 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
1096 return RETURN_ERR;
1097 }
1098
1099 if (!mld_test(mld_index)) {
1100 wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
1101 return RETURN_ERR;
1102 }
1103
1104 mld = &(mld_config.mld[mld_index]);
1105#if 0
1106 if (mld->type == AP_MLD_SINGLE_LINK) {
1107 /*check single link mld is not occupied by other ap*/
1108 for (i = 0; i < MAX_APS; i++) {
1109 if(mld_ap_test(mld, i))
1110 break;
1111 }
1112
1113 if (i < MAX_APS) {
1114 if (i == ap_index) {
1115 wifi_debug(DEBUG_ERROR, "current ap(%d) has already joined single link mld(%d)\n", i, mld_index);
1116 return RETURN_OK;
1117 }
1118 wifi_debug(DEBUG_ERROR,
1119 "single link mld(%d) already has an affiliated AP(ap_index %d)\n", mld_index, i);
1120 return RETURN_ERR;
1121 }
1122 } else if (mld->type == AP_MLD_MULTI_LINK) {
1123#endif
1124 /*check if a same band ap already has been joined before*/
developer6c6ef372023-11-08 10:59:14 +08001125 for (i = 0; i < MAX_APS; i++) {
1126 if(mld_ap_test(mld, i)) {
1127 if (i == ap_index) {
1128 wifi_debug(DEBUG_ERROR, "current ap(index=%d) has already joined current mld\n", i);
1129 return RETURN_OK;
1130 }
developerc3556192023-12-06 17:59:09 +08001131
1132 if (vap_index_to_radio_array_index(i, &radio1, &bss_idx) != RETURN_OK) {
1133 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
1134 return RETURN_ERR;
1135 }
1136
1137 if (vap_index_to_radio_array_index(ap_index, &radio2, &bss_idx) != RETURN_OK) {
1138 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
1139 return RETURN_ERR;
1140 }
1141
1142 if (radio1 == radio2) {
developer6c6ef372023-11-08 10:59:14 +08001143 wifi_debug(DEBUG_ERROR, "same band ap(index=%d) has already joined current mld\n", i);
1144 return RETURN_ERR;
1145 }
1146 }
1147 }
1148
1149 res = v_secure_system("mwctl %s set apmld=addlink:group=%u", interface_name, mld_index);
1150
1151 if (res) {
1152 wifi_debug(DEBUG_ERROR, "fail to add ap to ap mld with mld_index %d\n", mld_index);
1153 return RETURN_ERR;
1154 }
1155
1156 mld_ap_set(mld, ap_index, 1);
developer17038e62023-03-02 14:43:43 +08001157
developer6c6ef372023-11-08 10:59:14 +08001158 return RETURN_OK;
1159}
1160
1161INT wifi_eht_remove_from_ap_mld(unsigned char mld_index, INT ap_index)
1162{
1163 int res;
1164// enum mld_type type;
1165 struct multi_link_device *mld;
1166 char interface_name[IF_NAME_SIZE] = {0};
1167
1168 if (ap_index < 0 || ap_index >= MAX_APS) {
1169 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
1170 return RETURN_ERR;
1171 }
1172
1173 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
1174 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
1175 return RETURN_ERR;
1176 }
1177
1178// if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
1179 if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
1180 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
1181 return RETURN_ERR;
1182 }
1183
1184 if (!mld_test(mld_index)) {
1185 wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
1186 return RETURN_ERR;
1187 }
1188
1189 mld = &(mld_config.mld[mld_index]);
1190
developerb340de62023-11-22 20:10:05 +08001191 res = v_secure_system("mwctl %s set apmld=dellink", interface_name);
developer6c6ef372023-11-08 10:59:14 +08001192
1193 if (res) {
1194 wifi_debug(DEBUG_ERROR, "fail to del ap from ap mld with mld_index %d\n", mld_index);
1195 return RETURN_ERR;
1196 }
1197
1198 mld_ap_set(mld, ap_index, 0);
1199
1200 return RETURN_OK;
1201}
1202
1203INT wifi_eht_get_ap_from_mld(unsigned char mld_index, unsigned char ap_index[], unsigned char *ap_num)
1204{
1205 unsigned char i, j = 0;
1206 struct multi_link_device *mld;
1207
1208// if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
1209 if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
1210 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
1211 return RETURN_ERR;
1212 }
1213
1214 if (!mld_test(mld_index)) {
1215 wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
1216 return RETURN_ERR;
1217 }
1218
1219 mld = &(mld_config.mld[mld_index]);
1220
1221 for (i = 0; i < MAX_APS; i++) {
1222 if (mld_ap_test(mld, i))
1223 ap_index[j++] = i;
1224 }
1225
1226 *ap_num = j;
1227
1228 return RETURN_OK;
1229}
1230
1231INT wifi_eht_mld_ap_transfer(unsigned char old_mld_index,
1232 unsigned char new_mld_index, INT ap_index)
1233{
developerc3556192023-12-06 17:59:09 +08001234 int res, radio1, radio2, bss_idx;
developer6c6ef372023-11-08 10:59:14 +08001235// enum mld_type type;
1236 struct multi_link_device *mld, *old_mld;
1237 char interface_name[IF_NAME_SIZE] = {0};
1238 unsigned char i;
developer6c6ef372023-11-08 10:59:14 +08001239
1240 if (old_mld_index == new_mld_index) {
1241 wifi_debug(DEBUG_ERROR, "same mld index %d\n", new_mld_index);
1242 return RETURN_OK;
1243 }
1244
1245 if (ap_index < 0 || ap_index >= MAX_APS) {
1246 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
1247 return RETURN_ERR;
1248 }
1249
1250 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
1251 wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
1252 return RETURN_ERR;
1253 }
1254
1255 if (old_mld_index == 0 || old_mld_index > MAX_ML_MLD_CNT) {
1256 wifi_debug(DEBUG_ERROR, "invalid old_mld_index %d\n", old_mld_index);
1257 return RETURN_ERR;
1258 }
developerb340de62023-11-22 20:10:05 +08001259 old_mld = &(mld_config.mld[old_mld_index]);
developer6c6ef372023-11-08 10:59:14 +08001260
1261 if (!mld_test(old_mld_index)) {
1262 wifi_debug(DEBUG_ERROR, "mld does not exist with old_mld_index %d\n", old_mld_index);
1263 return RETURN_ERR;
1264 }
1265
1266
1267// if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
1268 if (new_mld_index == 0 || new_mld_index > MAX_ML_MLD_CNT) {
1269 wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", new_mld_index);
1270 return RETURN_ERR;
1271 }
1272
1273 if (!mld_test(new_mld_index)) {
1274 wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", new_mld_index);
1275 return RETURN_ERR;
1276 }
1277
1278 mld = &(mld_config.mld[new_mld_index]);
1279
developerc3556192023-12-06 17:59:09 +08001280
developer6c6ef372023-11-08 10:59:14 +08001281 for (i = 0; i < MAX_APS; i++) {
1282 if(mld_ap_test(mld, i)) {
1283 if (i == ap_index) {
1284 wifi_debug(DEBUG_ERROR, "current ap has already joined current mld\n");
1285 return RETURN_OK;
1286 }
developerc3556192023-12-06 17:59:09 +08001287
1288 if (vap_index_to_radio_array_index(i, &radio1, &bss_idx) != RETURN_OK) {
1289 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
1290 return RETURN_ERR;
1291 }
1292
1293 if (vap_index_to_radio_array_index(ap_index, &radio2, &bss_idx) != RETURN_OK) {
1294 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
1295 return RETURN_ERR;
1296 }
1297
1298 if (radio1 == radio2) {
developer6c6ef372023-11-08 10:59:14 +08001299 wifi_debug(DEBUG_ERROR, "same band ap(index=%d) has already joined current mld\n", i);
1300 return RETURN_ERR;
1301 }
1302 }
1303 }
1304
1305 res = v_secure_system("mwctl %s set apmld=tsfrlink:group=%u", interface_name, new_mld_index);
1306
1307 if (res) {
1308 wifi_debug(DEBUG_ERROR, "fail to transfer ap to ap mld with mld_index %d\n", new_mld_index);
1309 return RETURN_ERR;
1310 }
1311
1312 mld_ap_set(old_mld, ap_index, 0);
1313 mld_ap_set(mld, ap_index, 1);
1314
1315 return RETURN_OK;
1316}
1317
1318INT wifi_eht_config_sync2_dat_by_radio(unsigned char band)
1319{
1320 unsigned char bss_idx, mld_index;
1321 char config_file_dat[128] = {0}, MldGroup_V_Str[128] = {0}, buf[64] = {0};
1322 int res, vap_index, len = 0, bssidnum;
1323 struct params MldGroup;
1324
developercd0b70a2023-12-11 11:25:50 +08001325 if (band >= get_runtime_max_radio()) {
developer6c6ef372023-11-08 10:59:14 +08001326 wifi_debug(DEBUG_ERROR, "invalid band %u\n", band);
1327 return RETURN_ERR;
1328 }
1329
1330 res = wifi_BandProfileRead(0, band, "BssidNum", buf, sizeof(buf), "0");
1331 if (res != 0) {
1332 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
1333 return RETURN_ERR;
1334 }
1335
1336 bssidnum = atoi(buf);
1337 if (bssidnum <= 0) {
1338 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
1339 return RETURN_ERR;
1340 }
1341 if (bssidnum > LOGAN_MAX_NUM_VAP_PER_RADIO) {
1342 wifi_debug(DEBUG_ERROR, "bss_num is larger than %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO);
1343 return RETURN_ERR;
1344 }
1345
1346 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
1347 if (os_snprintf_error(sizeof(config_file_dat), res)) {
1348 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1349 return RETURN_ERR;
1350 }
1351
1352 for (bss_idx = 0; bss_idx < bssidnum; bss_idx++) {
developerc3556192023-12-06 17:59:09 +08001353 if (array_index_to_vap_index(band, bss_idx, &vap_index) != RETURN_OK) {
developer6c6ef372023-11-08 10:59:14 +08001354 wifi_debug(DEBUG_ERROR, "invalide vap index, band=%d, bss_idx=%d\n", (int)band, (int)bss_idx);
1355 break;
1356 }
1357 mld_index = mld_ap_test_all_mlds(vap_index);
1358 res = snprintf(&(MldGroup_V_Str[len]), sizeof(MldGroup_V_Str) - len, "%u;", mld_index);
1359 if (os_snprintf_error(sizeof(MldGroup_V_Str) - len, res)) {
1360 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1361 break;
1362 }
1363 len += res;
1364 }
1365
1366 MldGroup.name = "MldGroup";
1367 MldGroup.value = MldGroup_V_Str;
1368 wifi_datfileWrite(config_file_dat, &MldGroup, 1);
1369 wifi_debug(DEBUG_ERROR, "band[%u] MldGroup=%s\n", band, MldGroup_V_Str);
1370
1371 return RETURN_OK;
1372}
1373
1374void wifi_eht_config_sync2_dat(void)
1375{
1376 unsigned char band;
1377
developercd0b70a2023-12-11 11:25:50 +08001378 for (band = 0; band < get_runtime_max_radio(); band++) {
developer6c6ef372023-11-08 10:59:14 +08001379 wifi_eht_config_sync2_dat_by_radio(band);
1380 }
1381}
1382
1383#endif
developer96b38512023-02-22 11:17:45 +08001384
1385static int
1386get_value(const char *conf_file, const char *param, char *value, int len)
1387{
developera3511852023-06-14 14:12:59 +08001388 FILE *fp;
1389 int ret = -1;
1390 int param_len = strlen(param);
1391 int buf_len;
developer86035662023-06-28 19:21:12 +08001392 char buf[256] = {0};
developer96b38512023-02-22 11:17:45 +08001393
developera3511852023-06-14 14:12:59 +08001394 fp = fopen(conf_file, "r");
1395 if (!fp) {
1396 return -1;
1397 }
developer96b38512023-02-22 11:17:45 +08001398
developera3511852023-06-14 14:12:59 +08001399 while (fgets(buf, sizeof(buf), fp)) {
1400 buf_len = strlen(buf);
developer86035662023-06-28 19:21:12 +08001401 if (buf_len == 0) {
1402 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +08001403 if (fclose(fp) != 0) {
1404 wifi_debug(DEBUG_ERROR, "fclose fail\n");
1405 }
developer86035662023-06-28 19:21:12 +08001406 return RETURN_ERR;
1407 }
developera3511852023-06-14 14:12:59 +08001408 if (buf[buf_len - 1] == '\n') {
1409 buf_len--;
1410 buf[buf_len] = '\0';
1411 }
1412 if ((buf_len > param_len) &&
1413 (strncmp(buf, param, param_len) == 0) &&
1414 (buf[param_len] == '=')) {
developer96b38512023-02-22 11:17:45 +08001415
developera3511852023-06-14 14:12:59 +08001416 if (buf_len == (param_len + 1)) {
1417 value[0] = '\0';
1418 ret = 0;
1419 } else {
1420 ret = snprintf(value, len, "%s", buf + (param_len + 1));
developer75bd10c2023-06-27 11:34:08 +08001421 if (os_snprintf_error(len, ret)) {
1422 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1423 }
developera3511852023-06-14 14:12:59 +08001424 }
developerd14dff12023-06-28 22:47:44 +08001425 if (fclose(fp) != 0) {
1426 ret = -1;
1427 wifi_debug(DEBUG_ERROR, "fclose fail\n");
1428 }
developera3511852023-06-14 14:12:59 +08001429 return ret;
1430 }
1431 }
developer37646972023-06-29 10:58:43 +08001432 if (fclose(fp) == EOF){
1433 wifi_debug(DEBUG_ERROR, "fclose fail\n");
1434 return RETURN_ERR;
1435 }
developera3511852023-06-14 14:12:59 +08001436 return -1;
developer96b38512023-02-22 11:17:45 +08001437}
1438
1439static int
1440get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
1441{
developera3511852023-06-14 14:12:59 +08001442 char buf[256];
1443 int ret;
1444 char *save_ptr = NULL;
1445 char *tok = NULL;
developer96b38512023-02-22 11:17:45 +08001446
developera3511852023-06-14 14:12:59 +08001447 ret = get_value(conf_file, param, buf, sizeof(buf));
1448 if (ret < 0)
1449 return ret;
developer96b38512023-02-22 11:17:45 +08001450
developera3511852023-06-14 14:12:59 +08001451 tok = strtok_r(buf, ";", &save_ptr);
1452 do {
1453 if (idx == 0 || tok == NULL)
1454 break;
1455 else
1456 idx--;
developer96b38512023-02-22 11:17:45 +08001457
developera3511852023-06-14 14:12:59 +08001458 tok = strtok_r(NULL, ";", &save_ptr);
1459 } while (tok != NULL);
developer96b38512023-02-22 11:17:45 +08001460
developera3511852023-06-14 14:12:59 +08001461 if (tok) {
1462 ret = snprintf(value, len, "%s", tok);
developer75bd10c2023-06-27 11:34:08 +08001463 if (os_snprintf_error(len, ret)) {
1464 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1465 return -1;
1466 }
developera3511852023-06-14 14:12:59 +08001467 } else {
1468 ret = 0;
1469 value[0] = '\0';
1470 }
developer96b38512023-02-22 11:17:45 +08001471
developera3511852023-06-14 14:12:59 +08001472 return ret;
developer96b38512023-02-22 11:17:45 +08001473}
1474
1475
developer72fb0bb2023-01-11 09:46:29 +08001476#ifdef HAL_NETLINK_IMPL
1477typedef struct {
developera3511852023-06-14 14:12:59 +08001478 int id;
1479 struct nl_sock* socket;
1480 struct nl_cb* cb;
developer72fb0bb2023-01-11 09:46:29 +08001481} Netlink;
1482
1483static int mac_addr_aton(unsigned char *mac_addr, char *arg)
1484{
developera3511852023-06-14 14:12:59 +08001485 unsigned char mac_addr_int[6]={};
developer75bd10c2023-06-27 11:34:08 +08001486 unsigned int recv;
1487
1488 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);
1489
1490 if (recv != 6) {
1491 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
1492 return -1;
1493 }
developera3511852023-06-14 14:12:59 +08001494 mac_addr[0] = mac_addr_int[0];
1495 mac_addr[1] = mac_addr_int[1];
1496 mac_addr[2] = mac_addr_int[2];
1497 mac_addr[3] = mac_addr_int[3];
1498 mac_addr[4] = mac_addr_int[4];
1499 mac_addr[5] = mac_addr_int[5];
1500 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001501}
1502
1503static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
1504{
developera3511852023-06-14 14:12:59 +08001505 unsigned int mac_addr_int[6]={};
developere40952c2023-06-15 18:46:43 +08001506 int res;
1507
developera3511852023-06-14 14:12:59 +08001508 mac_addr_int[0] = arg[0];
1509 mac_addr_int[1] = arg[1];
1510 mac_addr_int[2] = arg[2];
1511 mac_addr_int[3] = arg[3];
1512 mac_addr_int[4] = arg[4];
1513 mac_addr_int[5] = arg[5];
developere40952c2023-06-15 18:46:43 +08001514 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]);
1515 if (os_snprintf_error(20, res)) {
1516 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1517 }
developera3511852023-06-14 14:12:59 +08001518 return;
developer72fb0bb2023-01-11 09:46:29 +08001519}
1520
1521static int ieee80211_frequency_to_channel(int freq)
1522{
developera3511852023-06-14 14:12:59 +08001523 /* see 802.11-2007 17.3.8.3.2 and Annex J */
1524 if (freq == 2484)
1525 return 14;
1526 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
1527 else if (freq == 5935)
1528 return 2;
1529 else if (freq < 2484)
1530 return (freq - 2407) / 5;
1531 else if (freq >= 4910 && freq <= 4980)
1532 return (freq - 4000) / 5;
1533 else if (freq < 5950)
1534 return (freq - 5000) / 5;
1535 else if (freq <= 45000) /* DMG band lower limit */
1536 /* see 802.11ax D6.1 27.3.23.2 */
1537 return (freq - 5950) / 5;
1538 else if (freq >= 58320 && freq <= 70200)
1539 return (freq - 56160) / 2160;
1540 else
1541 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001542}
1543
1544static int initSock80211(Netlink* nl) {
developera3511852023-06-14 14:12:59 +08001545 nl->socket = nl_socket_alloc();
1546 if (!nl->socket) {
developer75bd10c2023-06-27 11:34:08 +08001547 wifi_debug(DEBUG_ERROR, "Failing to allocate the sock\n");
developera3511852023-06-14 14:12:59 +08001548 return -ENOMEM;
1549 }
developer72fb0bb2023-01-11 09:46:29 +08001550
developera3511852023-06-14 14:12:59 +08001551 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
developer72fb0bb2023-01-11 09:46:29 +08001552
developera3511852023-06-14 14:12:59 +08001553 if (genl_connect(nl->socket)) {
developer75bd10c2023-06-27 11:34:08 +08001554 wifi_debug(DEBUG_ERROR, "Failed to connect\n");
developera3511852023-06-14 14:12:59 +08001555 nl_close(nl->socket);
1556 nl_socket_free(nl->socket);
1557 return -ENOLINK;
1558 }
developer72fb0bb2023-01-11 09:46:29 +08001559
developera3511852023-06-14 14:12:59 +08001560 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
1561 if (nl->id< 0) {
developer75bd10c2023-06-27 11:34:08 +08001562 wifi_debug(DEBUG_ERROR, "interface not found.\n");
developera3511852023-06-14 14:12:59 +08001563 nl_close(nl->socket);
1564 nl_socket_free(nl->socket);
1565 return -ENOENT;
1566 }
developer72fb0bb2023-01-11 09:46:29 +08001567
developera3511852023-06-14 14:12:59 +08001568 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
1569 if ((!nl->cb)) {
developer75bd10c2023-06-27 11:34:08 +08001570 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink callback.\n");
developera3511852023-06-14 14:12:59 +08001571 nl_close(nl->socket);
1572 nl_socket_free(nl->socket);
1573 return ENOMEM;
1574 }
developer72fb0bb2023-01-11 09:46:29 +08001575
developera3511852023-06-14 14:12:59 +08001576 return nl->id;
developer72fb0bb2023-01-11 09:46:29 +08001577}
1578
1579static int nlfree(Netlink *nl)
1580{
developera3511852023-06-14 14:12:59 +08001581 nl_cb_put(nl->cb);
1582 nl_close(nl->socket);
1583 nl_socket_free(nl->socket);
1584 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001585}
1586
1587static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
developera3511852023-06-14 14:12:59 +08001588 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
1589 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
1590 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
developer72fb0bb2023-01-11 09:46:29 +08001591};
1592
1593static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
1594};
1595
1596static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
1597};
1598
1599typedef struct _wifi_channelStats_loc {
developera3511852023-06-14 14:12:59 +08001600 INT array_size;
1601 INT ch_number;
1602 BOOL ch_in_pool;
1603 INT ch_noise;
1604 BOOL ch_radar_noise;
1605 INT ch_max_80211_rssi;
1606 INT ch_non_80211_noise;
1607 INT ch_utilization;
1608 ULLONG ch_utilization_total;
1609 ULLONG ch_utilization_busy;
1610 ULLONG ch_utilization_busy_tx;
1611 ULLONG ch_utilization_busy_rx;
1612 ULLONG ch_utilization_busy_self;
1613 ULLONG ch_utilization_busy_ext;
developer72fb0bb2023-01-11 09:46:29 +08001614} wifi_channelStats_t_loc;
1615
1616typedef struct wifi_device_info {
developera3511852023-06-14 14:12:59 +08001617 INT wifi_devIndex;
1618 UCHAR wifi_devMacAddress[6];
1619 CHAR wifi_devIPAddress[64];
1620 BOOL wifi_devAssociatedDeviceAuthentiationState;
1621 INT wifi_devSignalStrength;
1622 INT wifi_devTxRate;
1623 INT wifi_devRxRate;
developer72fb0bb2023-01-11 09:46:29 +08001624} wifi_device_info_t;
1625
1626#endif
1627
1628//For 5g Alias Interfaces
developer72fb0bb2023-01-11 09:46:29 +08001629static BOOL Radio_flag = TRUE;
1630//wifi_setApBeaconRate(1, beaconRate);
1631
1632BOOL multiple_set = FALSE;
1633
developer8078acf2023-08-04 18:52:48 +08001634/*static int _syscmd(char *cmd, char *retBuf, int retBufSize)
developer72fb0bb2023-01-11 09:46:29 +08001635{
developera3511852023-06-14 14:12:59 +08001636 FILE *f;
1637 char *ptr = retBuf;
1638 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
developer72fb0bb2023-01-11 09:46:29 +08001639
developera3511852023-06-14 14:12:59 +08001640 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1641 if((f = popen(cmd, "r")) == NULL) {
developer75bd10c2023-06-27 11:34:08 +08001642 wifi_debug(DEBUG_ERROR, "\npopen %s error\n", cmd);
developera3511852023-06-14 14:12:59 +08001643 return RETURN_ERR;
1644 }
developer72fb0bb2023-01-11 09:46:29 +08001645
developera3511852023-06-14 14:12:59 +08001646 while(!feof(f))
1647 {
1648 *ptr = 0;
1649 if(bufSize>=128) {
1650 bufbytes=128;
1651 } else {
1652 bufbytes=bufSize-1;
1653 }
developer72fb0bb2023-01-11 09:46:29 +08001654
developerd14dff12023-06-28 22:47:44 +08001655 if (fgets(ptr,bufbytes,f) == NULL)
1656 break;
developera3511852023-06-14 14:12:59 +08001657 readbytes=strlen(ptr);
developer72fb0bb2023-01-11 09:46:29 +08001658
developera3511852023-06-14 14:12:59 +08001659 if(!readbytes)
1660 break;
developer72fb0bb2023-01-11 09:46:29 +08001661
developera3511852023-06-14 14:12:59 +08001662 bufSize-=readbytes;
1663 ptr += readbytes;
1664 }
1665 cmd_ret = pclose(f);
1666 retBuf[retBufSize-1]=0;
1667 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001668
developera3511852023-06-14 14:12:59 +08001669 return cmd_ret >> 8;
developer72fb0bb2023-01-11 09:46:29 +08001670}
developer8078acf2023-08-04 18:52:48 +08001671*/
developer72fb0bb2023-01-11 09:46:29 +08001672
1673INT radio_index_to_phy(int radioIndex)
1674{
developera3511852023-06-14 14:12:59 +08001675 /* TODO */
1676 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +08001677}
1678
1679INT wifi_getMaxRadioNumber(INT *max_radio_num)
1680{
developera3511852023-06-14 14:12:59 +08001681 char buf[4] = {0};
developere40952c2023-06-15 18:46:43 +08001682 int res;
developerc14d83a2023-06-29 20:09:42 +08001683 unsigned long tmp;
developera3511852023-06-14 14:12:59 +08001684 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001685
developer33f13ba2023-07-12 16:19:06 +08001686 res = _syscmd_secure(buf, sizeof(buf), "iw list | grep Wiphy | wc -l | tr -d '\\n'");
1687 if (res) {
1688 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08001689 }
developerc14d83a2023-06-29 20:09:42 +08001690 if (hal_strtoul(buf, 10, &tmp) < 0) {
1691 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08001692 }
developerc14d83a2023-06-29 20:09:42 +08001693 res = tmp;
developerd14dff12023-06-28 22:47:44 +08001694
1695 *max_radio_num = res > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:res;
developer72fb0bb2023-01-11 09:46:29 +08001696
developera3511852023-06-14 14:12:59 +08001697 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001698
developera3511852023-06-14 14:12:59 +08001699 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001700}
1701
developer17038e62023-03-02 14:43:43 +08001702wifi_band radio_index_to_band(int radioIndex)
1703{
developerdfd270b2023-12-12 10:24:30 +08001704 char buf[64] = {0};
1705 long int nl80211_band = 0;
1706 wifi_band band = band_invalid;
1707 int res;
1708 int phyIndex = 0;
1709 int zero_array[MAX_NUM_RADIOS] = {0};
1710
1711 if (memcmp(radio_band, zero_array, sizeof(radio_band)) == 0) {
1712 phyIndex = radio_index_to_phy(radioIndex);
1713
1714 res = _syscmd_secure(buf, sizeof(buf),
1715 "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
1716
1717 if (res) {
1718 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
1719 }
1720
1721 if (hal_strtol(buf, 16, &nl80211_band) < 0) {
1722 wifi_debug(DEBUG_ERROR, "strtol fail\n");
1723 }
1724 if (nl80211_band == 1)
1725 band = band_2_4;
1726 else if (nl80211_band == 2)
1727 band = band_5;
1728 else if (nl80211_band == 4) // band == 3 is 60GHz
1729 band = band_6;
1730
1731 radio_band[radioIndex] = band;
1732 }
1733
developera3511852023-06-14 14:12:59 +08001734 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +08001735}
1736
developer72fb0bb2023-01-11 09:46:29 +08001737wifi_band wifi_index_to_band(int apIndex)
1738{
developera3511852023-06-14 14:12:59 +08001739 char buf[64] = {0};
developerc14d83a2023-06-29 20:09:42 +08001740 long int nl80211_band = 0;
developera3511852023-06-14 14:12:59 +08001741 int i = 0;
1742 int phyIndex = 0;
developerc3556192023-12-06 17:59:09 +08001743 int radioIndex = 0, bss_idx;
developera3511852023-06-14 14:12:59 +08001744 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08001745 int res;
developera3511852023-06-14 14:12:59 +08001746 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001747
developerc3556192023-12-06 17:59:09 +08001748 if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
1749 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", apIndex);
developer9ce44382023-06-28 11:09:37 +08001750 return RETURN_ERR;
1751 }
developerc3556192023-12-06 17:59:09 +08001752
developera3511852023-06-14 14:12:59 +08001753 phyIndex = radio_index_to_phy(radioIndex);
developer33f13ba2023-07-12 16:19:06 +08001754 while (i < 10) {
1755 res = _syscmd_secure(buf, sizeof(buf),
1756 "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
1757
1758 if (res) {
1759 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08001760 }
developer33f13ba2023-07-12 16:19:06 +08001761
developerc14d83a2023-06-29 20:09:42 +08001762 if (hal_strtol(buf, 16, &nl80211_band) < 0) {
1763 wifi_debug(DEBUG_ERROR, "strtol fail\n");
1764 }
developera3511852023-06-14 14:12:59 +08001765 if (nl80211_band == 1)
1766 band = band_2_4;
1767 else if (nl80211_band == 2)
1768 band = band_5;
1769 else if (nl80211_band == 4) // band == 3 is 60GHz
1770 band = band_6;
developer72fb0bb2023-01-11 09:46:29 +08001771
developera3511852023-06-14 14:12:59 +08001772 if(band != band_invalid)
1773 break;
developer69b61b02023-03-07 17:17:44 +08001774
developera3511852023-06-14 14:12:59 +08001775 i++;
1776 sleep(1);
1777 }
developer72fb0bb2023-01-11 09:46:29 +08001778
developera3511852023-06-14 14:12:59 +08001779 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1780 return band;
developer72fb0bb2023-01-11 09:46:29 +08001781}
1782
1783static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
1784{
developer8078acf2023-08-04 18:52:48 +08001785
developer7e4a2a62023-04-06 19:56:03 +08001786 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001787 int res = 0;
developer72fb0bb2023-01-11 09:46:29 +08001788
developer72fb0bb2023-01-11 09:46:29 +08001789
developer8078acf2023-08-04 18:52:48 +08001790 res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",conf_file, param);
1791 if (res) {
1792 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer7e4a2a62023-04-06 19:56:03 +08001793 }
developerb758dfd2023-06-21 17:32:07 +08001794
developer7e4a2a62023-04-06 19:56:03 +08001795
developere40952c2023-06-15 18:46:43 +08001796 res = snprintf(output, output_size, "%s", buf);
1797 if (os_snprintf_error(output_size, res)) {
1798 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1799 return RETURN_ERR;
1800 }
developer7e4a2a62023-04-06 19:56:03 +08001801
1802 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001803}
1804
1805static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
1806{
developer8078acf2023-08-04 18:52:48 +08001807
developera3511852023-06-14 14:12:59 +08001808 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001809 int res;
developer72fb0bb2023-01-11 09:46:29 +08001810
developera3511852023-06-14 14:12:59 +08001811 for (int i = 0; i < item_count; i++) {
1812 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
1813 if (strlen(buf) == 0) /*no such item, insert it*/
developer8078acf2023-08-04 18:52:48 +08001814 res = _syscmd_secure(buf, sizeof(buf), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file);
developera3511852023-06-14 14:12:59 +08001815 else /*find the item, update it*/
developer8078acf2023-08-04 18:52:48 +08001816 res = _syscmd_secure(buf, sizeof(buf), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file);
developera1255e42023-05-13 17:45:02 +08001817
developer8078acf2023-08-04 18:52:48 +08001818 if(res) {
1819 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08001820 }
developera3511852023-06-14 14:12:59 +08001821 }
developer72fb0bb2023-01-11 09:46:29 +08001822
developera3511852023-06-14 14:12:59 +08001823 return 0;
developera1255e42023-05-13 17:45:02 +08001824}
developerfde01262023-05-22 15:15:24 +08001825
developera1255e42023-05-13 17:45:02 +08001826static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
1827{
developere40952c2023-06-15 18:46:43 +08001828 int res = 0;
developera3511852023-06-14 14:12:59 +08001829 int len;
developerfde01262023-05-22 15:15:24 +08001830
developer8078acf2023-08-04 18:52:48 +08001831 res = _syscmd_secure(output, output_size, "datconf -f %s get %s", conf_file, param);
developere40952c2023-06-15 18:46:43 +08001832
developer8078acf2023-08-04 18:52:48 +08001833 if (res) {
1834 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developera3511852023-06-14 14:12:59 +08001835 }
developera1255e42023-05-13 17:45:02 +08001836
developer8078acf2023-08-04 18:52:48 +08001837
developera3511852023-06-14 14:12:59 +08001838 len = strlen(output);
1839 if ((len > 0) && (output[len - 1] == '\n')) {
1840 output[len - 1] = '\0';
1841 }
developerfde01262023-05-22 15:15:24 +08001842
developera3511852023-06-14 14:12:59 +08001843 return 0;
developerfde01262023-05-22 15:15:24 +08001844}
developera1255e42023-05-13 17:45:02 +08001845
developera1255e42023-05-13 17:45:02 +08001846static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
1847{
developere40952c2023-06-15 18:46:43 +08001848 int res;
developera3511852023-06-14 14:12:59 +08001849 char buf[MAX_BUF_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +08001850
developera3511852023-06-14 14:12:59 +08001851 for (int i = 0; i < item_count; i++) {
developer8078acf2023-08-04 18:52:48 +08001852 res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
developera1255e42023-05-13 17:45:02 +08001853
developer8078acf2023-08-04 18:52:48 +08001854 if (res) {
1855 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
1856 }
developera3511852023-06-14 14:12:59 +08001857 }
developera1255e42023-05-13 17:45:02 +08001858
developera3511852023-06-14 14:12:59 +08001859 return 0;
developera1255e42023-05-13 17:45:02 +08001860}
1861
developerfde01262023-05-22 15:15:24 +08001862static int wifi_l1ProfileRead(char *param, char *output, int output_size)
1863{
developera3511852023-06-14 14:12:59 +08001864 int ret;
developerfde01262023-05-22 15:15:24 +08001865
developera3511852023-06-14 14:12:59 +08001866 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1867 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001868 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001869 return RETURN_ERR;
1870 }
developerfde01262023-05-22 15:15:24 +08001871
developera3511852023-06-14 14:12:59 +08001872 ret = wifi_datfileRead(l1profile, param, output, output_size);
1873 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001874 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, l1profile, ret);
developera3511852023-06-14 14:12:59 +08001875 return RETURN_ERR;
1876 }
developerfde01262023-05-22 15:15:24 +08001877
developera3511852023-06-14 14:12:59 +08001878 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1879 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001880}
1881
1882static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
1883{
developera3511852023-06-14 14:12:59 +08001884 char option[64];
1885 char card_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001886 int res;
developerfde01262023-05-22 15:15:24 +08001887
developera3511852023-06-14 14:12:59 +08001888 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerfde01262023-05-22 15:15:24 +08001889
developera3511852023-06-14 14:12:59 +08001890 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001891 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001892 return RETURN_ERR;
1893 }
developerfde01262023-05-22 15:15:24 +08001894
developere40952c2023-06-15 18:46:43 +08001895 res = snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
1896 if (os_snprintf_error(sizeof(option), res)) {
1897 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +08001898 return RETURN_ERR;
1899 }
developere40952c2023-06-15 18:46:43 +08001900 res = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
1901 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001902 wifi_debug(DEBUG_ERROR, "wifi_l1ProfileRead %s failed, ret:%d", option, res);
developere40952c2023-06-15 18:46:43 +08001903 return RETURN_ERR;
1904 }
developerfde01262023-05-22 15:15:24 +08001905
developere40952c2023-06-15 18:46:43 +08001906 res = wifi_datfileRead(card_profile_path, param, output, output_size);
1907 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001908 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, card_profile_path, res);
developera3511852023-06-14 14:12:59 +08001909 return RETURN_ERR;
1910 }
developerfde01262023-05-22 15:15:24 +08001911
developera3511852023-06-14 14:12:59 +08001912 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1913 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001914}
1915
1916static int wifi_BandProfileRead(int card_idx,
developera3511852023-06-14 14:12:59 +08001917 int radio_idx,
1918 char *param,
1919 char *output,
1920 int output_size,
1921 char *default_value)
developerfde01262023-05-22 15:15:24 +08001922{
developera3511852023-06-14 14:12:59 +08001923 char option[64];
1924 char band_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001925 int ret, res;
developerfde01262023-05-22 15:15:24 +08001926
developera3511852023-06-14 14:12:59 +08001927 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1928 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001929 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001930 return RETURN_ERR;
1931 }
developerfde01262023-05-22 15:15:24 +08001932
developere40952c2023-06-15 18:46:43 +08001933 res = snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1934 if (os_snprintf_error(sizeof(option), res)) {
1935 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1936 return RETURN_ERR;
1937 }
developera3511852023-06-14 14:12:59 +08001938 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1939 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001940 wifi_debug(DEBUG_ERROR, "wifi_CardProfileRead %s failed, ret:%d", option, ret);
developera3511852023-06-14 14:12:59 +08001941 return RETURN_ERR;
1942 }
developerfde01262023-05-22 15:15:24 +08001943
developera3511852023-06-14 14:12:59 +08001944 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1945 if (ret != 0) {
1946 if (default_value) {
developere40952c2023-06-15 18:46:43 +08001947 res = snprintf(output, output_size, "%s", default_value);
1948 if (os_snprintf_error(output_size, res)) {
1949 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1950 return RETURN_ERR;
1951 }
developera3511852023-06-14 14:12:59 +08001952 } else {
1953 output[0] = '\0';
1954 }
1955 }
developerfde01262023-05-22 15:15:24 +08001956
developera3511852023-06-14 14:12:59 +08001957 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1958 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001959}
1960
developer72fb0bb2023-01-11 09:46:29 +08001961//For Getting Current Interface Name from corresponding hostapd configuration
1962static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1963{
developera3511852023-06-14 14:12:59 +08001964 char config_file[128] = {0};
developere40952c2023-06-15 18:46:43 +08001965 int res;
developer72fb0bb2023-01-11 09:46:29 +08001966
developera3511852023-06-14 14:12:59 +08001967 if (interface_name == NULL)
1968 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001969
developera3511852023-06-14 14:12:59 +08001970 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001971
developere40952c2023-06-15 18:46:43 +08001972 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1973 if (os_snprintf_error(sizeof(config_file), res)) {
1974 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1975 return RETURN_ERR;
1976 }
developera3511852023-06-14 14:12:59 +08001977 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1978 if (strlen(interface_name) == 0)
1979 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001980
developera3511852023-06-14 14:12:59 +08001981 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1982 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001983}
1984
developera1255e42023-05-13 17:45:02 +08001985static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1986{
developera3511852023-06-14 14:12:59 +08001987 char interface_name[IF_NAME_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08001988 char buf[MAX_CMD_SIZE]={'\0'};
1989 UCHAR channel = 0;
developere40952c2023-06-15 18:46:43 +08001990 int res;
developerc3556192023-12-06 17:59:09 +08001991 int main_vap_idx;
developera1255e42023-05-13 17:45:02 +08001992
developerc3556192023-12-06 17:59:09 +08001993 if (array_index_to_vap_index(radio_index, 0, &main_vap_idx) != RETURN_OK) {
1994 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_index);
1995 }
developera1255e42023-05-13 17:45:02 +08001996
developerc3556192023-12-06 17:59:09 +08001997 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08001998 return RETURN_ERR;
1999 /*interface name to channel number*/
developer8078acf2023-08-04 18:52:48 +08002000 res = _syscmd_secure(buf, sizeof(buf), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
2001
2002 if (res) {
2003 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002004 }
2005
developera3511852023-06-14 14:12:59 +08002006 channel = atoi(buf);
2007 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
developera1255e42023-05-13 17:45:02 +08002008 /*count dev number with the same channel*/
developer8078acf2023-08-04 18:52:48 +08002009 res = _syscmd_secure(buf, sizeof(buf), "iw dev | grep -i 'channel %d' | wc -l", channel);
2010
2011 if (res) {
2012 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002013 }
2014
developera3511852023-06-14 14:12:59 +08002015 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
2016 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
2017 return RETURN_OK;
developera1255e42023-05-13 17:45:02 +08002018}
developer72fb0bb2023-01-11 09:46:29 +08002019
2020static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
2021{
developera3511852023-06-14 14:12:59 +08002022 char interface_name[16] = {0};
developer8078acf2023-08-04 18:52:48 +08002023 char output[32]="";
developera3511852023-06-14 14:12:59 +08002024 FILE *fp;
developer8078acf2023-08-04 18:52:48 +08002025 int i;
developera3511852023-06-14 14:12:59 +08002026 //NOTE RELOAD should be done in ApplySSIDSettings
2027 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2028 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002029
2030 for (i=0; i<item_count; i++, list++) {
developer8078acf2023-08-04 18:52:48 +08002031 fp = v_secure_popen("r", "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
2032
developer8078acf2023-08-04 18:52:48 +08002033 if (fp == NULL) {
2034 perror("v_secure_popen failed");
developera3511852023-06-14 14:12:59 +08002035 return -1;
2036 }
developere40952c2023-06-15 18:46:43 +08002037 if (!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) {
developer8078acf2023-08-04 18:52:48 +08002038 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +08002039 perror("fgets failed");
2040 return -1;
2041 }
developer8078acf2023-08-04 18:52:48 +08002042 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +08002043 }
2044 return 0;
developer72fb0bb2023-01-11 09:46:29 +08002045}
2046
developer7e4a2a62023-04-06 19:56:03 +08002047static int wifi_quick_reload_ap(int apIndex)
2048{
2049 char interface_name[IF_NAME_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +08002050 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002051 int res;
developer7e4a2a62023-04-06 19:56:03 +08002052
2053 if (multiple_set == TRUE)
2054 return RETURN_OK;
2055
developer9f2358c2023-09-22 18:42:12 +08002056
developer7e4a2a62023-04-06 19:56:03 +08002057 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2058 return RETURN_ERR;
2059
developer8078acf2023-08-04 18:52:48 +08002060 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s reload", interface_name);
developer9f2358c2023-09-22 18:42:12 +08002061 if (res) {
developer8078acf2023-08-04 18:52:48 +08002062 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer7e4a2a62023-04-06 19:56:03 +08002063 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +08002064 }
developer7e4a2a62023-04-06 19:56:03 +08002065
2066 return RETURN_OK;
2067}
2068
developer72fb0bb2023-01-11 09:46:29 +08002069static int wifi_reloadAp(int apIndex)
2070{
developera3511852023-06-14 14:12:59 +08002071 char interface_name[16] = {0};
developer22e0c672023-06-07 15:25:37 +08002072 int res;
2073
developera3511852023-06-14 14:12:59 +08002074 if (multiple_set == TRUE)
2075 return RETURN_OK;
developera3511852023-06-14 14:12:59 +08002076 char buf[MAX_BUF_SIZE]="";
developer72fb0bb2023-01-11 09:46:29 +08002077
developera3511852023-06-14 14:12:59 +08002078 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2079 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002080
developer8078acf2023-08-04 18:52:48 +08002081 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s reload", interface_name);
2082 if (res) {
2083 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer22e0c672023-06-07 15:25:37 +08002084 return RETURN_ERR;
2085 }
developer72fb0bb2023-01-11 09:46:29 +08002086
developer8078acf2023-08-04 18:52:48 +08002087
2088 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s disable", interface_name);
2089 if (res) {
2090 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer22e0c672023-06-07 15:25:37 +08002091 return RETURN_ERR;
2092 }
developer72fb0bb2023-01-11 09:46:29 +08002093
developer8078acf2023-08-04 18:52:48 +08002094 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s enable", interface_name);
2095 if (res) {
2096 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developera3511852023-06-14 14:12:59 +08002097 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08002098 }
developer72fb0bb2023-01-11 09:46:29 +08002099
developera3511852023-06-14 14:12:59 +08002100 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002101}
2102
2103void wifi_RestartHostapd_2G()
2104{
developera3511852023-06-14 14:12:59 +08002105 int Public2GApIndex = 4;
developer72fb0bb2023-01-11 09:46:29 +08002106
developera3511852023-06-14 14:12:59 +08002107 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2108 wifi_setApEnable(Public2GApIndex, FALSE);
2109 wifi_setApEnable(Public2GApIndex, TRUE);
2110 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002111}
2112
2113void wifi_RestartHostapd_5G()
2114{
developerbb9b20f2023-10-17 18:46:37 +08002115 int Public5GApIndex = 1;
developer72fb0bb2023-01-11 09:46:29 +08002116
developera3511852023-06-14 14:12:59 +08002117 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2118 wifi_setApEnable(Public5GApIndex, FALSE);
2119 wifi_setApEnable(Public5GApIndex, TRUE);
2120 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002121}
2122
2123void wifi_RestartPrivateWifi_2G()
2124{
developera3511852023-06-14 14:12:59 +08002125 int PrivateApIndex = 0;
developer72fb0bb2023-01-11 09:46:29 +08002126
developera3511852023-06-14 14:12:59 +08002127 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2128 wifi_setApEnable(PrivateApIndex, FALSE);
2129 wifi_setApEnable(PrivateApIndex, TRUE);
2130 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002131}
2132
2133void wifi_RestartPrivateWifi_5G()
2134{
developera3511852023-06-14 14:12:59 +08002135 int Private5GApIndex = 1;
developer72fb0bb2023-01-11 09:46:29 +08002136
developera3511852023-06-14 14:12:59 +08002137 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2138 wifi_setApEnable(Private5GApIndex, FALSE);
2139 wifi_setApEnable(Private5GApIndex, TRUE);
2140 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002141}
2142
2143static int writeBandWidth(int radioIndex,char *bw_value)
2144{
developera3511852023-06-14 14:12:59 +08002145 char buf[MAX_BUF_SIZE];
developere40952c2023-06-15 18:46:43 +08002146 int res;
developer72fb0bb2023-01-11 09:46:29 +08002147
developere40952c2023-06-15 18:46:43 +08002148
developer8078acf2023-08-04 18:52:48 +08002149 if (_syscmd_secure(buf, sizeof(buf), "grep SET_BW%d %s", radioIndex, BW_FNAME)) {
developer82160f02023-08-19 15:30:44 +08002150 res = _syscmd_secure(buf, sizeof(buf), "echo SET_BW%d=%s >> /nvram/bw_file.txt", radioIndex, bw_value);
developer8078acf2023-08-04 18:52:48 +08002151 if (res) {
2152 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002153 }
developera3511852023-06-14 14:12:59 +08002154 return RETURN_OK;
2155 }
developer72fb0bb2023-01-11 09:46:29 +08002156
developer8078acf2023-08-04 18:52:48 +08002157
2158 res = _syscmd_secure(buf, sizeof(buf), "sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
2159 if (res) {
2160 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +08002161 }
developera3511852023-06-14 14:12:59 +08002162 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002163}
2164
2165// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
2166INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
2167{
developera3511852023-06-14 14:12:59 +08002168 struct params params={'\0'};
2169 char config_file[MAX_BUF_SIZE] = {0};
2170 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08002171 int res;
developera47dfe22023-12-21 16:02:31 +08002172 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08002173
developera3511852023-06-14 14:12:59 +08002174 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2175 // Copy the numeric value
2176 if (strlen (beaconRate) >= 5) {
2177 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
2178 buf[strlen(beaconRate) - 4] = '\0';
developer9ce44382023-06-28 11:09:37 +08002179 } else if (strlen(beaconRate) > 0){
2180 strncpy(buf, beaconRate,sizeof(buf) - 1);
2181 buf[sizeof(buf) - 1] = '\0';
2182 } else
developera3511852023-06-14 14:12:59 +08002183 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002184
developera3511852023-06-14 14:12:59 +08002185 params.name = "beacon_rate";
2186 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
2187 if (strncmp(buf, "5.5", 3) == 0) {
developere40952c2023-06-15 18:46:43 +08002188 res = snprintf(buf, sizeof(buf), "55");
2189 if (os_snprintf_error(sizeof(buf), res)) {
2190 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2191 return RETURN_ERR;
2192 }
developera3511852023-06-14 14:12:59 +08002193 params.value = buf;
2194 } else {
developer32f2a182023-06-27 19:50:41 +08002195 if (strlen(buf) >= (MAX_BUF_SIZE - 1)) {
2196 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
2197 return RETURN_ERR;
2198 }
2199 strncat(buf, "0", sizeof(buf) - strlen(buf) - 1);
developera3511852023-06-14 14:12:59 +08002200 params.value = buf;
2201 }
developer72fb0bb2023-01-11 09:46:29 +08002202
developera47dfe22023-12-21 16:02:31 +08002203 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
2204 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
2205 return RETURN_ERR;
2206 }
2207
2208 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer32f2a182023-06-27 19:50:41 +08002209 if (os_snprintf_error(sizeof(config_file), res)) {
2210 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2211 return RETURN_ERR;
2212 }
2213
developera3511852023-06-14 14:12:59 +08002214 wifi_hostapdWrite(config_file, &params, 1);
2215 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2216 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002217
developera3511852023-06-14 14:12:59 +08002218 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002219}
2220
2221INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
2222{
developera3511852023-06-14 14:12:59 +08002223 char config_file[128] = {'\0'};
2224 char temp_output[MAX_BUF_SIZE] = {'\0'};
2225 char buf[128] = {'\0'};
developera47dfe22023-12-21 16:02:31 +08002226 int main_vap_idx;
developer8078acf2023-08-04 18:52:48 +08002227
developerc14d83a2023-06-29 20:09:42 +08002228 long int rate = 0;
developere40952c2023-06-15 18:46:43 +08002229 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002230
developera3511852023-06-14 14:12:59 +08002231 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2232 if (NULL == beaconRate)
2233 return RETURN_ERR;
developera47dfe22023-12-21 16:02:31 +08002234
2235 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
2236 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
2237 return RETURN_ERR;
2238 }
developer72fb0bb2023-01-11 09:46:29 +08002239
developera47dfe22023-12-21 16:02:31 +08002240 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer75bd10c2023-06-27 11:34:08 +08002241 if (os_snprintf_error(sizeof(config_file), res)) {
2242 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2243 return RETURN_ERR;
2244 }
developera3511852023-06-14 14:12:59 +08002245 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
2246 phyId = radio_index_to_phy(radioIndex);
2247 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
2248 if(strlen(buf) > 0) {
2249 if (strncmp(buf, "55", 2) == 0)
developere40952c2023-06-15 18:46:43 +08002250 res = snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
developera3511852023-06-14 14:12:59 +08002251 else {
developerc14d83a2023-06-29 20:09:42 +08002252 if (hal_strtol(buf, 10, &rate) < 0) {
2253 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2254 }
developerb14b3462023-07-01 18:02:42 +08002255 res = snprintf(temp_output, sizeof(temp_output), "%ldMbps", rate/10);
developera3511852023-06-14 14:12:59 +08002256 }
developer75bd10c2023-06-27 11:34:08 +08002257 if (os_snprintf_error(sizeof(temp_output), res)) {
2258 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2259 return RETURN_ERR;
2260 }
developera3511852023-06-14 14:12:59 +08002261 } else {
2262 // config not set, so we would use lowest rate as default
developer8078acf2023-08-04 18:52:48 +08002263 res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
2264 if (res) {
2265 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +08002266 }
developer8078acf2023-08-04 18:52:48 +08002267
developere40952c2023-06-15 18:46:43 +08002268 res = snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
developer75bd10c2023-06-27 11:34:08 +08002269 if (os_snprintf_error(sizeof(temp_output), res)) {
2270 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2271 return RETURN_ERR;
2272 }
developera3511852023-06-14 14:12:59 +08002273 }
developer75bd10c2023-06-27 11:34:08 +08002274
developera3511852023-06-14 14:12:59 +08002275 strncpy(beaconRate, temp_output, strlen(temp_output));
2276 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002277
developera3511852023-06-14 14:12:59 +08002278 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002279}
2280
2281INT wifi_setLED(INT radioIndex, BOOL enable)
2282{
2283 return 0;
2284}
2285INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
2286{
2287 return RETURN_OK;
2288}
2289/**********************************************************************************
2290 *
developer69b61b02023-03-07 17:17:44 +08002291 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08002292 *
2293**********************************************************************************/
2294//---------------------------------------------------------------------------------------------------
2295//Wifi system api
2296//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 +08002297INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002298{
developere40952c2023-06-15 18:46:43 +08002299 int res;
2300
developera3511852023-06-14 14:12:59 +08002301 if(!output_string)
2302 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002303 res = snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
2304 if (os_snprintf_error(64, res)) {
2305 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2306 return RETURN_ERR;
2307 }
developer72fb0bb2023-01-11 09:46:29 +08002308
developera3511852023-06-14 14:12:59 +08002309 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002310}
2311
developer9635f402023-12-25 19:48:21 +08002312static void
2313wifi_PrepareEnableSSIDConfig(bool reset)
2314{
2315 int res;
2316 char ret_buf[MAX_BUF_SIZE] = {0};
2317
2318 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2319
2320 if (access(SSID_ENABLE_CONFIG, F_OK) == 0 && reset == FALSE)
2321 return;
2322 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp /etc/enable_ssid %s", SSID_ENABLE_CONFIG);
2323 if (res) {
2324 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
2325 }
2326 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2327}
2328
2329static BOOL getVapEnableConfig(int vap_index)
2330{
2331 int res = 0;
2332 int len;
2333 char output[8] = {0};
2334
2335 res = _syscmd_secure(output, sizeof(output), "datconf -f %s get enable_ssid%d",
2336 SSID_ENABLE_CONFIG, vap_index);
2337
2338 if (res) {
2339 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
2340 }
2341
2342 len = strlen(output);
2343 if ((len > 0) && (output[len - 1] == '\n')) {
2344 output[len - 1] = '\0';
2345 }
2346
2347 return output[0] == '0' ? FALSE : TRUE;
2348}
2349
2350static BOOL setVapEnableConfig(int vap_index, BOOL enable)
2351{
2352 int res;
2353 char buf[8] = {0};
2354
2355 res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set enable_ssid%d \"%s\"",
2356 SSID_ENABLE_CONFIG, vap_index, enable ? "1" : "0");
2357
2358 if (res) {
2359 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
2360 }
2361
2362 wifi_debug(DEBUG_ERROR, "vap_index[%d] %s\n", vap_index, enable ? "enabled" : "disabled");
2363 return 0;
2364}
2365
developer72fb0bb2023-01-11 09:46:29 +08002366
2367/* wifi_factoryReset() function */
2368/**
developer69b61b02023-03-07 17:17:44 +08002369* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08002370* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
2371*
2372* @param None
2373*
2374* @return The status of the operation.
2375* @retval RETURN_OK if successful.
2376* @retval RETURN_ERR if any error is detected
2377*
2378* @execution Synchronous
2379* @sideeffect None
2380*
2381* @note This function must not suspend and must not invoke any blocking system
2382* calls. It should probably just send a message to a driver event handler task.
2383*
2384*/
2385INT wifi_factoryReset()
2386{
developer47cc27a2023-05-17 23:09:58 +08002387 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002388 int res;
developer72fb0bb2023-01-11 09:46:29 +08002389
developer47cc27a2023-05-17 23:09:58 +08002390 /*delete running hostapd conf files*/
2391 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
developere40952c2023-06-15 18:46:43 +08002392
developer8078acf2023-08-04 18:52:48 +08002393 res = _syscmd_secure(buf, sizeof(buf), "rm -rf /nvram/*.conf");
2394 if (res) {
2395 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
2396 }
developer72fb0bb2023-01-11 09:46:29 +08002397
developerd14dff12023-06-28 22:47:44 +08002398 wifi_PrepareDefaultHostapdConfigs(TRUE);
developer9635f402023-12-25 19:48:21 +08002399 wifi_PrepareEnableSSIDConfig(TRUE);
developer47cc27a2023-05-17 23:09:58 +08002400 wifi_psk_file_reset();
2401
developer8078acf2023-08-04 18:52:48 +08002402
developer47cc27a2023-05-17 23:09:58 +08002403 memset(buf, 0, MAX_BUF_SIZE);
2404
developer8078acf2023-08-04 18:52:48 +08002405 res = _syscmd_secure(buf, sizeof(buf), "systemctl restart hostapd.service");
2406 if (res) {
2407 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002408 }
2409
developer47cc27a2023-05-17 23:09:58 +08002410 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002411}
2412
2413/* wifi_factoryResetRadios() function */
2414/**
2415* @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.
2416*
2417* @param None
2418* @return The status of the operation
2419* @retval RETURN_OK if successful
2420* @retval RETURN_ERR if any error is detected
2421*
2422* @execution Synchronous
2423*
2424* @sideeffect None
2425*
2426* @note This function must not suspend and must not invoke any blocking system
2427* calls. It should probably just send a message to a driver event handler task.
2428*
2429*/
2430INT wifi_factoryResetRadios()
2431{
developera3511852023-06-14 14:12:59 +08002432 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
2433 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002434
developera3511852023-06-14 14:12:59 +08002435 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002436}
2437
developerfead3972023-05-25 20:15:02 +08002438ULONG get_radio_reset_cnt(int radioIndex)
2439{
developerfead3972023-05-25 20:15:02 +08002440 char buf[MAX_BUF_SIZE] = {0};
2441 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08002442 int res;
developerfead3972023-05-25 20:15:02 +08002443
developer8078acf2023-08-04 18:52:48 +08002444 res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developerfead3972023-05-25 20:15:02 +08002445 RADIO_RESET_FILE, radioIndex);
developer8078acf2023-08-04 18:52:48 +08002446 if (res) {
2447 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002448 }
2449
developerfead3972023-05-25 20:15:02 +08002450 if (strlen(buf) == 0)
2451 return 0;
2452 else {
2453 reset_count = atol(buf);
2454 return reset_count;
2455 }
2456}
developerd08b7d52023-08-22 15:41:36 +08002457
2458void reset_guard_interval(int radioIndex)
2459{
2460 char buf[MAX_BUF_SIZE] = {0};
2461 int res;
2462 FILE *f = NULL;
2463
2464 res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
2465 if (os_snprintf_error(sizeof(buf), res)) {
2466 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2467 return;
2468 }
2469 f = fopen(buf, "w");
2470 if (f == NULL)
2471 return;
2472 fprintf(f, "%s", "auto");
2473 if (fclose(f) == EOF)
2474 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
2475}
2476
developerfead3972023-05-25 20:15:02 +08002477void update_radio_reset_cnt(int radioIndex)
2478{
developerfead3972023-05-25 20:15:02 +08002479 char buf[MAX_BUF_SIZE] = {0};
2480 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08002481 int res;
developerfead3972023-05-25 20:15:02 +08002482
developer8078acf2023-08-04 18:52:48 +08002483 res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
2484 RADIO_RESET_FILE, radioIndex );
2485 if (res) {
2486 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002487 }
2488
developerfead3972023-05-25 20:15:02 +08002489 if (strlen(buf) == 0)
developer8078acf2023-08-04 18:52:48 +08002490 res =_syscmd_secure(buf, sizeof(buf), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
developerfead3972023-05-25 20:15:02 +08002491 else {
2492 reset_count = atol(buf);
2493 reset_count++;
developer8078acf2023-08-04 18:52:48 +08002494 res = _syscmd_secure(buf,sizeof(buf), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
developere40952c2023-06-15 18:46:43 +08002495 }
developer8078acf2023-08-04 18:52:48 +08002496
2497 if (res) {
2498 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developerfead3972023-05-25 20:15:02 +08002499 }
developerfead3972023-05-25 20:15:02 +08002500}
developer72fb0bb2023-01-11 09:46:29 +08002501
2502/* wifi_factoryResetRadio() function */
2503/**
2504* @description Restore selected radio parameters without touching access point parameters
2505*
2506* @param radioIndex - Index of Wi-Fi Radio channel
2507*
2508* @return The status of the operation.
2509* @retval RETURN_OK if successful.
2510* @retval RETURN_ERR if any error is detected
2511*
2512* @execution Synchronous.
2513* @sideeffect None.
2514*
2515* @note This function must not suspend and must not invoke any blocking system
2516* calls. It should probably just send a message to a driver event handler task.
2517*
2518*/
2519INT wifi_factoryResetRadio(int radioIndex) //RDKB
2520{
developer47cc27a2023-05-17 23:09:58 +08002521 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002522
developerb2977562023-05-24 17:54:12 +08002523 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08002524
developerb2977562023-05-24 17:54:12 +08002525 /*reset gi setting*/
developerd08b7d52023-08-22 15:41:36 +08002526 reset_guard_interval(radioIndex);
2527
developerb2977562023-05-24 17:54:12 +08002528 /*TBD: check mbss issue*/
2529 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08002530 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08002531
developer47cc27a2023-05-17 23:09:58 +08002532 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2533 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002534}
2535
2536/* wifi_initRadio() function */
2537/**
2538* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08002539* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08002540* different hardware implementations may have different initilization requirements.
2541* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
2542*
2543* @return The status of the operation.
2544* @retval RETURN_OK if successful.
2545* @retval RETURN_ERR if any error is detected
2546*
2547* @execution Synchronous.
2548* @sideeffect None.
2549*
2550* @note This function must not suspend and must not invoke any blocking system
2551* calls. It should probably just send a message to a driver event handler task.
2552*
2553*/
2554INT wifi_initRadio(INT radioIndex)
2555{
developera3511852023-06-14 14:12:59 +08002556 //TODO: Initializes the wifi subsystem (for specified radio)
2557 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002558}
2559
developerb717e062023-11-17 14:13:19 +08002560USHORT cfgmode_to_wmode(UCHAR cfg_mode)
2561{
2562 if (cfg_mode >= PHY_MODE_MAX)
2563 cfg_mode = PHY_MODE_MAX;
2564
2565 return CFG_WMODE_MAP[cfg_mode * 2 + 1];
2566}
2567
2568INT wlan_config_set_ch_band(unsigned int wmode)
2569{
2570 int band = band_2_4;
2571
2572 /* do not change sequence due to 6GHz might include AC/GN then confused */
2573 if (WMODE_CAP_6G(wmode))
2574 band = band_6;
2575 else if (WMODE_CAP_5G(wmode))
2576 band = band_5;
2577
2578 return band;
2579}
2580
2581
developer17038e62023-03-02 14:43:43 +08002582static void
2583wifi_ParseProfile(void)
2584{
developere40952c2023-06-15 18:46:43 +08002585 int i, res;
developera3511852023-06-14 14:12:59 +08002586 int max_radio_num = 0;
2587 int card_idx;
2588 int band_idx;
2589 int phy_idx = 0;
2590 int wireless_mode = 0;
2591 char buf[MAX_BUF_SIZE] = {0};
2592 char chip_name[12];
2593 char card_profile[MAX_BUF_SIZE] = {0};
2594 char band_profile[MAX_BUF_SIZE] = {0};
developerb717e062023-11-17 14:13:19 +08002595 unsigned int wmode;
developer17038e62023-03-02 14:43:43 +08002596
developera3511852023-06-14 14:12:59 +08002597 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08002598
developera3511852023-06-14 14:12:59 +08002599 memset(main_prefix, 0, sizeof(main_prefix));
2600 memset(ext_prefix, 0, sizeof(ext_prefix));
2601 memset(default_ssid, 0, sizeof(default_ssid));
2602 for (i = 0; i < MAX_NUM_RADIOS; i++)
2603 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08002604
developera3511852023-06-14 14:12:59 +08002605 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
2606 /* LOG */
developer17038e62023-03-02 14:43:43 +08002607 return;
developera3511852023-06-14 14:12:59 +08002608 }
developer17038e62023-03-02 14:43:43 +08002609
developera3511852023-06-14 14:12:59 +08002610 for (card_idx = 0; card_idx < 3; card_idx++) {
developere40952c2023-06-15 18:46:43 +08002611 res = snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
2612 if (os_snprintf_error(sizeof(buf), res)) {
2613 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2614 return;
2615 }
developera3511852023-06-14 14:12:59 +08002616 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
2617 break;
2618 }
developere40952c2023-06-15 18:46:43 +08002619 res = snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
2620 if (os_snprintf_error(sizeof(buf), res)) {
2621 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2622 return;
2623 }
developera3511852023-06-14 14:12:59 +08002624 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
2625 break;
2626 }
2627 for (band_idx = 0; band_idx < 3; band_idx++) {
developere40952c2023-06-15 18:46:43 +08002628 res = snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
2629 if (os_snprintf_error(sizeof(buf), res)) {
2630 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2631 return;
2632 }
developera3511852023-06-14 14:12:59 +08002633 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
2634 /* LOG */
developerc3556192023-12-06 17:59:09 +08002635 continue;
developera3511852023-06-14 14:12:59 +08002636 }
developer17038e62023-03-02 14:43:43 +08002637
developere40952c2023-06-15 18:46:43 +08002638 res = snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
2639 if (os_snprintf_error(sizeof(buf), res)) {
2640 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2641 return;
2642 }
developera3511852023-06-14 14:12:59 +08002643 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
2644 /* LOG */
2645 }
developer17038e62023-03-02 14:43:43 +08002646
developere40952c2023-06-15 18:46:43 +08002647 res = snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
2648 if (os_snprintf_error(sizeof(buf), res)) {
2649 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2650 return;
2651 }
developera3511852023-06-14 14:12:59 +08002652 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
2653 /* LOG */
2654 }
developer17038e62023-03-02 14:43:43 +08002655
developera3511852023-06-14 14:12:59 +08002656 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
2657 /* LOG */
2658 }
2659 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
2660 /* LOG */
2661 }
developer745f0bd2023-03-06 14:32:53 +08002662
developera3511852023-06-14 14:12:59 +08002663 wireless_mode = atoi(buf);
developerb717e062023-11-17 14:13:19 +08002664 wmode = cfgmode_to_wmode(wireless_mode);
2665 radio_band[phy_idx] = wlan_config_set_ch_band(wmode);
developera3511852023-06-14 14:12:59 +08002666 phy_idx++;
developerc3556192023-12-06 17:59:09 +08002667 g_phy_count = phy_idx;
developera3511852023-06-14 14:12:59 +08002668 }
2669 }
developer17038e62023-03-02 14:43:43 +08002670
developera3511852023-06-14 14:12:59 +08002671 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08002672}
2673
2674static void
developerd14dff12023-06-28 22:47:44 +08002675wifi_PrepareDefaultHostapdConfigs(bool reset)
developer17038e62023-03-02 14:43:43 +08002676{
developere40952c2023-06-15 18:46:43 +08002677 int radio_idx, res;
developer0132ed92023-03-21 13:48:53 +08002678 int bss_idx;
2679 int ap_idx;
developer8078acf2023-08-04 18:52:48 +08002680
developerb149d9d2023-06-06 16:14:22 +08002681 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer0132ed92023-03-21 13:48:53 +08002682 char ssid[MAX_BUF_SIZE] = {0};
2683 char interface[32] = {0};
developer7afe45d2023-12-15 17:45:51 +08002684 char bridge[32] = {0};
developer0132ed92023-03-21 13:48:53 +08002685 char ret_buf[MAX_BUF_SIZE] = {0};
2686 char psk_file[64] = {0};
developer7afe45d2023-12-15 17:45:51 +08002687 struct params params[4];
developer17038e62023-03-02 14:43:43 +08002688
developer0132ed92023-03-21 13:48:53 +08002689 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2690 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08002691
developerbb9b20f2023-10-17 18:46:37 +08002692 for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
developerc3556192023-12-06 17:59:09 +08002693 if (array_index_to_vap_index(radio_idx, bss_idx, &ap_idx) != RETURN_OK) {
2694 wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radio_idx, bss_idx);
2695 continue;
2696 }
developer0132ed92023-03-21 13:48:53 +08002697
developere40952c2023-06-15 18:46:43 +08002698 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
2699 if (os_snprintf_error(sizeof(config_file), res)) {
2700 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2701 return;
2702 }
developerd14dff12023-06-28 22:47:44 +08002703 if (access(config_file, F_OK) == 0 && reset == FALSE)
2704 continue;
developer8078acf2023-08-04 18:52:48 +08002705 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
2706 if (res) {
2707 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002708 }
developer8078acf2023-08-04 18:52:48 +08002709
developera73adb82023-11-13 14:09:37 +08002710 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_MLD, bss_idx);
2711 if (os_snprintf_error(sizeof(ssid), res)) {
2712 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2713 return;
2714 }
developer17038e62023-03-02 14:43:43 +08002715
developer7afe45d2023-12-15 17:45:51 +08002716 res = snprintf(bridge, sizeof(bridge), "brlan%d", bss_idx);
2717 if (os_snprintf_error(sizeof(bridge), res)) {
2718 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2719 return;
2720 }
2721
developer47cc27a2023-05-17 23:09:58 +08002722 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08002723 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
2724 if (os_snprintf_error(sizeof(interface), res)) {
2725 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2726 return;
2727 }
developer47cc27a2023-05-17 23:09:58 +08002728 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08002729 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
2730 if (os_snprintf_error(sizeof(interface), res)) {
2731 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2732 return;
2733 }
developer47cc27a2023-05-17 23:09:58 +08002734 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08002735 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
2736 if (os_snprintf_error(sizeof(interface), res)) {
2737 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2738 return;
2739 }
developer47cc27a2023-05-17 23:09:58 +08002740 }
developer17038e62023-03-02 14:43:43 +08002741
developer47cc27a2023-05-17 23:09:58 +08002742 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08002743 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
2744 if (os_snprintf_error(sizeof(psk_file), res)) {
2745 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2746 return;
2747 }
developer17038e62023-03-02 14:43:43 +08002748
developer47cc27a2023-05-17 23:09:58 +08002749 params[0].name = "ssid";
2750 params[0].value = ssid;
2751 params[1].name = "interface";
2752 params[1].value = interface;
2753 params[2].name = "wpa_psk_file";
2754 params[2].value = psk_file;
developer7afe45d2023-12-15 17:45:51 +08002755 params[3].name = "bridge";
2756 params[3].value = bridge;
developer17038e62023-03-02 14:43:43 +08002757
developer7afe45d2023-12-15 17:45:51 +08002758 wifi_hostapdWrite(config_file, params, sizeof(params) / sizeof(params[0]));
developer0132ed92023-03-21 13:48:53 +08002759 }
2760 }
2761 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08002762}
2763
developerd52547a2023-12-26 20:01:42 +08002764typedef long time_t;
2765static time_t radio_up_time[MAX_NUM_RADIOS];
2766
developer17038e62023-03-02 14:43:43 +08002767static void
developer4fe22c62023-08-03 13:23:58 +08002768wifiBringUpInterfacesForRadio(int radio_idx)
2769{
2770 int bss_idx;
2771 int ap_idx;
2772 char cmd[MAX_CMD_SIZE] = {0};
2773 char config_file[MAX_SUB_CMD_SIZE] = {0};
2774 char ret_buf[MAX_BUF_SIZE] = {0};
2775 char inf_name[IF_NAME_SIZE] = {0};
developer82160f02023-08-19 15:30:44 +08002776 int res, ret, bss_num;
developer4fe22c62023-08-03 13:23:58 +08002777
2778 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2779
2780 bss_idx = 0;
developer82160f02023-08-19 15:30:44 +08002781
2782 ret = wifi_BandProfileRead(0, radio_idx, "BssidNum", ret_buf, sizeof(ret_buf), "1");
2783 if (ret != 0) {
2784 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
2785 return;
2786 }
2787
2788 bss_num = atoi(ret_buf);
2789 if (bss_num <= 0) {
2790 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", ret_buf);
2791 return ;
2792 }
developerbb9b20f2023-10-17 18:46:37 +08002793
2794 if (bss_num > LOGAN_MAX_NUM_VAP_PER_RADIO) {
2795 wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
2796 bss_num = LOGAN_MAX_NUM_VAP_PER_RADIO;
2797 }
2798
developer82160f02023-08-19 15:30:44 +08002799 wifi_debug(DEBUG_ERROR, "band %d BssidNum %d\n", radio_idx, bss_num);
developer4fe22c62023-08-03 13:23:58 +08002800 /*TBD: we need refine setup flow and mbss flow*/
developer82160f02023-08-19 15:30:44 +08002801 for (bss_idx = 0; bss_idx < bss_num; bss_idx++) {
developerc3556192023-12-06 17:59:09 +08002802 if (array_index_to_vap_index(radio_idx, bss_idx, &ap_idx) != RETURN_OK) {
2803 wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radio_idx, bss_idx);
2804 continue;
2805 }
developer4fe22c62023-08-03 13:23:58 +08002806
developer9635f402023-12-25 19:48:21 +08002807 /* For main interface, always bring it up firstly.
2808 * The purpose is that the non-main interfaces could be added successfully.
2809 */
2810 if (getVapEnableConfig(ap_idx) == FALSE && !is_main_vap_index(ap_idx))
2811 continue;
2812
2813 wifi_debug(DEBUG_NOTICE, "bring up vap[%d]\n", ap_idx);
2814
developere7e0ae42023-08-17 09:29:49 +08002815 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s%d.psk", PSK_FILE, ap_idx);
2816 if (res) {
2817 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer4fe22c62023-08-03 13:23:58 +08002818 }
developer4fe22c62023-08-03 13:23:58 +08002819
2820 memset(cmd, 0, MAX_CMD_SIZE);
2821 memset(ret_buf, 0, MAX_BUF_SIZE);
2822
2823 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
2824 if (os_snprintf_error(sizeof(cmd), res)) {
2825 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2826 return;
2827 }
developer82160f02023-08-19 15:30:44 +08002828
developere7e0ae42023-08-17 09:29:49 +08002829 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radio_idx, config_file);
2830 if (res) {
2831 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer4fe22c62023-08-03 13:23:58 +08002832 }
developer4fe22c62023-08-03 13:23:58 +08002833
developer9635f402023-12-25 19:48:21 +08002834 /* For main interface, bring it down if it is disabled, by using 'ifconfig rax0 down'.*/
2835 if (getVapEnableConfig(ap_idx) == FALSE && is_main_vap_index(ap_idx))
2836 wifi_setApEnable(ap_idx, FALSE);
2837
developer4fe22c62023-08-03 13:23:58 +08002838 wifi_GetInterfaceName(ap_idx, inf_name);
developer82160f02023-08-19 15:30:44 +08002839 wifi_debug(DEBUG_ERROR, "bring up %s\n", inf_name);
developer4fe22c62023-08-03 13:23:58 +08002840
2841 memset(cmd, 0, MAX_CMD_SIZE);
2842 memset(ret_buf, 0, MAX_BUF_SIZE);
2843
2844 /* fix vap-status file */
developere7e0ae42023-08-17 09:29:49 +08002845 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "sed -i \"s/^%s=.*/%s=1/\" %s", inf_name, inf_name, VAP_STATUS_FILE);
2846 if (res) {
2847 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer4fe22c62023-08-03 13:23:58 +08002848 }
developere7e0ae42023-08-17 09:29:49 +08002849
developer82160f02023-08-19 15:30:44 +08002850 }
developer4fe22c62023-08-03 13:23:58 +08002851
2852 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2853}
2854
developer4fe22c62023-08-03 13:23:58 +08002855static void
2856wifi_BringUpInterfaces(void)
2857{
2858 int radio_idx;
2859 int band_idx;
developerd52547a2023-12-26 20:01:42 +08002860 struct timeval tv_now;
developer4fe22c62023-08-03 13:23:58 +08002861
2862 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercd0b70a2023-12-11 11:25:50 +08002863
2864 for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
developer4fe22c62023-08-03 13:23:58 +08002865 band_idx = radio_index_to_band(radio_idx);
2866 if (band_idx < 0) {
2867 break;
2868 }
2869 wifiBringUpInterfacesForRadio(radio_idx);
developerd52547a2023-12-26 20:01:42 +08002870
2871 gettimeofday(&tv_now, NULL);
2872 radio_up_time[radio_idx] = tv_now.tv_sec;
developer4fe22c62023-08-03 13:23:58 +08002873 }
2874 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2875}
2876
2877static void
developer17038e62023-03-02 14:43:43 +08002878wifi_BringDownInterfacesForRadio(int radio_idx)
2879{
developer8078acf2023-08-04 18:52:48 +08002880
developera3511852023-06-14 14:12:59 +08002881 char ret_buf[MAX_BUF_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08002882 int res;
developerb758dfd2023-06-21 17:32:07 +08002883
developera3511852023-06-14 14:12:59 +08002884 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08002885
developer8078acf2023-08-04 18:52:48 +08002886 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
2887 if (res) {
2888 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002889 }
developer8a3bbbf2023-03-15 17:47:23 +08002890
developera3511852023-06-14 14:12:59 +08002891 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08002892}
2893
2894
2895static void
2896wifi_BringDownInterfaces(void)
2897{
developera3511852023-06-14 14:12:59 +08002898 int radio_idx;
2899 int band_idx;
developer17038e62023-03-02 14:43:43 +08002900
developera3511852023-06-14 14:12:59 +08002901 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercd0b70a2023-12-11 11:25:50 +08002902 for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
developera3511852023-06-14 14:12:59 +08002903 band_idx = radio_index_to_band(radio_idx);
2904 if (band_idx < 0) {
2905 break;
2906 }
2907 wifi_BringDownInterfacesForRadio(radio_idx);
2908 }
2909 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08002910}
2911
developerb2977562023-05-24 17:54:12 +08002912static void wifi_dat_file_reset_by_radio(char radio_idx)
2913{
developer8078acf2023-08-04 18:52:48 +08002914
developerb2977562023-05-24 17:54:12 +08002915 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08002916 char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
2917 char dat_file[MAX_SUB_CMD_SIZE]= {0};
developere40952c2023-06-15 18:46:43 +08002918 int res;
developerb2977562023-05-24 17:54:12 +08002919
developere40952c2023-06-15 18:46:43 +08002920 res = snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
2921 if (os_snprintf_error(sizeof(rom_dat_file), res)) {
2922 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2923 return;
2924 }
2925 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
2926 if (os_snprintf_error(sizeof(dat_file), res)) {
2927 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2928 return;
2929 }
developerb2977562023-05-24 17:54:12 +08002930
developer8078acf2023-08-04 18:52:48 +08002931 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp -rf %s %s", rom_dat_file, dat_file);
2932 if (res) {
2933 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
2934 }
developerb2977562023-05-24 17:54:12 +08002935}
2936
developer47cc27a2023-05-17 23:09:58 +08002937static void wifi_psk_file_reset()
2938{
developer47cc27a2023-05-17 23:09:58 +08002939 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08002940 char psk_file[MAX_SUB_CMD_SIZE]= {0};
developer47cc27a2023-05-17 23:09:58 +08002941 char vap_idx = 0;
developere40952c2023-06-15 18:46:43 +08002942 int res;
developer47cc27a2023-05-17 23:09:58 +08002943
2944 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
developere40952c2023-06-15 18:46:43 +08002945 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
2946 if (os_snprintf_error(sizeof(psk_file), res)) {
2947 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2948 return;
2949 }
developer47cc27a2023-05-17 23:09:58 +08002950
2951 if (access(psk_file, F_OK) != 0) {
developer8078acf2023-08-04 18:52:48 +08002952 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", psk_file);
2953 if (res) {
2954 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002955 }
developer47cc27a2023-05-17 23:09:58 +08002956 } else {
developere40952c2023-06-15 18:46:43 +08002957
developer8078acf2023-08-04 18:52:48 +08002958 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "echo '' > %s", psk_file);
2959 if (res) {
2960 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
2961 }
developer47cc27a2023-05-17 23:09:58 +08002962 }
2963 }
developerb2977562023-05-24 17:54:12 +08002964}
2965
developer8a3bbbf2023-03-15 17:47:23 +08002966static void wifi_vap_status_reset()
2967{
developera3511852023-06-14 14:12:59 +08002968 char ret_buf[MAX_BUF_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08002969 int radio_idx = 0;
developer8a3bbbf2023-03-15 17:47:23 +08002970 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08002971 int res;
developer8666b312023-03-24 14:05:31 +08002972
developer8a3bbbf2023-03-15 17:47:23 +08002973 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developer8078acf2023-08-04 18:52:48 +08002974 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", VAP_STATUS_FILE);
2975 if (res) {
2976 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002977 }
developer8a3bbbf2023-03-15 17:47:23 +08002978 } else {
developer8078acf2023-08-04 18:52:48 +08002979 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "echo '' > %s", VAP_STATUS_FILE);
2980 if (res) {
2981 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002982 }
developer8a3bbbf2023-03-15 17:47:23 +08002983 }
2984
developer8a3bbbf2023-03-15 17:47:23 +08002985 memset(ret_buf, 0, MAX_BUF_SIZE);
2986
2987 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
developerbb9b20f2023-10-17 18:46:37 +08002988 for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
developer82160f02023-08-19 15:30:44 +08002989 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "echo %s%d=0 >> /nvram/vap-status", ext_prefix[radio_idx], bss_idx);
developer8078acf2023-08-04 18:52:48 +08002990 if (res) {
2991 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08002992 }
developer8a3bbbf2023-03-15 17:47:23 +08002993 }
2994
developerfead3972023-05-25 20:15:02 +08002995}
2996
2997static void wifi_radio_reset_count_reset()
2998{
developera3511852023-06-14 14:12:59 +08002999 char ret_buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08003000 int res;
developera19a38f2023-11-27 19:30:48 +08003001 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08003002
developera73adb82023-11-13 14:09:37 +08003003 if (access(RADIO_RESET_FILE, F_OK) != 0) {
developer8078acf2023-08-04 18:52:48 +08003004 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", RADIO_RESET_FILE);
3005 if (res) {
3006 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003007 }
developerfead3972023-05-25 20:15:02 +08003008 }
developera19a38f2023-11-27 19:30:48 +08003009 f = fopen("/nvram/radio_reset", "w");
3010 if (f == NULL)
3011 return;
3012 fprintf(f, "%s", "reset0=0\n");
3013 fprintf(f, "%s", "reset1=0\n");
3014 fprintf(f, "%s", "reset2=0\n");
3015 if (fclose(f) == EOF)
3016 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developer8a3bbbf2023-03-15 17:47:23 +08003017}
developer17038e62023-03-02 14:43:43 +08003018
developer179a1522023-11-14 13:52:36 +08003019static void wifi_guard_interval_file_check()
3020{
3021 char ret_buf[MAX_BUF_SIZE] = {0};
3022 int res;
3023 unsigned char i = 0;
3024 char file[MAX_SUB_CMD_SIZE] = {0};
3025 FILE *f = NULL;
developer179a1522023-11-14 13:52:36 +08003026
developercd0b70a2023-12-11 11:25:50 +08003027 for (i = 0; i < get_runtime_max_radio(); i++) {
developer179a1522023-11-14 13:52:36 +08003028 res = snprintf(file, sizeof(file), "%s%d.txt", GUARD_INTERVAL_FILE, i);
3029 if (os_snprintf_error(sizeof(file), res)) {
3030 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3031 }
3032 wifi_debug(DEBUG_ERROR, "%s:file %s", __func__, file);
3033 if (access(file, F_OK) != 0) {
3034 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
3035 if (res) {
3036 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
3037 }
3038 }
3039 f = fopen(file, "w");
3040 if (f == NULL)
3041 return;
3042 fprintf(f, "%s", "auto");
3043 if (fclose(f) == EOF)
3044 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
3045 }
3046}
3047
3048static void wifi_power_percentage_file_check()
3049{
3050 char ret_buf[MAX_BUF_SIZE] = {0};
3051 int res;
3052 unsigned char band = 0;
3053 char file[MAX_SUB_CMD_SIZE] = {0};
3054 FILE *f = NULL;
3055
3056 for (band = band_2_4; band <= band_6; band++) {
3057 res = snprintf(file, sizeof(file), "%s%d.txt", POWER_PERCENTAGE, band);
3058 if (os_snprintf_error(sizeof(file), res)) {
3059 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3060 }
3061 wifi_debug(DEBUG_ERROR, "%s:file %s", __func__, file);
3062 if (access(file, F_OK) != 0) {
3063 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
3064 if (res) {
3065 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
3066 }
3067 }
3068 f = fopen(file, "w");
3069 if (f == NULL)
3070 return;
3071 fprintf(f, "%s", "100");
3072 if (fclose(f) == EOF)
3073 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
3074 }
3075}
3076
3077static void wifi_mcs_file_check()
3078{
3079 char ret_buf[MAX_BUF_SIZE] = {0};
3080 int res;
3081 unsigned char i = 0;
3082 char file[MAX_SUB_CMD_SIZE] = {0};
3083 FILE *f = NULL;
developer179a1522023-11-14 13:52:36 +08003084
developercd0b70a2023-12-11 11:25:50 +08003085 for (i = 0; i < get_runtime_max_radio(); i++) {
developer179a1522023-11-14 13:52:36 +08003086 res = snprintf(file, sizeof(file), "%s%d.txt", MCS_FILE, i);
3087 if (os_snprintf_error(sizeof(file), res)) {
3088 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3089 }
3090 wifi_debug(DEBUG_ERROR, "%s:file %s", __func__, file);
3091 if (access(file, F_OK) != 0) {
3092 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
3093 if (res) {
3094 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
3095 }
3096 }
3097 f = fopen(file, "w");
3098 if (f == NULL)
3099 return;
3100 fprintf(f, "%s", "11");
3101 if (fclose(f) == EOF)
3102 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
3103 }
3104}
3105
developera19a38f2023-11-27 19:30:48 +08003106static void wifi_upload_reset()
3107{
3108 FILE *f = NULL;
3109
3110 if (access("/tmp/upload", F_OK) != 0) {
3111 f = fopen("/tmp/upload", "w+");
3112 if (f == NULL)
3113 return;
3114 fprintf(f, "%s", "5");
3115 if (fclose(f) == EOF)
3116 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
3117 }
3118}
developer179a1522023-11-14 13:52:36 +08003119
developer72fb0bb2023-01-11 09:46:29 +08003120// Initializes the wifi subsystem (all radios)
developera3511852023-06-14 14:12:59 +08003121INT wifi_init() //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003122{
developera3511852023-06-14 14:12:59 +08003123 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercc9a4f32023-05-30 17:40:02 +08003124 static int CallOnce = 1;
developera19a38f2023-11-27 19:30:48 +08003125
developera3511852023-06-14 14:12:59 +08003126 //Not intitializing macfilter for Turris-Omnia Platform for now
3127 //macfilter_init();
3128 if (CallOnce) {
developercc9a4f32023-05-30 17:40:02 +08003129 wifi_ParseProfile();
developerd14dff12023-06-28 22:47:44 +08003130 wifi_PrepareDefaultHostapdConfigs(FALSE);
developer9635f402023-12-25 19:48:21 +08003131 wifi_PrepareEnableSSIDConfig(FALSE);
developercc9a4f32023-05-30 17:40:02 +08003132 wifi_psk_file_reset();
developer33f13ba2023-07-12 16:19:06 +08003133 //v_secure_system("/usr/sbin/iw reg set US");
3134 v_secure_system("systemctl start hostapd.service");
developercc9a4f32023-05-30 17:40:02 +08003135 sleep(2);
developerc338aba2023-08-09 13:56:42 +08003136 setbuf(stdout, NULL);
developercc9a4f32023-05-30 17:40:02 +08003137 wifi_vap_status_reset();
3138 wifi_radio_reset_count_reset();
developer4fe22c62023-08-03 13:23:58 +08003139 wifi_BringUpInterfaces();
developer6c6ef372023-11-08 10:59:14 +08003140 eht_mld_config_init();
developercc9a4f32023-05-30 17:40:02 +08003141 CallOnce = 0;
developer6c6ef372023-11-08 10:59:14 +08003142 mld_info_display();
developer179a1522023-11-14 13:52:36 +08003143 wifi_guard_interval_file_check();
3144 wifi_power_percentage_file_check();
3145 wifi_mcs_file_check();
developera19a38f2023-11-27 19:30:48 +08003146 /* for wifiagent TDK test */
3147 wifi_upload_reset();
developera3511852023-06-14 14:12:59 +08003148 }
developer96b38512023-02-22 11:17:45 +08003149
developera3511852023-06-14 14:12:59 +08003150 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003151
developera3511852023-06-14 14:12:59 +08003152 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003153}
3154
3155/* wifi_reset() function */
3156/**
3157* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08003158* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08003159* different hardware implementations may have different requirements.
3160* Parameters : None
3161*
3162* @return The status of the operation.
3163* @retval RETURN_OK if successful.
3164* @retval RETURN_ERR if any error is detected
3165*
3166* @execution Synchronous.
3167* @sideeffect None.
3168*
3169* @note This function must not suspend and must not invoke any blocking system
3170* calls. It should probably just send a message to a driver event handler task.
3171*
3172*/
3173INT wifi_reset()
3174{
developera19a38f2023-11-27 19:30:48 +08003175 int radio_idx;
developera3511852023-06-14 14:12:59 +08003176 wifi_BringDownInterfaces();
3177 sleep(2);
developer17038e62023-03-02 14:43:43 +08003178
developera3511852023-06-14 14:12:59 +08003179 //TODO: resets the wifi subsystem, deletes all APs
developer33f13ba2023-07-12 16:19:06 +08003180 v_secure_system("systemctl stop hostapd.service");
developera3511852023-06-14 14:12:59 +08003181 sleep(2);
developer17038e62023-03-02 14:43:43 +08003182
developer33f13ba2023-07-12 16:19:06 +08003183 v_secure_system("systemctl start hostapd.service");
developera3511852023-06-14 14:12:59 +08003184 sleep(5);
developer17038e62023-03-02 14:43:43 +08003185
developerd14dff12023-06-28 22:47:44 +08003186 wifi_PrepareDefaultHostapdConfigs(TRUE);
developer9635f402023-12-25 19:48:21 +08003187 wifi_PrepareEnableSSIDConfig(TRUE);
developer47cc27a2023-05-17 23:09:58 +08003188 wifi_psk_file_reset();
developer4fe22c62023-08-03 13:23:58 +08003189 wifi_BringUpInterfaces();
developera3511852023-06-14 14:12:59 +08003190 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08003191
3192 wifi_vap_status_reset();
developera19a38f2023-11-27 19:30:48 +08003193 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
3194 update_radio_reset_cnt(radio_idx);
developer8a3bbbf2023-03-15 17:47:23 +08003195
developera3511852023-06-14 14:12:59 +08003196 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003197}
3198
3199/* wifi_down() function */
3200/**
3201* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08003202* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08003203* different hardware implementations may have different requirements.
3204*
3205* @param None
3206*
3207* @return The status of the operation
3208* @retval RETURN_OK if successful
3209* @retval RETURN_ERR if any error is detected
3210*
3211* @execution Synchronous
3212* @sideeffect None
3213*
3214* @note This function must not suspend and must not invoke any blocking system
3215* calls. It should probably just send a message to a driver event handler task.
3216*
3217*/
3218INT wifi_down()
3219{
developera3511852023-06-14 14:12:59 +08003220 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
developercd0b70a2023-12-11 11:25:50 +08003221
3222 for (int radioIndex = 0; radioIndex < get_runtime_max_radio(); radioIndex++)
developerb2977562023-05-24 17:54:12 +08003223 wifi_setRadioEnable(radioIndex, FALSE);
3224
developera3511852023-06-14 14:12:59 +08003225 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003226}
3227
3228
3229/* wifi_createInitialConfigFiles() function */
3230/**
3231* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08003232* and content of these files are implementation dependent. This function call is
3233* used to trigger this task if necessary. Some implementations may not need this
3234* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08003235* do nothing and return RETURN_OK.
3236*
3237* @param None
3238*
3239* @return The status of the operation
3240* @retval RETURN_OK if successful
3241* @retval RETURN_ERR if any error is detected
3242*
3243* @execution Synchronous
3244* @sideeffect None
3245*
3246* @note This function must not suspend and must not invoke any blocking system
3247* calls. It should probably just send a message to a driver event handler task.
3248*
3249*/
3250INT wifi_createInitialConfigFiles()
3251{
developera3511852023-06-14 14:12:59 +08003252 //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)
3253 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003254}
3255
developer7e4a2a62023-04-06 19:56:03 +08003256/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08003257INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
3258{
developera3511852023-06-14 14:12:59 +08003259 int ret;
developer72fb0bb2023-01-11 09:46:29 +08003260
developera3511852023-06-14 14:12:59 +08003261 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08003262
developera3511852023-06-14 14:12:59 +08003263 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
3264 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08003265 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead CountryCode failed\n");
developera3511852023-06-14 14:12:59 +08003266 return RETURN_ERR;
3267 }
developer7e4a2a62023-04-06 19:56:03 +08003268
developera3511852023-06-14 14:12:59 +08003269 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08003270
developera3511852023-06-14 14:12:59 +08003271 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003272}
3273
3274INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
3275{
developer7e4a2a62023-04-06 19:56:03 +08003276 /*Set wifi config. Wait for wifi reset to apply*/
developer7e4a2a62023-04-06 19:56:03 +08003277 struct params params;
3278 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08003279 int ret = 0, res;
developera47dfe22023-12-21 16:02:31 +08003280 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08003281
developer7e4a2a62023-04-06 19:56:03 +08003282 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003283
developer7e4a2a62023-04-06 19:56:03 +08003284 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
3285 printf("%s: input para error!!!\n", __func__);
3286 return RETURN_ERR;
3287 }
developer72fb0bb2023-01-11 09:46:29 +08003288
developerc79e9172023-06-06 19:48:03 +08003289 if (!strlen(CountryCode)) {
3290 memcpy(CountryCode, "US", strlen("US")); /*default set the code to US*/
3291 CountryCode[2] = '\0';
3292 }
developer72fb0bb2023-01-11 09:46:29 +08003293
developer7e4a2a62023-04-06 19:56:03 +08003294 params.name = "country_code";
3295 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08003296
developera47dfe22023-12-21 16:02:31 +08003297 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
3298 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
3299 return RETURN_ERR;
3300 }
3301 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developere40952c2023-06-15 18:46:43 +08003302 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
3303 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3304 return RETURN_ERR;
3305 }
developer7e4a2a62023-04-06 19:56:03 +08003306 ret = wifi_hostapdWrite(config_file, &params, 1);
3307
3308 if (ret) {
3309 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
3310 __func__, ret);
3311 }
3312
3313 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3314
3315 if (ret) {
3316 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
3317 __func__, ret);
3318 }
3319
3320 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3321
3322 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003323}
3324
3325INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
3326{
developera3511852023-06-14 14:12:59 +08003327 char interface_name[16] = {0};
3328 char channel_util_file[64] = {0};
3329 char cmd[128] = {0};
3330 char buf[128] = {0};
3331 char *line = NULL;
3332 char *param = NULL, *value = NULL;
developere40952c2023-06-15 18:46:43 +08003333 int read = 0, res;
developera3511852023-06-14 14:12:59 +08003334 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
developer86035662023-06-28 19:21:12 +08003335 unsigned long preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
developerc14d83a2023-06-29 20:09:42 +08003336 long int rssi;
3337 long int tmp_l;
3338 unsigned long tmp_ul;
developera3511852023-06-14 14:12:59 +08003339 size_t len = 0;
3340 FILE *f = NULL;
developerc3556192023-12-06 17:59:09 +08003341 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08003342
developera3511852023-06-14 14:12:59 +08003343 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003344
developerc3556192023-12-06 17:59:09 +08003345 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
3346 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
3347 }
3348
3349 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08003350 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +08003351
3352 res = _syscmd_secure(buf, sizeof(buf), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
3353 if (res) {
3354 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003355 }
3356
developerc14d83a2023-06-29 20:09:42 +08003357 if (hal_strtol(buf, 10, &rssi) < 0) {
3358 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3359 }
3360 outputChannelStats2->ch_Max80211Rssi = rssi;
developer72fb0bb2023-01-11 09:46:29 +08003361
developera3511852023-06-14 14:12:59 +08003362 memset(cmd, 0, sizeof(cmd));
3363 memset(buf, 0, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08003364 res = snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
3365 if (os_snprintf_error(sizeof(cmd), res)) {
3366 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3367 return RETURN_ERR;
3368 }
developer8078acf2023-08-04 18:52:48 +08003369 f = v_secure_popen("r","iw %s survey dump | grep 'in use' -A6", interface_name);
3370 if (f == NULL) {
3371 wifi_dbg_printf("%s: v_secure_popen %s error\n", __func__, cmd);
developera3511852023-06-14 14:12:59 +08003372 return RETURN_ERR;
3373 }
developer72fb0bb2023-01-11 09:46:29 +08003374
developera3511852023-06-14 14:12:59 +08003375 read = getline(&line, &len, f);
3376 while (read != -1) {
3377 param = strtok(line, ":\t");
developerc14d83a2023-06-29 20:09:42 +08003378 if (!param) {
3379 read = getline(&line, &len, f);
3380 continue;
3381 }
developera3511852023-06-14 14:12:59 +08003382 value = strtok(NULL, " ");
developerc14d83a2023-06-29 20:09:42 +08003383 if (!value) {
developer37646972023-06-29 10:58:43 +08003384 read = getline(&line, &len, f);
3385 continue;
3386 }
developera3511852023-06-14 14:12:59 +08003387 if(strstr(param, "frequency") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08003388 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
3389 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3390 }
3391 outputChannelStats2->ch_Frequency = tmp_ul;
developera3511852023-06-14 14:12:59 +08003392 }
3393 if(strstr(param, "noise") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08003394 if (hal_strtol(value, 10, &tmp_l) < 0) {
3395 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3396 }
3397 outputChannelStats2->ch_NoiseFloor = tmp_l;
developer37646972023-06-29 10:58:43 +08003398
developerc14d83a2023-06-29 20:09:42 +08003399 if (hal_strtol(value, 10, &tmp_l) < 0) {
3400 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3401 }
3402 outputChannelStats2->ch_Non80211Noise = tmp_l;
developera3511852023-06-14 14:12:59 +08003403 }
3404 if(strstr(param, "channel active time") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08003405 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
3406 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3407 }
3408 ActiveTime = tmp_ul;
developera3511852023-06-14 14:12:59 +08003409 }
developer5b23cd02023-07-19 20:26:03 +08003410 if(strstr(param, "channel busy time") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08003411 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
3412 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3413 }
3414 BusyTime = tmp_ul;
developera3511852023-06-14 14:12:59 +08003415 }
3416 if(strstr(param, "channel transmit time") != NULL) {
developerc14d83a2023-06-29 20:09:42 +08003417 if (hal_strtoul(value, 10, &tmp_ul) < 0) {
3418 wifi_debug(DEBUG_ERROR, "strtol fail\n");
3419 }
3420 TransmitTime = tmp_ul;
developera3511852023-06-14 14:12:59 +08003421 }
3422 read = getline(&line, &len, f);
3423 }
developer8078acf2023-08-04 18:52:48 +08003424 v_secure_pclose(f);
developer72fb0bb2023-01-11 09:46:29 +08003425
developera3511852023-06-14 14:12:59 +08003426 // The file should store the last active, busy and transmit time
developere40952c2023-06-15 18:46:43 +08003427 res = snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
3428 if (os_snprintf_error(sizeof(channel_util_file), res)) {
3429 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3430 return RETURN_ERR;
3431 }
3432
developera3511852023-06-14 14:12:59 +08003433 f = fopen(channel_util_file, "r");
3434 if (f != NULL) {
3435 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08003436 if (hal_strtoul(line, 10, &preActiveTime) < 0) {
3437 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +08003438 }
developera3511852023-06-14 14:12:59 +08003439 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08003440 if (hal_strtoul(line, 10, &preBusyTime) < 0) {
3441 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerb6f05602023-06-30 11:32:41 +08003442
developer86035662023-06-28 19:21:12 +08003443 }
developera3511852023-06-14 14:12:59 +08003444 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08003445 if (hal_strtoul(line, 10, &preTransmitTime) < 0) {
3446 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +08003447 }
developer5b23cd02023-07-19 20:26:03 +08003448
developerc14d83a2023-06-29 20:09:42 +08003449 if (fclose(f) == EOF)
3450 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developer5b23cd02023-07-19 20:26:03 +08003451
developerc14d83a2023-06-29 20:09:42 +08003452 }
3453
developerb14b3462023-07-01 18:02:42 +08003454 /*if (ActiveTime == preActiveTime) {
developer5b23cd02023-07-19 20:26:03 +08003455 wifi_debug(DEBUG_ERROR, "error:ActiveTime[%d] == preActiveTime[%ld]\n",
developerb14b3462023-07-01 18:02:42 +08003456 ActiveTime, preActiveTime);
developerc14d83a2023-06-29 20:09:42 +08003457 return RETURN_ERR;
developerb14b3462023-07-01 18:02:42 +08003458 }*/
developer72fb0bb2023-01-11 09:46:29 +08003459
developera3511852023-06-14 14:12:59 +08003460 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
3461 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
developer72fb0bb2023-01-11 09:46:29 +08003462
developera3511852023-06-14 14:12:59 +08003463 f = fopen(channel_util_file, "w");
3464 if (f != NULL) {
developer86035662023-06-28 19:21:12 +08003465 if (fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime) < 0) {
3466 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
3467 }
3468 if (fclose(f) != 0) {
3469 wifi_debug(DEBUG_ERROR, "fclose fail\n");
3470 }
developera3511852023-06-14 14:12:59 +08003471 }
3472 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3473 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003474}
3475
3476/**********************************************************************************
3477 *
3478 * Wifi radio level function prototypes
3479 *
3480**********************************************************************************/
3481
3482//Get the total number of radios in this wifi subsystem
3483INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
3484{
developera3511852023-06-14 14:12:59 +08003485 if (NULL == output)
3486 return RETURN_ERR;
developercd0b70a2023-12-11 11:25:50 +08003487
3488 *output = get_runtime_max_radio();
developer72fb0bb2023-01-11 09:46:29 +08003489
developera3511852023-06-14 14:12:59 +08003490 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003491}
3492
developer69b61b02023-03-07 17:17:44 +08003493//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08003494INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
3495{
developera3511852023-06-14 14:12:59 +08003496 if (NULL == output)
3497 return RETURN_ERR;
3498 *output = MAX_APS;
developer72fb0bb2023-01-11 09:46:29 +08003499
developera3511852023-06-14 14:12:59 +08003500 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003501}
3502
3503//Get the Radio enable config parameter
developera3511852023-06-14 14:12:59 +08003504INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003505{
developer56fbedb2023-05-30 16:47:05 +08003506 char interface_name[16] = {0};
developer8078acf2023-08-04 18:52:48 +08003507 char buf[128] = {0};
developerc3556192023-12-06 17:59:09 +08003508 int apIndex, bss_idx;
developer3a85ab82023-05-25 11:59:38 +08003509
developer56fbedb2023-05-30 16:47:05 +08003510 if (NULL == output_bool)
3511 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003512
developer56fbedb2023-05-30 16:47:05 +08003513 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08003514
developer56fbedb2023-05-30 16:47:05 +08003515 /* loop all interface in radio, if any is enable, reture true, else return false */
developerc3556192023-12-06 17:59:09 +08003516 for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++)
developer56fbedb2023-05-30 16:47:05 +08003517 {
developerc3556192023-12-06 17:59:09 +08003518 if (array_index_to_vap_index(radioIndex, bss_idx, &apIndex) != RETURN_OK) {
3519 wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, bss_idx %d\n", radioIndex, bss_idx);
3520 continue;
3521 }
developer56fbedb2023-05-30 16:47:05 +08003522 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
3523 continue;
developer8078acf2023-08-04 18:52:48 +08003524
developer8078acf2023-08-04 18:52:48 +08003525 *output_bool = _syscmd_secure(buf, sizeof(buf), "ifconfig %s 2> /dev/null | grep UP", interface_name) ? FALSE : TRUE;
developer56fbedb2023-05-30 16:47:05 +08003526 if (*output_bool == TRUE)
3527 break;
developer8078acf2023-08-04 18:52:48 +08003528
developer56fbedb2023-05-30 16:47:05 +08003529 }
3530
3531 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003532}
3533
developereef7d562023-10-21 16:04:21 +08003534enum mwctl_chan_width {
3535 MWCTL_CHAN_WIDTH_20,
3536 MWCTL_CHAN_WIDTH_40,
3537 MWCTL_CHAN_WIDTH_80,
3538 MWCTL_CHAN_WIDTH_160,
3539 MWCTL_CHAN_WIDTH_320,
3540};
3541
3542struct bw_option {
3543 unsigned int bandwith;
3544 enum mwctl_chan_width mode;
3545};
3546
3547struct bw_option bw_opt[] = {
3548 {20, MWCTL_CHAN_WIDTH_20},
3549 {40, MWCTL_CHAN_WIDTH_40},
3550 {80, MWCTL_CHAN_WIDTH_80},
3551 {160, MWCTL_CHAN_WIDTH_160},
3552 {320, MWCTL_CHAN_WIDTH_320},
3553};
3554
3555INT wifi_setChannel_netlink(INT radioIndex, ULONG* channel, UINT *bandwidth, UCHAR *ext_ch, UCHAR *ht_coex)
3556{
3557 int ret;
3558 int i;
3559 struct unl unl_ins;
3560 struct nl_msg *msg = NULL;
3561 struct nlattr * msg_data = NULL;
3562 struct mtk_nl80211_param param;
3563 bool b_match = FALSE;
3564
3565 /*init mtk nl80211 vendor cmd*/
3566 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
3567 param.if_type = NL80211_ATTR_WIPHY;
3568 param.if_idx = radio_index_to_phy(radioIndex);
3569
3570 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3571 if (ret) {
3572 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3573 return RETURN_ERR;
3574 }
3575
3576 /*add mtk vendor cmd data*/
3577 if (channel != NULL)
3578 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
3579 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
3580 nlmsg_free(msg);
3581 goto err;
3582 }
3583
3584 if (bandwidth != NULL) {
3585 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
3586 if (bw_opt[i].bandwith == *bandwidth) {
3587 b_match = true;
3588 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
3589 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
3590 nlmsg_free(msg);
3591 goto err;
3592 }
3593 break;
3594 }
3595 }
3596
3597 if (!b_match) {
3598 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
3599 nlmsg_free(msg);
3600 goto err;
3601 }
3602 }
3603
3604 if (ext_ch != NULL)
3605 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_HT_EXTCHAN, *ext_ch)) {
3606 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_HT_EXTCHAN attribute error\n");
3607 nlmsg_free(msg);
3608 goto err;
3609 }
3610
3611 if (ht_coex != NULL)
3612 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_HT_COEX, *ht_coex)) {
3613 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_HT_COEX attribute error\n");
3614 nlmsg_free(msg);
3615 goto err;
3616 }
3617
3618 /*send mtk nl80211 vendor msg*/
3619 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3620 if (ret) {
3621 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3622 goto err;
3623 }
3624 /*deinit mtk nl80211 vendor msg*/
3625 mtk_nl80211_deint(&unl_ins);
developer8461fe52023-11-07 16:11:44 +08003626 wifi_debug(DEBUG_INFO, "set cmd success.\n");
developereef7d562023-10-21 16:04:21 +08003627 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3628
3629 return RETURN_OK;
3630err:
3631 mtk_nl80211_deint(&unl_ins);
3632 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3633 return RETURN_ERR;
3634}
3635
3636INT wifi_set80211h_netlink(INT radioIndex, unsigned char enable)
3637{
3638 int ret;
3639 struct unl unl_ins;
3640 struct nl_msg *msg = NULL;
3641 struct nlattr * msg_data = NULL;
3642 struct mtk_nl80211_param param;
3643
3644 /*init mtk nl80211 vendor cmd*/
3645 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_RADIO;
3646 param.if_type = NL80211_ATTR_WIPHY;
3647 param.if_idx = radio_index_to_phy(radioIndex);
3648
3649 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3650 if (ret) {
3651 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3652 return RETURN_ERR;
3653 }
3654
3655 /*add mtk vendor cmd data*/
3656 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_IEEE80211H_INFO, enable)) {
3657 wifi_debug(DEBUG_ERROR, "Nla put IEEE80211H_INFO attribute error\n");
3658 nlmsg_free(msg);
3659 goto err;
3660 }
3661
3662 /*send mtk nl80211 vendor msg*/
3663 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3664 if (ret) {
3665 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3666 goto err;
3667 }
3668 /*deinit mtk nl80211 vendor msg*/
3669 mtk_nl80211_deint(&unl_ins);
3670 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
3671 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3672
3673 return RETURN_OK;
3674err:
3675 mtk_nl80211_deint(&unl_ins);
3676 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3677 return RETURN_ERR;
3678}
3679
developer72fb0bb2023-01-11 09:46:29 +08003680INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
3681{
developera3511852023-06-14 14:12:59 +08003682 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +08003683 char buf[MAX_BUF_SIZE] = {0};
developerc3556192023-12-06 17:59:09 +08003684 int apIndex, bss_idx;
developere40952c2023-06-15 18:46:43 +08003685 int phyId = 0, res;
developerc3556192023-12-06 17:59:09 +08003686 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08003687
developera3511852023-06-14 14:12:59 +08003688 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003689
developera3511852023-06-14 14:12:59 +08003690 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003691
developera3511852023-06-14 14:12:59 +08003692 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08003693
developerc3556192023-12-06 17:59:09 +08003694 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
3695 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
3696 }
3697
3698 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developer47cc27a2023-05-17 23:09:58 +08003699 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08003700
developer8078acf2023-08-04 18:52:48 +08003701
3702 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
3703 if (res) {
3704 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003705 }
developer8078acf2023-08-04 18:52:48 +08003706 memset(buf, 0, MAX_BUF_SIZE);
developer47cc27a2023-05-17 23:09:58 +08003707
developer8078acf2023-08-04 18:52:48 +08003708 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
3709 if (res) {
3710 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003711 }
developer8078acf2023-08-04 18:52:48 +08003712
developere82c0ca2023-05-10 16:25:35 +08003713 if(strncmp(buf, "OK", 2))
developer75bd10c2023-06-27 11:34:08 +08003714 wifi_debug(DEBUG_ERROR, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08003715 } else {
developerc3556192023-12-06 17:59:09 +08003716 for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
3717 if (array_index_to_vap_index(radioIndex, bss_idx, &apIndex) != RETURN_OK) {
3718 wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, bss_idx %d\n", radioIndex, bss_idx);
3719 continue;
3720 }
3721 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
3722 wifi_debug(DEBUG_ERROR, "!!!Fail to get name of apIndex[%d]\n", apIndex);
developera3511852023-06-14 14:12:59 +08003723 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +08003724 }
developer72fb0bb2023-01-11 09:46:29 +08003725
developer8a3bbbf2023-03-15 17:47:23 +08003726 memset(buf, 0, MAX_BUF_SIZE);
3727
developer8078acf2023-08-04 18:52:48 +08003728
3729 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
3730 if (res) {
3731 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003732 }
developer8a3bbbf2023-03-15 17:47:23 +08003733
developera3511852023-06-14 14:12:59 +08003734 if(*buf == '1') {
developer8078acf2023-08-04 18:52:48 +08003735 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up", interface_name);
3736 if (res) {
3737 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003738 }
developer8a3bbbf2023-03-15 17:47:23 +08003739
developer8a3bbbf2023-03-15 17:47:23 +08003740 memset(buf, 0, MAX_BUF_SIZE);
3741
developer8078acf2023-08-04 18:52:48 +08003742 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",phyId,apIndex);
3743 if (res) {
3744 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08003745 }
developera3511852023-06-14 14:12:59 +08003746 }
3747 }
developera3511852023-06-14 14:12:59 +08003748 }
developer72fb0bb2023-01-11 09:46:29 +08003749
developera3511852023-06-14 14:12:59 +08003750 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3751 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003752}
3753
3754//Get the Radio enable status
3755INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
3756{
developera3511852023-06-14 14:12:59 +08003757 if (NULL == output_bool)
3758 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003759
developera3511852023-06-14 14:12:59 +08003760 return wifi_getRadioEnable(radioIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08003761}
3762
3763//Get the Radio Interface name from platform, eg "wlan0"
3764INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
3765{
developerc3556192023-12-06 17:59:09 +08003766 int main_vap_idx;
3767
developercd0b70a2023-12-11 11:25:50 +08003768 if (NULL == output_string || radioIndex>=get_runtime_max_radio() || radioIndex<0)
developera3511852023-06-14 14:12:59 +08003769 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +08003770
3771 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
3772 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
3773 }
3774 return wifi_GetInterfaceName(main_vap_idx, output_string);
developer72fb0bb2023-01-11 09:46:29 +08003775}
3776
developer6e578302023-06-21 10:11:16 +08003777int mtk_get_vow_info_callback(struct nl_msg *msg, void *data)
3778{
3779 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3780 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX + 1];
3781 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3782 int err = 0;
3783 struct vow_info *vow_info = NULL;
3784 struct mtk_nl80211_cb_data *cb_data = data;
3785
3786 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3787 genlmsg_attrlen(gnlh, 0), NULL);
3788 if (err < 0) {
3789 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
3790 return err;
3791 }
3792
3793 if (tb[NL80211_ATTR_VENDOR_DATA]) {
3794 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX,
3795 tb[NL80211_ATTR_VENDOR_DATA], NULL);
3796 if (err < 0){
3797 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX fails\n");
3798 return err;
3799 }
3800
3801 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]) {
3802 vow_info = (struct vow_info *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]);
3803 memmove(cb_data->out_buf, vow_info, sizeof(struct vow_info));
3804 }
3805 }
3806
3807 return 0;
3808}
3809
3810INT mtk_wifi_set_air_time_management(
3811 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
3812 char* data, INT len, void *output)
3813{
3814 char inf_name[IF_NAME_SIZE] = {0};
3815 unsigned int if_idx = 0;
3816 int ret = -1;
3817 struct unl unl_ins;
3818 struct nl_msg *msg = NULL;
3819 struct nlattr * msg_data = NULL;
3820 struct mtk_nl80211_param param;
3821
3822 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
3823 return RETURN_ERR;
3824 if_idx = if_nametoindex(inf_name);
3825 if (!if_idx) {
3826 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
3827 return RETURN_ERR;
3828 }
3829 /*init mtk nl80211 vendor cmd*/
3830 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_VOW;
3831 param.if_type = NL80211_ATTR_IFINDEX;
3832 param.if_idx = if_idx;
3833
3834 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3835 if (ret) {
3836 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3837 return RETURN_ERR;
3838 }
3839 /*add mtk vendor cmd data*/
3840 if (nla_put(msg, vendor_data_attr, len, data)) {
3841 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
3842 nlmsg_free(msg);
3843 goto err;
3844 }
3845
3846 /*send mtk nl80211 vendor msg*/
3847 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
3848 if (ret) {
3849 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3850 goto err;
3851 }
3852 /*deinit mtk nl80211 vendor msg*/
3853 mtk_nl80211_deint(&unl_ins);
3854 wifi_debug(DEBUG_INFO, "send cmd success.\n");
3855
3856 return RETURN_OK;
3857err:
3858 mtk_nl80211_deint(&unl_ins);
3859 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
3860 return RETURN_ERR;
3861}
3862
3863//Get the ATM(Air Time Management) Capable.
3864INT wifi_getATMCapable(BOOL *output_bool)
3865{
3866 if (NULL == output_bool)
3867 return RETURN_ERR;
3868 *output_bool = TRUE;
3869
3870 return RETURN_OK;
3871}
3872
3873INT wifi_setATMEnable(BOOL enable)
3874{
developer6e578302023-06-21 10:11:16 +08003875 int radio_idx = 0;
developer22e56142023-11-30 17:02:47 +08003876 int bss_idx;
developer6e578302023-06-21 10:11:16 +08003877 char dat_file[MAX_BUF_SIZE] = {0};
3878 int res;
developer08e5ea32023-12-01 10:25:49 +08003879 struct params params[3];
developer22e56142023-11-30 17:02:47 +08003880 struct vow_group_en_param atc_en_param;
developerdfd270b2023-12-12 10:24:30 +08003881 int main_vap_idx;
developer6e578302023-06-21 10:11:16 +08003882
developercd0b70a2023-12-11 11:25:50 +08003883 for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
developerdfd270b2023-12-12 10:24:30 +08003884 if (array_index_to_vap_index(radio_idx, 0, &main_vap_idx) != RETURN_OK) {
3885 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_idx);
3886 return RETURN_ERR;
3887 }
3888
developer6e578302023-06-21 10:11:16 +08003889 if (mtk_wifi_set_air_time_management
developerdfd270b2023-12-12 10:24:30 +08003890 (main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO,
developer6e578302023-06-21 10:11:16 +08003891 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
3892 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
3893 return RETURN_ERR;
3894 }
3895
3896 if (mtk_wifi_set_air_time_management
developerdfd270b2023-12-12 10:24:30 +08003897 (main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_BW_EN_INFO,
developer6e578302023-06-21 10:11:16 +08003898 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
3899 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
3900 return RETURN_ERR;
3901 }
3902
developer22e56142023-11-30 17:02:47 +08003903 /* atc support 15 group now , per band use 5 group */
3904 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
3905 atc_en_param.group = bss_idx;
3906 atc_en_param.en = enable;
3907 if (mtk_wifi_set_air_time_management
developerdfd270b2023-12-12 10:24:30 +08003908 (main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO,
developer22e56142023-11-30 17:02:47 +08003909 NULL, (char *)&atc_en_param, sizeof(struct vow_group_en_param), NULL)!= RETURN_OK) {
3910 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO cmd fails\n");
3911 return RETURN_ERR;
3912 }
3913 }
3914
developer6e578302023-06-21 10:11:16 +08003915 params[0].name = "VOW_Airtime_Fairness_En";
3916 params[0].value = enable ? "1" : "0";
3917 params[1].name = "VOW_BW_Ctrl";
3918 params[1].value = enable ? "1" : "0";
developer08e5ea32023-12-01 10:25:49 +08003919 params[2].name = "VOW_Airtime_Ctrl_En";
3920 params[2].value = enable ? "1;1;1;1;1;0;0;0;0;0;0;0;0;0;0" : "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";
developer6e578302023-06-21 10:11:16 +08003921
3922 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
3923 if (os_snprintf_error(sizeof(dat_file), res)) {
3924 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3925 return RETURN_ERR;
3926 }
developer08e5ea32023-12-01 10:25:49 +08003927 wifi_datfileWrite(dat_file, params, 3);
developer6e578302023-06-21 10:11:16 +08003928 }
3929
3930 return RETURN_OK;
3931}
3932
3933INT wifi_getATMEnable(BOOL *output_enable)
3934{
developer6e578302023-06-21 10:11:16 +08003935 int radio_idx = 0;
3936 struct vow_info vow_info;
3937 struct vow_info get_vow_info;
3938 struct mtk_nl80211_cb_data cb_data;
developerdfd270b2023-12-12 10:24:30 +08003939 int main_vap_idx;
developer6e578302023-06-21 10:11:16 +08003940
3941 if (output_enable == NULL)
3942 return RETURN_ERR;
3943
developer6e578302023-06-21 10:11:16 +08003944
3945 *output_enable = FALSE;
3946
3947 memset(&vow_info, 0, sizeof(struct vow_info));
3948
3949 cb_data.out_buf = (char *)&vow_info;
3950 cb_data.out_len = sizeof(struct vow_info);
3951
developercd0b70a2023-12-11 11:25:50 +08003952 for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
developerdfd270b2023-12-12 10:24:30 +08003953 if (array_index_to_vap_index(radio_idx, 0, &main_vap_idx) != RETURN_OK) {
3954 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_idx);
3955 return RETURN_ERR;
3956 }
developer6e578302023-06-21 10:11:16 +08003957 if (mtk_wifi_set_air_time_management
developerdfd270b2023-12-12 10:24:30 +08003958 (main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
developer6e578302023-06-21 10:11:16 +08003959 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
3960 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
3961 return RETURN_ERR;
3962 }
3963
3964 if (vow_info.atf_en == TRUE || vow_info.bw_en == TRUE) {
3965 *output_enable = TRUE;
3966 break;
3967 }
3968 }
3969
3970 return RETURN_OK;
3971}
3972
developer6e578302023-06-21 10:11:16 +08003973INT wifi_setApATMAirTimePercent(INT apIndex, UINT ap_AirTimePercent)
3974{
developer6e578302023-06-21 10:11:16 +08003975 struct vow_ratio_param radio_param;
developer2510b6d2023-12-14 11:28:12 +08003976 int group = 0;
3977 int radio_index = 0;
developer6e578302023-06-21 10:11:16 +08003978
developer22e56142023-11-30 17:02:47 +08003979 if (ap_AirTimePercent < 0 || ap_AirTimePercent > 100) {
3980 wifi_debug(DEBUG_ERROR, "invalid air time percent!\n");
developer6e578302023-06-21 10:11:16 +08003981 return RETURN_ERR;
3982 }
3983
developer2510b6d2023-12-14 11:28:12 +08003984 if (vap_index_to_radio_array_index(apIndex, &radio_index, &group) != RETURN_OK) {
3985 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", apIndex);
developer6e578302023-06-21 10:11:16 +08003986 return RETURN_ERR;
developer2510b6d2023-12-14 11:28:12 +08003987 }
developer6e578302023-06-21 10:11:16 +08003988
developer22e56142023-11-30 17:02:47 +08003989 if (group > 5) {
3990 wifi_debug(DEBUG_ERROR, "invalid group!\n");
developer6e578302023-06-21 10:11:16 +08003991 return RETURN_ERR;
3992 }
3993
3994 radio_param.group = group;
3995 radio_param.ratio = ap_AirTimePercent;
3996 if (mtk_wifi_set_air_time_management
3997 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO,
3998 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
3999 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO cmd fails\n");
4000 return RETURN_ERR;
4001 }
4002
4003 if (mtk_wifi_set_air_time_management
4004 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO,
4005 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
4006 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO cmd fails\n");
4007 return RETURN_ERR;
4008 }
4009
4010 return RETURN_OK;
4011}
4012
4013INT wifi_getApATMAirTimePercent(INT apIndex, UINT *output_ap_AirTimePercent)
4014{
developer2510b6d2023-12-14 11:28:12 +08004015 int group = 0;
developer6e578302023-06-21 10:11:16 +08004016 struct vow_info get_vow_info, vow_info;
4017 struct mtk_nl80211_cb_data cb_data;
developer2510b6d2023-12-14 11:28:12 +08004018 int radio_index = 0;
developer6e578302023-06-21 10:11:16 +08004019
4020 if (output_ap_AirTimePercent == NULL)
4021 return RETURN_ERR;
4022
developer2510b6d2023-12-14 11:28:12 +08004023 if (vap_index_to_radio_array_index(apIndex, &radio_index, &group) != RETURN_OK) {
4024 wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", apIndex);
developer22e56142023-11-30 17:02:47 +08004025 return RETURN_ERR;
developer2510b6d2023-12-14 11:28:12 +08004026 }
developer22e56142023-11-30 17:02:47 +08004027 if (group > 5) {
developer6e578302023-06-21 10:11:16 +08004028 wifi_debug(DEBUG_ERROR, "invalid group!\n");
4029 return RETURN_ERR;
4030 }
4031
4032 memset(&vow_info, 0, sizeof(struct vow_info));
4033 memset(&get_vow_info, 0, sizeof(struct vow_info));
4034
4035 cb_data.out_buf = (char *)&vow_info;
4036 cb_data.out_len = sizeof(struct vow_info);
4037
4038 get_vow_info.group = group;
4039
4040 if (mtk_wifi_set_air_time_management
4041 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
4042 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
4043 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
4044 return RETURN_ERR;
4045 }
4046
4047 *output_ap_AirTimePercent = vow_info.ratio;
4048
4049 return RETURN_ERR;
4050}
4051
developerd14dff12023-06-28 22:47:44 +08004052INT wifi_getApATMSta(INT apIndex, UCHAR *output_sta_MAC_ATM_array, UINT buf_size)
4053{
4054 ULONG dev_num = 0;
4055 struct vow_info vow_info;
4056 struct vow_info get_vow_info;
4057 struct mtk_nl80211_cb_data cb_data;
4058 unsigned int percent;
4059 char assocArray[MAX_BUF_SIZE] = {0};
4060 char *mac = NULL;
4061 unsigned char output_len = 0;
4062 int res;
4063 char buf[MAX_BUF_SIZE] = {0};
4064
4065 memset(&vow_info, 0, sizeof(struct vow_info));
4066 memset(&get_vow_info, 0, sizeof(struct vow_info));
4067
4068 cb_data.out_buf = (char *)&vow_info;
4069 cb_data.out_len = sizeof(struct vow_info);
4070
4071 if (mtk_wifi_set_air_time_management
4072 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
4073 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
4074 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
4075 return RETURN_ERR;
4076 }
4077
4078 if (vow_info.atf_en == FALSE) {
4079 wifi_debug(DEBUG_ERROR, "ATF disable!\n");
4080 return RETURN_ERR;
4081 }
4082
4083 if (wifi_getApNumDevicesAssociated(apIndex, &dev_num) != RETURN_OK) {
4084 wifi_debug(DEBUG_ERROR, "get sta num fail!\n");
4085 return RETURN_ERR;;
4086 }
4087
4088 percent = 100 / dev_num;
4089
4090 if (wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray)) != RETURN_OK){
4091 wifi_debug(DEBUG_ERROR, "get sta mac fail!\n");
4092 return RETURN_ERR;;
4093 }
4094
4095 memset(output_sta_MAC_ATM_array, 0, MAX_BUF_SIZE);
4096
4097 mac = strtok(assocArray, "\n");
4098 while (mac != NULL) {
4099 if (strlen(mac) >= 17) {
4100 res = snprintf(buf, sizeof(buf), "%s %d|", mac, percent);
4101
4102 if (os_snprintf_error(sizeof(buf), res)) {
4103 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4104 return RETURN_ERR;
4105 }
4106
4107 if (output_len + strlen(buf) > buf_size)
4108 break;
4109
4110 strncat((char *)output_sta_MAC_ATM_array, buf, strlen(buf));
4111
4112 output_len += strlen(buf);
4113 }
4114
4115 mac = strtok(NULL, "\n");
4116 }
4117
4118 /* Remove the last | */
4119 if (strlen((char *)output_sta_MAC_ATM_array) != 0)
4120 output_sta_MAC_ATM_array[strlen((char *)output_sta_MAC_ATM_array)-1] = '\0';
4121
4122 return RETURN_OK;
4123}
4124
4125INT wifi_setApATMSta(INT apIndex, UCHAR *sta_MAC_ATM_array, UINT ap_AirTimePercent)
4126{
4127 return RETURN_ERR;
4128}
developer9ce44382023-06-28 11:09:37 +08004129
developer72fb0bb2023-01-11 09:46:29 +08004130//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
4131//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.
4132INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
4133{
developera3511852023-06-14 14:12:59 +08004134 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
4135 // For max bit rate, we should always choose the best MCS
4136 char mode[64] = {0};
4137 char channel_bandwidth_str[64] = {0};
4138 UINT mode_map = 0;
4139 UINT num_subcarrier = 0;
4140 UINT code_bits = 0;
4141 float code_rate = 0; // use max code rate
4142 int NSS = 0;
4143 UINT Symbol_duration = 0;
4144 UINT GI_duration = 0;
4145 wifi_guard_interval_t gi = wifi_guard_interval_auto;
4146 BOOL enable = FALSE;
4147 float bit_rate = 0;
developere40952c2023-06-15 18:46:43 +08004148 int ant_bitmap = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08004149
developera3511852023-06-14 14:12:59 +08004150 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4151 if (NULL == output_string)
4152 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004153
developera3511852023-06-14 14:12:59 +08004154 wifi_getRadioEnable(radioIndex, &enable);
4155 if (enable == FALSE) {
developere40952c2023-06-15 18:46:43 +08004156 res = snprintf(output_string, 64, "0 Mb/s");
4157 if (os_snprintf_error(64, res)) {
4158 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4159 return RETURN_ERR;
4160 }
developera3511852023-06-14 14:12:59 +08004161 return RETURN_OK;
4162 }
developer72fb0bb2023-01-11 09:46:29 +08004163
developera3511852023-06-14 14:12:59 +08004164 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08004165 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +08004166 return RETURN_ERR;
4167 }
developer72fb0bb2023-01-11 09:46:29 +08004168
developera3511852023-06-14 14:12:59 +08004169 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08004170 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +08004171 return RETURN_ERR;
4172 }
developer72fb0bb2023-01-11 09:46:29 +08004173
developera3511852023-06-14 14:12:59 +08004174 if (gi == wifi_guard_interval_3200)
4175 GI_duration = 32;
4176 else if (gi == wifi_guard_interval_1600)
4177 GI_duration = 16;
4178 else if (gi == wifi_guard_interval_800)
4179 GI_duration = 8;
4180 else // auto, 400
4181 GI_duration = 4;
developer72fb0bb2023-01-11 09:46:29 +08004182
developera3511852023-06-14 14:12:59 +08004183 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08004184 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error\n");
developera3511852023-06-14 14:12:59 +08004185 return RETURN_ERR;
4186 }
developer72fb0bb2023-01-11 09:46:29 +08004187
developera3511852023-06-14 14:12:59 +08004188 if (strstr(channel_bandwidth_str, "80+80") != NULL)
developer32f2a182023-06-27 19:50:41 +08004189 memcpy(channel_bandwidth_str, "160", strlen("160"));
developer72fb0bb2023-01-11 09:46:29 +08004190
developera3511852023-06-14 14:12:59 +08004191 if (mode_map & WIFI_MODE_AX) {
4192 if (strstr(channel_bandwidth_str, "160") != NULL)
4193 num_subcarrier = 1960;
4194 else if (strstr(channel_bandwidth_str, "80") != NULL)
4195 num_subcarrier = 980;
4196 else if (strstr(channel_bandwidth_str, "40") != NULL)
4197 num_subcarrier = 468;
4198 else if (strstr(channel_bandwidth_str, "20") != NULL)
4199 num_subcarrier = 234;
4200 code_bits = 10;
4201 code_rate = (float)5/6;
4202 Symbol_duration = 128;
4203 GI_duration = 8;/*HE no GI 400ns*/
4204 } else if (mode_map & WIFI_MODE_AC) {
4205 if (strstr(channel_bandwidth_str, "160") != NULL)
4206 num_subcarrier = 468;
4207 else if (strstr(channel_bandwidth_str, "80") != NULL)
4208 num_subcarrier = 234;
4209 else if (strstr(channel_bandwidth_str, "40") != NULL)
4210 num_subcarrier = 108;
4211 else if (strstr(channel_bandwidth_str, "20") != NULL)
4212 num_subcarrier = 52;
4213 code_bits = 8;
4214 code_rate = (float)5/6;
4215 Symbol_duration = 32;
4216 } else if (mode_map & WIFI_MODE_N) {
4217 if (strstr(channel_bandwidth_str, "160") != NULL)
4218 num_subcarrier = 468;
4219 else if (strstr(channel_bandwidth_str, "80") != NULL)
4220 num_subcarrier = 234;
4221 else if (strstr(channel_bandwidth_str, "40") != NULL)
4222 num_subcarrier = 108;
4223 else if (strstr(channel_bandwidth_str, "20") != NULL)
4224 num_subcarrier = 52;
4225 code_bits = 6;
4226 code_rate = (float)3/4;
4227 Symbol_duration = 32;
4228 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
4229 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
developere40952c2023-06-15 18:46:43 +08004230 res = snprintf(output_string, 64, "65 Mb/s");
4231 if (os_snprintf_error(64, res)) {
4232 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4233 return RETURN_ERR;
4234 }
developera3511852023-06-14 14:12:59 +08004235 return RETURN_OK;
4236 } else {
developere40952c2023-06-15 18:46:43 +08004237 res = snprintf(output_string, 64, "0 Mb/s");
4238 if (os_snprintf_error(64, res)) {
4239 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4240 return RETURN_ERR;
4241 }
developera3511852023-06-14 14:12:59 +08004242 return RETURN_OK;
4243 }
developer72fb0bb2023-01-11 09:46:29 +08004244
developera3511852023-06-14 14:12:59 +08004245 // Spatial streams
4246 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08004247 wifi_debug(DEBUG_ERROR, "wifi_getRadioTxChainMask return error\n");
developera3511852023-06-14 14:12:59 +08004248 return RETURN_ERR;
4249 }
4250 for (; ant_bitmap > 0; ant_bitmap >>= 1)
4251 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08004252
developera3511852023-06-14 14:12:59 +08004253 // multiple 10 is to align duration unit (0.1 us)
4254 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
developere40952c2023-06-15 18:46:43 +08004255 res = snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
4256 if (os_snprintf_error(64, res)) {
4257 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4258 return RETURN_ERR;
4259 }
developera3511852023-06-14 14:12:59 +08004260 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
4261 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
4262 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004263
developera3511852023-06-14 14:12:59 +08004264 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004265}
developer72fb0bb2023-01-11 09:46:29 +08004266
4267//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
4268//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.
4269INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
4270{
developera3511852023-06-14 14:12:59 +08004271 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004272
developera3511852023-06-14 14:12:59 +08004273 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4274 if (NULL == output_string)
4275 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004276
developerdfd270b2023-12-12 10:24:30 +08004277 band = radio_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004278
developera3511852023-06-14 14:12:59 +08004279 memset(output_string, 0, 10);
4280 if (band == band_2_4)
developer32f2a182023-06-27 19:50:41 +08004281 memcpy(output_string, "2.4GHz", strlen("2.4GHz"));
developera3511852023-06-14 14:12:59 +08004282 else if (band == band_5)
developer32f2a182023-06-27 19:50:41 +08004283 memcpy(output_string, "5GHz", strlen("5GHz"));
developera3511852023-06-14 14:12:59 +08004284 else if (band == band_6)
developer32f2a182023-06-27 19:50:41 +08004285 memcpy(output_string, "6GHz", strlen("6GHz"));
developera3511852023-06-14 14:12:59 +08004286 else
4287 return RETURN_ERR;
4288 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004289
developera3511852023-06-14 14:12:59 +08004290 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004291}
4292
4293//Get the frequency band at which the radio is operating, eg: "2.4GHz"
4294//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.
4295INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
4296{
developera3511852023-06-14 14:12:59 +08004297 wifi_band band = band_invalid;
developer9ce44382023-06-28 11:09:37 +08004298 int res = -1;
developere40952c2023-06-15 18:46:43 +08004299
developera3511852023-06-14 14:12:59 +08004300 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4301 if (NULL == output_string)
4302 return RETURN_ERR;
developerdfd270b2023-12-12 10:24:30 +08004303 band = radio_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004304
developera3511852023-06-14 14:12:59 +08004305 if (band == band_2_4)
developere40952c2023-06-15 18:46:43 +08004306 res = snprintf(output_string, 64, "2.4GHz");
developera3511852023-06-14 14:12:59 +08004307 else if (band == band_5)
developere40952c2023-06-15 18:46:43 +08004308 res = snprintf(output_string, 64, "5GHz");
developera3511852023-06-14 14:12:59 +08004309 else if (band == band_6)
developere40952c2023-06-15 18:46:43 +08004310 res = snprintf(output_string, 64, "6GHz");
developer72fb0bb2023-01-11 09:46:29 +08004311
developere40952c2023-06-15 18:46:43 +08004312 if (os_snprintf_error(64, res)) {
4313 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4314 return RETURN_ERR;
4315 }
developera3511852023-06-14 14:12:59 +08004316 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004317
developera3511852023-06-14 14:12:59 +08004318 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004319}
4320
4321//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
4322//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.
4323INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
4324{
developera3511852023-06-14 14:12:59 +08004325 char buf[128]={0};
4326 char temp_output[128] = {0};
4327 wifi_band band;
developere40952c2023-06-15 18:46:43 +08004328 int phyId = 0, res;
developerb8b49112023-12-21 14:24:55 +08004329 char dat_file[MAX_BUF_SIZE] = {0};
4330 char str_radio_mode[16] = {0};
4331 unsigned long radio_mode;
developer72fb0bb2023-01-11 09:46:29 +08004332
developera3511852023-06-14 14:12:59 +08004333 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4334 if (NULL == output_string)
4335 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004336
developerdfd270b2023-12-12 10:24:30 +08004337 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08004338 if (band == band_2_4) {
developer32f2a182023-06-27 19:50:41 +08004339 strncat(temp_output, "b,g,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08004340 } else if (band == band_5) {
developer32f2a182023-06-27 19:50:41 +08004341 strncat(temp_output, "a,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08004342 }
4343 phyId = radio_index_to_phy(radioIndex);
4344 // ht capabilities
developer8078acf2023-08-04 18:52:48 +08004345
4346 res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep '[^PHY|MAC|VHT].Capabilities' | head -n 1 | cut -d ':' -f2 | sed 's/^.//' | tr -d '\\n'", phyId);
4347 if (res) {
4348 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08004349 }
developer8078acf2023-08-04 18:52:48 +08004350
developera3511852023-06-14 14:12:59 +08004351 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
developer32f2a182023-06-27 19:50:41 +08004352 if (strlen(temp_output) >= sizeof(temp_output) - 2)
4353 return RETURN_ERR;
4354 strncat(temp_output, "n,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08004355 }
developer72fb0bb2023-01-11 09:46:29 +08004356
developera3511852023-06-14 14:12:59 +08004357 // vht capabilities
4358 if (band == band_5) {
developer8078acf2023-08-04 18:52:48 +08004359 res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
4360 if (res) {
4361 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08004362 }
developere40952c2023-06-15 18:46:43 +08004363 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
developer32f2a182023-06-27 19:50:41 +08004364 if (strlen(temp_output) >= sizeof(temp_output) - 3)
4365 return RETURN_ERR;
developerc14d83a2023-06-29 20:09:42 +08004366 strncat(temp_output, "ac,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08004367 }
4368 }
developer72fb0bb2023-01-11 09:46:29 +08004369
developera3511852023-06-14 14:12:59 +08004370 // he capabilities
developer8078acf2023-08-04 18:52:48 +08004371 res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'HE MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
4372 if (res) {
4373 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08004374 }
developer8078acf2023-08-04 18:52:48 +08004375
developera3511852023-06-14 14:12:59 +08004376 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08004377 if (strlen(temp_output) >= sizeof(temp_output) - 3)
4378 return RETURN_ERR;
4379 strncat(temp_output, "ax,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08004380 }
developer72fb0bb2023-01-11 09:46:29 +08004381
developere82c0ca2023-05-10 16:25:35 +08004382 // eht capabilities
developerb8b49112023-12-21 14:24:55 +08004383 /*res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'EHT MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
developer8078acf2023-08-04 18:52:48 +08004384 if (res) {
4385 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08004386 }
developer8078acf2023-08-04 18:52:48 +08004387
developera3511852023-06-14 14:12:59 +08004388 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08004389 if (strlen(temp_output) >= sizeof(temp_output) - 3)
4390 return RETURN_ERR;
4391 strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
developerb8b49112023-12-21 14:24:55 +08004392 }*/
4393 /* iw phy info cannot get EHT MAC Capabilities due to the backport version*/
4394 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
4395 if (os_snprintf_error(sizeof(dat_file), res)) {
4396 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4397 return RETURN_ERR;
4398 }
4399
4400 wifi_datfileRead(dat_file, "WirelessMode", str_radio_mode, sizeof(str_radio_mode));
4401 if (hal_strtoul(str_radio_mode, 10, &radio_mode) < 0) {
4402 wifi_debug(DEBUG_ERROR, "strtol fail\n");
4403 }
4404
4405 if (radio_mode >= PHY_11BE_24G) {
4406 if (strlen(temp_output) >= sizeof(temp_output) - 3)
4407 return RETURN_ERR;
4408 strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08004409 }
developere82c0ca2023-05-10 16:25:35 +08004410
developera3511852023-06-14 14:12:59 +08004411 // Remove the last comma
4412 if (strlen(temp_output) != 0)
4413 temp_output[strlen(temp_output)-1] = '\0';
4414 strncpy(output_string, temp_output, strlen(temp_output));
4415 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4416 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004417}
4418
4419//Get the radio operating mode, and pure mode flag. eg: "ac"
4420//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.
4421INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
4422{
developere40952c2023-06-15 18:46:43 +08004423 int res;
4424
developera3511852023-06-14 14:12:59 +08004425 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4426 if (NULL == output_string)
4427 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004428
developera3511852023-06-14 14:12:59 +08004429 if (radioIndex == 0) {
developere40952c2023-06-15 18:46:43 +08004430 res = snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
4431 if (os_snprintf_error(64, res)) {
4432 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4433 return RETURN_ERR;
4434 }
developera3511852023-06-14 14:12:59 +08004435 *gOnly = FALSE;
4436 *nOnly = TRUE;
4437 *acOnly = FALSE;
4438 } else {
developere40952c2023-06-15 18:46:43 +08004439 res = snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
4440 if (os_snprintf_error(64, res)) {
4441 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4442 return RETURN_ERR;
4443 }
developera3511852023-06-14 14:12:59 +08004444 *gOnly = FALSE;
4445 *nOnly = FALSE;
4446 *acOnly = FALSE;
4447 }
4448 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004449
developera3511852023-06-14 14:12:59 +08004450 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004451}
4452
developer0f10c772023-05-16 21:43:39 +08004453#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08004454
4455int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08004456{
developerfead3972023-05-25 20:15:02 +08004457 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4458 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
developerc14d83a2023-06-29 20:09:42 +08004459 struct genlmsghdr *gnlh;
developerfead3972023-05-25 20:15:02 +08004460 unsigned int *phymode;
4461 int err = 0;
4462 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08004463
developerfead3972023-05-25 20:15:02 +08004464 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08004465 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developerfead3972023-05-25 20:15:02 +08004466 return NL_SKIP;
4467 }
developerc14d83a2023-06-29 20:09:42 +08004468 gnlh = nlmsg_data(nlmsg_hdr(msg));
developer72fb0bb2023-01-11 09:46:29 +08004469
developerfead3972023-05-25 20:15:02 +08004470 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4471 genlmsg_attrlen(gnlh, 0), NULL);
4472 if (err < 0) {
4473 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
4474 return NL_SKIP;
4475 }
developer0f10c772023-05-16 21:43:39 +08004476
developerfead3972023-05-25 20:15:02 +08004477 if (tb[NL80211_ATTR_VENDOR_DATA]) {
4478 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
4479 tb[NL80211_ATTR_VENDOR_DATA], NULL);
4480 if (err < 0)
4481 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08004482
developerfead3972023-05-25 20:15:02 +08004483 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
4484 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
4485
4486 memset(cb_data->out_buf, 0, cb_data->out_len);
4487 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
4488 }
4489 } else
4490 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
4491
4492 return NL_OK;
4493}
developer0f10c772023-05-16 21:43:39 +08004494
developerfead3972023-05-25 20:15:02 +08004495void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
4496{
4497 wifi_band band;
4498 unsigned char radio_mode_tem_len;
developere40952c2023-06-15 18:46:43 +08004499 int res;
developerfead3972023-05-25 20:15:02 +08004500
developerdfd270b2023-12-12 10:24:30 +08004501 band = radio_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08004502 // puremode is a bit map
developera3511852023-06-14 14:12:59 +08004503 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08004504 memset(output_string, 0, RADIO_MODE_LEN);
4505
4506 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4507
4508 switch (band) {
4509 case band_2_4:
4510 if (phymode & WMODE_B) {
developere40952c2023-06-15 18:46:43 +08004511 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
4512 if (os_snprintf_error(radio_mode_tem_len, res)) {
4513 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4514 return;
4515 }
developer0f10c772023-05-16 21:43:39 +08004516 *pureMode |= WIFI_MODE_B;
4517 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4518 }
4519 if (phymode & WMODE_G) {
developere40952c2023-06-15 18:46:43 +08004520 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
4521 if (os_snprintf_error(radio_mode_tem_len, res)) {
4522 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4523 return;
4524 }
developer0f10c772023-05-16 21:43:39 +08004525 *pureMode |= WIFI_MODE_G;
4526 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4527 }
4528 if (phymode & WMODE_GN) {
developere40952c2023-06-15 18:46:43 +08004529 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
4530 if (os_snprintf_error(radio_mode_tem_len, res)) {
4531 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4532 return;
4533 }
developer0f10c772023-05-16 21:43:39 +08004534 *pureMode |= WIFI_MODE_N;
4535 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4536 }
4537 if (phymode & WMODE_AX_24G) {
developere40952c2023-06-15 18:46:43 +08004538 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
4539 if (os_snprintf_error(radio_mode_tem_len, res)) {
4540 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4541 return;
4542 }
developer0f10c772023-05-16 21:43:39 +08004543 *pureMode |= WIFI_MODE_AX;
4544 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4545 }
4546 if (phymode & WMODE_BE_24G) {
developere40952c2023-06-15 18:46:43 +08004547 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
4548 if (os_snprintf_error(radio_mode_tem_len, res)) {
4549 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4550 return;
4551 }
developer0f10c772023-05-16 21:43:39 +08004552 *pureMode |= WIFI_MODE_BE;
4553 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4554 }
4555 break;
4556 case band_5:
4557 if (phymode & WMODE_A) {
developere40952c2023-06-15 18:46:43 +08004558 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
4559 if (os_snprintf_error(radio_mode_tem_len, res)) {
4560 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4561 return;
4562 }
developer0f10c772023-05-16 21:43:39 +08004563 *pureMode |= WIFI_MODE_A;
4564 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4565 }
4566 if (phymode & WMODE_AN) {
developere40952c2023-06-15 18:46:43 +08004567 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
4568 if (os_snprintf_error(radio_mode_tem_len, res)) {
4569 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4570 return;
4571 }
developer0f10c772023-05-16 21:43:39 +08004572 *pureMode |= WIFI_MODE_N;
4573 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4574 }
4575 if (phymode & WMODE_AC) {
developere40952c2023-06-15 18:46:43 +08004576 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
4577 if (os_snprintf_error(radio_mode_tem_len, res)) {
4578 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4579 return;
4580 }
developer0f10c772023-05-16 21:43:39 +08004581 *pureMode |= WIFI_MODE_AC;
4582 }
4583 if (phymode & WMODE_AX_5G) {
developere40952c2023-06-15 18:46:43 +08004584 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
4585 if (os_snprintf_error(radio_mode_tem_len, res)) {
4586 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4587 return;
4588 }
developer0f10c772023-05-16 21:43:39 +08004589 *pureMode |= WIFI_MODE_AX;
4590 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4591 }
4592 if (phymode & WMODE_BE_5G) {
developere40952c2023-06-15 18:46:43 +08004593 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
4594 if (os_snprintf_error(radio_mode_tem_len, res)) {
4595 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4596 return;
4597 }
developer0f10c772023-05-16 21:43:39 +08004598 *pureMode |= WIFI_MODE_BE;
4599 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4600 }
4601 break;
4602 case band_6:
4603 if (phymode & WMODE_AX_6G) {
developere40952c2023-06-15 18:46:43 +08004604 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
4605 if (os_snprintf_error(radio_mode_tem_len, res)) {
4606 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4607 return;
4608 }
developer0f10c772023-05-16 21:43:39 +08004609 *pureMode |= WIFI_MODE_AX;
4610 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4611 }
4612 if (phymode & WMODE_BE_6G) {
developere40952c2023-06-15 18:46:43 +08004613 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
4614 if (os_snprintf_error(radio_mode_tem_len, res)) {
4615 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4616 return;
4617 }
developer0f10c772023-05-16 21:43:39 +08004618 *pureMode |= WIFI_MODE_BE;
4619 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
4620 }
4621 break;
4622 default:
developer86035662023-06-28 19:21:12 +08004623 wifi_debug(DEBUG_ERROR, "%s band_idx invalid\n", __func__);
developer0f10c772023-05-16 21:43:39 +08004624 break;
4625 }
4626
4627 /* Remove the last comma */
4628 if (strlen(output_string) != 0)
developera3511852023-06-14 14:12:59 +08004629 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08004630
developerfead3972023-05-25 20:15:02 +08004631}
4632
4633INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
4634{
4635 unsigned int phymode;
4636 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08004637 int ret = -1;
4638 unsigned int if_idx = 0;
4639 struct unl unl_ins;
4640 struct nl_msg *msg = NULL;
4641 struct nlattr * msg_data = NULL;
4642 struct mtk_nl80211_param param;
4643 struct mtk_nl80211_cb_data cb_data;
developerc3556192023-12-06 17:59:09 +08004644 int main_vap_idx;
developerfead3972023-05-25 20:15:02 +08004645
developera3511852023-06-14 14:12:59 +08004646 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4647 if (NULL == output_string || NULL == pureMode)
developerdaf24792023-06-06 11:40:04 +08004648 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08004649
developerc3556192023-12-06 17:59:09 +08004650 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
4651 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
4652 return RETURN_ERR;
4653 }
developerfead3972023-05-25 20:15:02 +08004654
developerc3556192023-12-06 17:59:09 +08004655 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developerfead3972023-05-25 20:15:02 +08004656 return RETURN_ERR;
4657
4658 if_idx = if_nametoindex(interface_name);
4659 if (!if_idx) {
4660 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4661 return RETURN_ERR;
4662 }
4663 /*init mtk nl80211 vendor cmd*/
4664 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
4665 param.if_type = NL80211_ATTR_IFINDEX;
4666 param.if_idx = if_idx;
4667
4668 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4669 if (ret) {
4670 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4671 return RETURN_ERR;
4672 }
4673
4674 /*add mtk vendor cmd data*/
4675 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
4676 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
4677 nlmsg_free(msg);
4678 goto err;
4679 }
4680
4681 /*send mtk nl80211 vendor msg*/
4682 cb_data.out_buf = (char *)&phymode;
4683 cb_data.out_len = sizeof(unsigned int);
4684
4685 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
4686
4687 if (ret) {
4688 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4689 goto err;
4690 }
4691 /*deinit mtk nl80211 vendor msg*/
4692 mtk_nl80211_deint(&unl_ins);
4693
4694 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
developer6e578302023-06-21 10:11:16 +08004695 wifi_debug(DEBUG_INFO,"send cmd success\n");
developerfead3972023-05-25 20:15:02 +08004696
developera3511852023-06-14 14:12:59 +08004697 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4698 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004699err:
4700 mtk_nl80211_deint(&unl_ins);
4701 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
4702 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004703}
4704
4705// Set the radio operating mode, and pure mode flag.
4706INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
4707{
developera3511852023-06-14 14:12:59 +08004708 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
4709 if (strcmp (channelMode,"11A") == 0)
4710 {
4711 writeBandWidth(radioIndex,"20MHz");
4712 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
4713 printf("\nChannel Mode is 802.11a (5GHz)\n");
4714 }
4715 else if (strcmp (channelMode,"11NAHT20") == 0)
4716 {
4717 writeBandWidth(radioIndex,"20MHz");
4718 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
4719 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
4720 }
4721 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
4722 {
4723 writeBandWidth(radioIndex,"40MHz");
4724 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
4725 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
4726 }
4727 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
4728 {
4729 writeBandWidth(radioIndex,"40MHz");
4730 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
4731 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
4732 }
4733 else if (strcmp (channelMode,"11ACVHT20") == 0)
4734 {
4735 writeBandWidth(radioIndex,"20MHz");
4736 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
4737 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
4738 }
4739 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
4740 {
4741 writeBandWidth(radioIndex,"40MHz");
4742 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
4743 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
4744 }
4745 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
4746 {
4747 writeBandWidth(radioIndex,"40MHz");
4748 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
4749 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
4750 }
4751 else if (strcmp (channelMode,"11ACVHT80") == 0)
4752 {
4753 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
4754 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
4755 }
4756 else if (strcmp (channelMode,"11ACVHT160") == 0)
4757 {
4758 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
4759 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
4760 }
4761 else if (strcmp (channelMode,"11B") == 0)
4762 {
4763 writeBandWidth(radioIndex,"20MHz");
4764 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
4765 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
4766 }
4767 else if (strcmp (channelMode,"11G") == 0)
4768 {
4769 writeBandWidth(radioIndex,"20MHz");
4770 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
4771 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
4772 }
4773 else if (strcmp (channelMode,"11NGHT20") == 0)
4774 {
4775 writeBandWidth(radioIndex,"20MHz");
4776 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
4777 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
4778 }
4779 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
4780 {
4781 writeBandWidth(radioIndex,"40MHz");
4782 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
4783 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
4784 }
4785 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
4786 {
4787 writeBandWidth(radioIndex,"40MHz");
4788 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
4789 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
4790 }
4791 else
4792 {
4793 return RETURN_ERR;
4794 }
4795 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004796
developera3511852023-06-14 14:12:59 +08004797 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004798}
4799
developer0f10c772023-05-16 21:43:39 +08004800unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
4801{
developerfead3972023-05-25 20:15:02 +08004802 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08004803
developer408cde72023-10-19 13:44:02 +08004804 switch (radioIndex) {
developer0f10c772023-05-16 21:43:39 +08004805 case band_2_4:
4806 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
4807 wireless_mode = PHY_11GN_MIXED;
4808 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
4809 wireless_mode = PHY_11BGN_MIXED;
4810 if (pureMode & WIFI_MODE_AX)
4811 wireless_mode = PHY_11AX_24G;
4812 if (pureMode & WIFI_MODE_BE)
4813 wireless_mode = PHY_11BE_24G;
4814 break;
4815 case band_5:
4816 if (pureMode == WIFI_MODE_N)
4817 wireless_mode = PHY_11N_5G;
4818 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
4819 wireless_mode = PHY_11VHT_N_MIXED;
4820 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
4821 wireless_mode = PHY_11VHT_N_A_MIXED;
4822 if (pureMode & WIFI_MODE_AX)
4823 wireless_mode = PHY_11AX_5G;
4824 if (pureMode & WIFI_MODE_BE)
4825 wireless_mode = PHY_11BE_5G;
4826 break;
4827 case band_6:
4828 if (pureMode & WIFI_MODE_AX)
4829 wireless_mode = PHY_11AX_6G;
4830 if (pureMode & WIFI_MODE_BE)
4831 wireless_mode = PHY_11BE_6G;
4832 break;
4833 default:
developer37646972023-06-29 10:58:43 +08004834 if (fprintf(stderr, "%s band_idx invalid\n", __func__) < 0)
4835 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developer0f10c772023-05-16 21:43:39 +08004836 break;
4837 }
4838
4839 return wireless_mode;
4840}
4841
developer72fb0bb2023-01-11 09:46:29 +08004842// Set the radio operating mode, and pure mode flag.
4843INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
4844{
developerfead3972023-05-25 20:15:02 +08004845 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08004846
developer0f10c772023-05-16 21:43:39 +08004847 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08004848 int ret = -1;
4849 unsigned int if_idx = 0;
4850 struct unl unl_ins;
4851 struct nl_msg *msg = NULL;
4852 struct nlattr * msg_data = NULL;
4853 struct mtk_nl80211_param param;
developer8461fe52023-11-07 16:11:44 +08004854 char buf[MAX_BUF_SIZE] = {0};
4855 char dat_file[MAX_BUF_SIZE] = {0};
4856 struct params params={0};
4857 int res;
developerc3556192023-12-06 17:59:09 +08004858 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08004859
developer9f2358c2023-09-22 18:42:12 +08004860 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s:%d_%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004861
developer0f10c772023-05-16 21:43:39 +08004862 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08004863
developera3511852023-06-14 14:12:59 +08004864 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08004865 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08004866 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08004867 }
developer72fb0bb2023-01-11 09:46:29 +08004868
developerc3556192023-12-06 17:59:09 +08004869 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
4870 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
4871 return RETURN_ERR;
4872 }
4873
4874 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08004875 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08004876
4877 if_idx = if_nametoindex(interface_name);
4878 if (!if_idx) {
4879 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
4880 return RETURN_ERR;
4881 }
4882 /*init mtk nl80211 vendor cmd*/
4883 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
4884 param.if_type = NL80211_ATTR_IFINDEX;
4885 param.if_idx = if_idx;
4886
4887 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4888 if (ret) {
4889 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4890 return RETURN_ERR;
4891 }
4892
4893 /*add mtk vendor cmd data*/
4894 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
4895 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
4896 nlmsg_free(msg);
4897 goto err;
4898 }
4899 /*send mtk nl80211 vendor msg*/
4900 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4901 if (ret) {
4902 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4903 goto err;
4904 }
4905 /*deinit mtk nl80211 vendor msg*/
4906 mtk_nl80211_deint(&unl_ins);
4907 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08004908
developer8461fe52023-11-07 16:11:44 +08004909 /*update dat profile*/
developer0f10c772023-05-16 21:43:39 +08004910 params.name = "WirelessMode";
developere40952c2023-06-15 18:46:43 +08004911 res = snprintf(buf, sizeof(buf), "%d", wireless_mode);
4912 if (os_snprintf_error(sizeof(buf), res)) {
4913 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4914 return RETURN_ERR;
4915 }
4916
developera3511852023-06-14 14:12:59 +08004917 params.value = buf;
developer0f10c772023-05-16 21:43:39 +08004918
developere40952c2023-06-15 18:46:43 +08004919 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
4920 if (os_snprintf_error(sizeof(dat_file), res)) {
4921 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4922 return RETURN_ERR;
4923 }
developera3511852023-06-14 14:12:59 +08004924 wifi_datfileWrite(dat_file, &params, 1);
developer0f10c772023-05-16 21:43:39 +08004925
developera3511852023-06-14 14:12:59 +08004926 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004927
developera3511852023-06-14 14:12:59 +08004928 return RETURN_OK;
developer8461fe52023-11-07 16:11:44 +08004929err:
4930 mtk_nl80211_deint(&unl_ins);
4931 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4932 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004933}
4934
4935INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
4936
developera3511852023-06-14 14:12:59 +08004937 char config_file[64] = {0};
4938 char buf[64] = {0};
4939 struct params params = {0};
4940 wifi_band band = band_invalid;
developera47dfe22023-12-21 16:02:31 +08004941 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08004942
developera3511852023-06-14 14:12:59 +08004943 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004944
developerdfd270b2023-12-12 10:24:30 +08004945 band = radio_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004946
developera3511852023-06-14 14:12:59 +08004947 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
4948 return RETURN_ERR;
4949 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
4950 return RETURN_ERR;
4951 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
4952 return RETURN_ERR;
developera47dfe22023-12-21 16:02:31 +08004953
4954 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
4955 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
4956 return RETURN_ERR;
4957 }
developer72fb0bb2023-01-11 09:46:29 +08004958
developera47dfe22023-12-21 16:02:31 +08004959 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer75bd10c2023-06-27 11:34:08 +08004960 if (os_snprintf_error(sizeof(config_file), res)) {
4961 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4962 return RETURN_ERR;
4963 }
developera3511852023-06-14 14:12:59 +08004964 params.name = "hw_mode";
4965 params.value = hw_mode;
4966 wifi_hostapdWrite(config_file, &params, 1);
4967 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08004968
developera3511852023-06-14 14:12:59 +08004969 if (band == band_2_4) {
4970 if (strncmp(hw_mode, "b", 1) == 0) {
4971 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
developere40952c2023-06-15 18:46:43 +08004972 res = snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
4973 if (os_snprintf_error(sizeof(buf), res)) {
4974 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4975 return RETURN_ERR;
4976 }
developera3511852023-06-14 14:12:59 +08004977 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08004978 res = snprintf(buf, sizeof(buf), "%s", "1,2");
4979 if (os_snprintf_error(sizeof(buf), res)) {
4980 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4981 return RETURN_ERR;
4982 }
developera3511852023-06-14 14:12:59 +08004983 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
4984 } else {
4985 // 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 +08004986
developere40952c2023-06-15 18:46:43 +08004987 res = snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
4988 if (os_snprintf_error(sizeof(buf), res)) {
4989 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4990 return RETURN_ERR;
4991 }
developera3511852023-06-14 14:12:59 +08004992 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08004993 res = snprintf(buf, sizeof(buf), "%s", "6,12,24");
4994 if (os_snprintf_error(sizeof(buf), res)) {
4995 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4996 return RETURN_ERR;
4997 }
developera3511852023-06-14 14:12:59 +08004998 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
4999 }
5000 }
developer72fb0bb2023-01-11 09:46:29 +08005001
developera3511852023-06-14 14:12:59 +08005002 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5003 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005004}
5005
5006INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
5007{
developera3511852023-06-14 14:12:59 +08005008 char config_file[64] = {0};
5009 struct params params = {0};
5010 wifi_band band = band_invalid;
developera47dfe22023-12-21 16:02:31 +08005011 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08005012
developera3511852023-06-14 14:12:59 +08005013 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005014
developerdfd270b2023-12-12 10:24:30 +08005015 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08005016 if (band != band_2_4)
5017 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005018
developera47dfe22023-12-21 16:02:31 +08005019 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
5020 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
5021 return RETURN_ERR;
5022 }
5023
5024 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer75bd10c2023-06-27 11:34:08 +08005025 if (os_snprintf_error(sizeof(config_file), res)) {
5026 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5027 return RETURN_ERR;
5028 }
developera3511852023-06-14 14:12:59 +08005029 params.name = "noscan";
5030 params.value = noscan;
5031 wifi_hostapdWrite(config_file, &params, 1);
5032 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08005033
developera3511852023-06-14 14:12:59 +08005034 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5035 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005036}
5037
5038//Get the list of supported channel. eg: "1-11"
5039//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.
5040INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
5041{
developera3511852023-06-14 14:12:59 +08005042 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5043 if (NULL == output_string)
5044 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +08005045
developera3511852023-06-14 14:12:59 +08005046 char buf[128] = {0};
5047 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +08005048 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08005049
developera3511852023-06-14 14:12:59 +08005050 // Parse possible channel number and separate them with commas.
5051 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
5052 phyId = radio_index_to_phy(radioIndex);
5053 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
5054 if (dfs_enable)
developer8078acf2023-08-04 18:52:48 +08005055 res = _syscmd_secure(buf, sizeof(buf), "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 +08005056 else
developer8078acf2023-08-04 18:52:48 +08005057 res = _syscmd_secure(buf, sizeof(buf), "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 +08005058
developer8078acf2023-08-04 18:52:48 +08005059 if (res) {
5060 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08005061 }
developera3511852023-06-14 14:12:59 +08005062 strncpy(output_string, buf, strlen(buf) < sizeof(buf) ? strlen(buf) : sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005063
developera3511852023-06-14 14:12:59 +08005064 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5065 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005066}
developerd1824452023-05-18 12:30:04 +08005067//Getting current radio extension channel
5068INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
5069{
developera3511852023-06-14 14:12:59 +08005070 CHAR buf[150] = {0};
developer32f2a182023-06-27 19:50:41 +08005071 int len;
developerd1824452023-05-18 12:30:04 +08005072
developera3511852023-06-14 14:12:59 +08005073 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developerb14b3462023-07-01 18:02:42 +08005074
5075 if (strncmp(buf, "0", 1) == 0) {
developer32f2a182023-06-27 19:50:41 +08005076 len = strlen("BelowControlChannel");
5077 memcpy(Value, "BelowControlChannel", len);
developerc14d83a2023-06-29 20:09:42 +08005078 Value[len] = '\0';
developer32f2a182023-06-27 19:50:41 +08005079 }
developerb14b3462023-07-01 18:02:42 +08005080 else if(strncmp(buf, "1", 1) == 0) {
developer32f2a182023-06-27 19:50:41 +08005081 len = strlen("AboveControlChannel");
5082 memcpy(Value, "AboveControlChannel", len);
developerc14d83a2023-06-29 20:09:42 +08005083 Value[len] = '\0';
developer32f2a182023-06-27 19:50:41 +08005084 }
developer5b23cd02023-07-19 20:26:03 +08005085
developera3511852023-06-14 14:12:59 +08005086 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08005087}
developerf6a87542023-05-16 15:47:28 +08005088
developerb57e9a82023-11-22 18:29:55 +08005089enum bw_idx {
5090 BAND_WIDTH_20,
5091 BAND_WIDTH_40,
5092 BAND_WIDTH_80,
5093 BAND_WIDTH_160,
5094 BAND_WIDTH_8080 = 6,
5095 BAND_WIDTH_320
5096};
5097
5098struct hal_ch_layout {
5099 UCHAR ch_low_bnd;
5100 UCHAR ch_up_bnd;
5101 UCHAR cent_freq_idx;
5102};
5103
5104static struct hal_ch_layout ch_5G_40M[] = {
5105 {36, 40, 38},
5106 {44, 48, 46},
5107 {52, 56, 54},
5108 {60, 64, 62},
5109 {100, 104, 102},
5110 {108, 112, 110},
5111 {116, 120, 118},
5112 {124, 128, 126},
5113 {132, 136, 134},
5114 {140, 144, 142},
5115 {149, 153, 151},
5116 {157, 161, 159},
5117 {0, 0, 0},
5118};
5119
5120static struct hal_ch_layout ch_5G_80M[] = {
5121 {36, 48, 42},
5122 {52, 64, 58},
5123 {100, 112, 106},
5124 {116, 128, 122},
5125 {132, 144, 138},
5126 {149, 161, 155},
5127 {165, 177, 171},
5128 {0, 0, 0},
5129};
5130
5131static struct hal_ch_layout ch_5G_160M[] = {
5132 {36, 64, 50},
5133 {100, 128, 114},
5134 {149, 177, 163},
5135 {0, 0, 0},
5136};
5137
5138static struct hal_ch_layout ch_6G_40M[] = {
5139 {1, 5, 3},
5140 {9, 13, 11},
5141 {17, 21, 19},
5142 {25, 29, 27},
5143 {33, 37, 35},
5144 {41, 45, 43},
5145 {49, 53, 51},
5146 {57, 61, 59},
5147 {65, 69, 67},
5148 {73, 77, 75},
5149 {81, 85, 83},
5150 {89, 93, 91},
5151 {97, 101, 99},
5152 {105, 109, 107},
5153 {113, 117, 115},
5154 {121, 125, 123},
5155 {129, 133, 131},
5156 {137, 141, 139},
5157 {145, 149, 147},
5158 {153, 157, 155},
5159 {161, 165, 163},
5160 {169, 173, 171},
5161 {177, 181, 179},
5162 {185, 189, 187},
5163 {193, 197, 195},
5164 {201, 205, 203},
5165 {209, 213, 211},
5166 {217, 221, 219},
5167 {225, 229, 227},
5168 {0, 0, 0},
5169};
5170
5171static struct hal_ch_layout ch_6G_80M[] = {
5172 {1, 13, 7},
5173 {17, 29, 23},
5174 {33, 45, 39},
5175 {49, 61, 55},
5176 {65, 77, 71},
5177 {81, 93, 87},
5178 {97, 109, 103},
5179 {113, 125, 119},
5180 {129, 141, 135},
5181 {145, 157, 151},
5182 {161, 173, 167},
5183 {177, 189, 183},
5184 {193, 205, 199},
5185 {209, 221, 215},
5186 {0, 0, 0},
5187};
5188
5189static struct hal_ch_layout ch_6G_160M[] = {
5190 {1, 29, 15},
5191 {33, 61, 47},
5192 {65, 93, 79},
5193 {97, 125, 111},
5194 {129, 157, 143},
5195 {161, 189, 175},
5196 {193, 221, 207},
5197 {0, 0, 0},
5198};
5199
5200static struct hal_ch_layout ch_6G_320M[] = {
5201 {1, 61, 31},
5202 {33, 93, 63},
5203 {65, 125, 95},
5204 {97, 157, 127},
5205 {129, 189, 159},
5206 {161, 221, 191},
5207 {0, 0, 0},
5208};
5209
5210struct hal_ch_layout *hal_get_ch_array(UCHAR bw, UCHAR ch_band, UCHAR *layout_size)
5211{
5212 switch (ch_band) {
5213 case band_5:
5214 if (bw == BAND_WIDTH_40) {
5215 *layout_size = ARRAY_SIZE(ch_5G_40M);
5216 return ch_5G_40M;
5217 } else if (bw == BAND_WIDTH_80) {
5218 *layout_size = ARRAY_SIZE(ch_5G_80M);
5219 return ch_5G_80M;
5220 } else if (bw == BAND_WIDTH_160) {
5221 *layout_size = ARRAY_SIZE(ch_5G_160M);
5222 return ch_5G_160M;
5223 } else
5224 return NULL;
5225
5226 case band_6:
5227 if (bw == BAND_WIDTH_40) {
5228 *layout_size = ARRAY_SIZE(ch_6G_40M);
5229 return ch_6G_40M;
5230 } else if (bw == BAND_WIDTH_80) {
5231 *layout_size = ARRAY_SIZE(ch_6G_80M);
5232 return ch_6G_80M;
5233 } else if (bw == BAND_WIDTH_160) {
5234 *layout_size = ARRAY_SIZE(ch_6G_160M);
5235 return ch_6G_160M;
5236 } else if (bw == BAND_WIDTH_320) {
5237 *layout_size = ARRAY_SIZE(ch_6G_320M);
5238 return ch_6G_320M;
5239 } else
5240 return NULL;
5241
5242 default:
5243 return NULL;
5244 }
5245}
5246
5247enum ext_ch {
5248 EXT_NONE,
5249 EXT_ABOVE,
5250 EXT_BELOW = 3
5251};
5252
5253int get_ExtCh_callback(struct nl_msg *msg, void *arg)
5254{
5255 UCHAR *data = (UCHAR *)arg;
5256 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5257 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
5258 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5259 int err = 0;
5260
5261 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5262 genlmsg_attrlen(gnlh, 0), NULL);
5263 if (err < 0)
5264 return NL_SKIP;
5265
5266 if (tb[NL80211_ATTR_VENDOR_DATA]) {
5267 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
5268 tb[NL80211_ATTR_VENDOR_DATA], NULL);
5269 if (err < 0)
5270 return NL_SKIP;
5271
5272 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL]) {
5273 *data = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL]);
5274 }
5275 }
5276
5277 return NL_OK;
5278}
5279
5280//Get the extension channel via netlink
5281UCHAR wifi_getExtCh_netlink(INT radioIndex)
5282{
5283 char interface_name[IF_NAME_SIZE] = {0};
5284 int ret = -1;
5285 unsigned int if_idx = 0;
5286 struct unl unl_ins;
5287 struct nl_msg *msg = NULL;
5288 struct nlattr * msg_data = NULL;
5289 struct mtk_nl80211_param param;
5290 UCHAR ext_ch = EXT_NONE;
developerc3556192023-12-06 17:59:09 +08005291 int main_vap_idx;
developerb57e9a82023-11-22 18:29:55 +08005292
5293 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5294
developerc3556192023-12-06 17:59:09 +08005295 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
5296 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
5297 return RETURN_ERR;
5298 }
5299
5300 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developerb57e9a82023-11-22 18:29:55 +08005301 return RETURN_ERR;
5302
5303 if_idx = if_nametoindex(interface_name);
5304 if (!if_idx) {
5305 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
5306 return RETURN_ERR;
5307 }
5308 /*init mtk nl80211 vendor cmd*/
5309 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
5310 param.if_type = NL80211_ATTR_IFINDEX;
5311 param.if_idx = if_idx;
5312
5313 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
5314 if (ret) {
5315 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
5316 return RETURN_ERR;
5317 }
5318
5319 /*add mtk vendor cmd data*/
5320 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL, 0)) {
5321 wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL attribute error\n");
5322 nlmsg_free(msg);
5323 goto err;
5324 }
5325
5326 /*send mtk nl80211 vendor msg*/
5327 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ExtCh_callback, &ext_ch);
5328
5329 if (ret) {
5330 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
5331 goto err;
5332 }
5333 /*deinit mtk nl80211 vendor msg*/
5334 mtk_nl80211_deint(&unl_ins);
5335 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
5336
5337 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5338 return ext_ch;
5339err:
5340 mtk_nl80211_deint(&unl_ins);
5341 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
5342 return EXT_NONE;
5343
5344}
5345
developer72fb0bb2023-01-11 09:46:29 +08005346//Get the list for used channel. eg: "1,6,9,11"
developerb57e9a82023-11-22 18:29:55 +08005347//the returned channels will be the all sub channels that the whole operating bw covers
developer72fb0bb2023-01-11 09:46:29 +08005348//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.
5349INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
5350{
developerb57e9a82023-11-22 18:29:55 +08005351 wifi_band band;
5352 ULONG pri_ch = 0;
developer96d86a02023-12-22 10:42:01 +08005353 UCHAR bw = BAND_WIDTH_20;
5354 CHAR bw_str[64] = {0};
developerb57e9a82023-11-22 18:29:55 +08005355 UCHAR ext_ch = EXT_NONE;
5356 UCHAR sub_ch_list[16] = {0};
5357 UCHAR sub_ch_num = 0;
5358 struct hal_ch_layout *layout = NULL;
5359 UCHAR layout_size = 0;
5360 UCHAR sub_ch = 0;
5361 UCHAR count = 0;
developere40952c2023-06-15 18:46:43 +08005362 int res;
developer72fb0bb2023-01-11 09:46:29 +08005363
developerb57e9a82023-11-22 18:29:55 +08005364 if (output_string == NULL) {
5365 wifi_debug(DEBUG_ERROR, "output_string is NULL, return\n");
5366 return RETURN_ERR;
5367 }
developer72fb0bb2023-01-11 09:46:29 +08005368
developerdfd270b2023-12-12 10:24:30 +08005369 band = radio_index_to_band(radioIndex);
developerb57e9a82023-11-22 18:29:55 +08005370 if (band == band_invalid) {
5371 wifi_debug(DEBUG_ERROR, "invalid band, return\n");
developera3511852023-06-14 14:12:59 +08005372 return RETURN_ERR;
developerb57e9a82023-11-22 18:29:55 +08005373 }
developer72fb0bb2023-01-11 09:46:29 +08005374
developerb57e9a82023-11-22 18:29:55 +08005375 /*get pri_ch*/
5376 if (wifi_getRadioChannel(radioIndex, &pri_ch) != RETURN_OK) {
5377 wifi_debug(DEBUG_ERROR, "Fail to get primary ch, return\n");
developera3511852023-06-14 14:12:59 +08005378 return RETURN_ERR;
developerb57e9a82023-11-22 18:29:55 +08005379 }
developer75bd10c2023-06-27 11:34:08 +08005380
developerb57e9a82023-11-22 18:29:55 +08005381 if (pri_ch == 0) {
5382 wifi_debug(DEBUG_ERROR, "invalid primary ch, return\n");
5383 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08005384 }
developerb57e9a82023-11-22 18:29:55 +08005385
5386 /*get bw*/
developer96d86a02023-12-22 10:42:01 +08005387 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, bw_str) != RETURN_OK) {
5388 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
developera3511852023-06-14 14:12:59 +08005389 return RETURN_ERR;
5390 }
developerb57e9a82023-11-22 18:29:55 +08005391
developer96d86a02023-12-22 10:42:01 +08005392 if (!strcmp(bw_str, "20MHz")) bw = BAND_WIDTH_20;
5393 else if (!strcmp(bw_str, "40MHz")) bw = BAND_WIDTH_40;
5394 else if (!strcmp(bw_str, "80MHz")) bw = BAND_WIDTH_80;
5395 else if (!strcmp(bw_str, "160MHz")) bw = BAND_WIDTH_160;
5396 else if (!strcmp(bw_str, "320MHz")) bw = BAND_WIDTH_320;
5397 else {
5398 wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", bw_str);
5399 bw = BAND_WIDTH_20;
developerd14dff12023-06-28 22:47:44 +08005400 }
developer72fb0bb2023-01-11 09:46:29 +08005401
developer166ae622023-12-21 15:27:09 +08005402 /*get ext_ch for 2G 40M and 6G 320M*/
5403 if ((band == band_2_4 && bw == BAND_WIDTH_40) ||
developer96d86a02023-12-22 10:42:01 +08005404 (band == band_6 && bw == BAND_WIDTH_320)) {
5405 char ext_ch_str[64]= {0};
5406 wifi_getRadioExtChannel(radioIndex, ext_ch_str);
5407 if (!strcmp(ext_ch_str, "AboveControlChannel"))
5408 ext_ch = EXT_ABOVE;
5409 else if (!strcmp(ext_ch_str, "BelowControlChannel"))
5410 ext_ch = EXT_BELOW;
5411 else
5412 ext_ch = EXT_NONE;
5413 }
developerb57e9a82023-11-22 18:29:55 +08005414
5415 /*2G 40M ext_ch sainity check, if check fail, only return primary ch*/
5416 if (band == band_2_4 && bw == BAND_WIDTH_40) {
5417 if (((ext_ch == EXT_ABOVE) && ((pri_ch + 4) > 14))
5418 || ((ext_ch == EXT_BELOW) && ((pri_ch - 4) < 1))) {
5419 wifi_debug(DEBUG_ERROR, "EXTCHA channels out of range\n");
5420 bw = BAND_WIDTH_20;
5421 } else if (ext_ch == EXT_NONE) {
5422 wifi_debug(DEBUG_ERROR, "EXTCHA is NONE for 40M\n");
5423 bw = BAND_WIDTH_20;
developere40952c2023-06-15 18:46:43 +08005424 }
developera3511852023-06-14 14:12:59 +08005425 }
developer72fb0bb2023-01-11 09:46:29 +08005426
developerb57e9a82023-11-22 18:29:55 +08005427 /*20M case, only return primary ch*/
5428 if (bw == BAND_WIDTH_20) {
5429 sub_ch_list[0] = pri_ch;
5430 sub_ch_num = 1;
5431 goto output;
5432 }
developer72fb0bb2023-01-11 09:46:29 +08005433
developerb57e9a82023-11-22 18:29:55 +08005434 /*2G/40M case, return all sub channels*/
5435 if ((band == band_2_4) && (bw == BAND_WIDTH_40)) {
5436 if (ext_ch == EXT_ABOVE) {
5437 for (count = 0, sub_ch = pri_ch; (sub_ch <= 14) && (sub_ch <= pri_ch + 4); count++, sub_ch++)
5438 sub_ch_list[count] = sub_ch;
5439 sub_ch_num = count;
5440 } else if (ext_ch == EXT_BELOW) {
5441 for (count = 0, sub_ch = pri_ch - 4; (sub_ch > 0) && (sub_ch <= pri_ch); count++, sub_ch++)
5442 sub_ch_list[count] = sub_ch;
5443 sub_ch_num = count;
developer32f2a182023-06-27 19:50:41 +08005444 }
developerb57e9a82023-11-22 18:29:55 +08005445 goto output;
5446 }
developer72fb0bb2023-01-11 09:46:29 +08005447
developerb57e9a82023-11-22 18:29:55 +08005448 /*for 5G/6G, need find layout*/
5449 if ((band == band_5) || (band == band_6)) {
5450 UCHAR index;
5451 UCHAR i;
5452 UCHAR ch_find = FALSE;
5453
5454 layout = hal_get_ch_array(bw, band, &layout_size);
5455 /*can not find, only return primary ch*/
5456 if (layout == NULL) {
5457 sub_ch_list[0] = pri_ch;
5458 sub_ch_num = 1;
5459 goto output;
developera3511852023-06-14 14:12:59 +08005460 }
developerb758dfd2023-06-21 17:32:07 +08005461
developerb57e9a82023-11-22 18:29:55 +08005462 /*find the layout[index] which contains the channels in use*/
5463 /*need consider 320M EXT here*/
5464 for (i = 0; i < layout_size; i++) {
5465 if (bw == BAND_WIDTH_320) {
5466 if ((pri_ch >= layout[i].ch_low_bnd) && (pri_ch <= layout[i].ch_up_bnd)
5467 && (ext_ch == EXT_ABOVE) && (pri_ch < layout[i].cent_freq_idx)) {
5468 ch_find = TRUE;
5469 index = i;
5470 break;
5471 } else if ((pri_ch >= layout[i].ch_low_bnd) && (pri_ch <= layout[i].ch_up_bnd)
5472 && (ext_ch == EXT_BELOW) && (pri_ch > layout[i].cent_freq_idx)) {
5473 ch_find = TRUE;
5474 index = i;
5475 break;
5476 }
5477 } else {
5478 if ((pri_ch >= layout[i].ch_low_bnd) && (pri_ch <= layout[i].ch_up_bnd)) {
5479 ch_find = TRUE;
5480 index = i;
5481 break;
5482 }
5483 }
5484 }
5485
5486 /*fill in sub_ch_list from layout[index]*/
5487 if (ch_find) {
5488 UCHAR start_ch = layout[index].ch_low_bnd;
5489 UCHAR end_ch = layout[index].ch_up_bnd;
5490 for (count = 0, sub_ch = start_ch; sub_ch <= end_ch; count++, sub_ch = sub_ch + 4)
5491 sub_ch_list[count] = sub_ch;
5492 sub_ch_num = count;
5493 } else
5494 wifi_debug(DEBUG_ERROR, "find layout[index] fail\n");
5495 }
5496
5497output:
developer96d86a02023-12-22 10:42:01 +08005498 for (count = 0; (count < sub_ch_num) && (sub_ch_num <= 16); count++) {
developerb57e9a82023-11-22 18:29:55 +08005499 if (count == (sub_ch_num - 1))
5500 res = snprintf(output_string + strlen(output_string), 256 - strlen(output_string), "%d", sub_ch_list[count]);
5501 else
5502 res = snprintf(output_string + strlen(output_string), 256 - strlen(output_string), "%d,", sub_ch_list[count]);
developere40952c2023-06-15 18:46:43 +08005503 if (os_snprintf_error(256, res)) {
5504 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5505 return RETURN_ERR;
5506 }
developerb57e9a82023-11-22 18:29:55 +08005507 }
developer72fb0bb2023-01-11 09:46:29 +08005508
developera3511852023-06-14 14:12:59 +08005509 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005510}
5511
developer408cde72023-10-19 13:44:02 +08005512int get_channel_handler(struct nl_msg *msg, void *data)
5513{
5514 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5515 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX + 1];
5516 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5517 unsigned char *channel = (unsigned char *)data;
5518 int err = 0;
5519
5520 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5521 genlmsg_attrlen(gnlh, 0), NULL);
5522 if (err < 0)
5523 return err;
5524
5525 if (tb[NL80211_ATTR_VENDOR_DATA]) {
5526 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX,
5527 tb[NL80211_ATTR_VENDOR_DATA], NULL);
5528 if (err < 0)
5529 return err;
5530
5531 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL]) {
5532 *channel = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL]);
5533 }
5534 }
5535
5536 return 0;
5537}
5538
5539INT mtk_wifi_get_radio_info(
5540 INT radioIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, void *output)
5541{
5542 int ret = -1;
5543 struct unl unl_ins;
5544 struct nl_msg *msg = NULL;
5545 struct nlattr * msg_data = NULL;
5546 struct mtk_nl80211_param param;
5547
5548 /*init mtk nl80211 vendor cmd*/
5549 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_BAND_INFO;
5550 param.if_type = NL80211_ATTR_WIPHY;
5551 param.if_idx = radio_index_to_phy(radioIndex);
5552
5553 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
5554 if (ret) {
5555 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
5556 return RETURN_ERR;
5557 }
5558 /*add mtk vendor cmd data*/
5559 if (nla_put_u8(msg, vendor_data_attr, 1)) {
5560 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
5561 nlmsg_free(msg);
5562 goto err;
5563 }
5564
5565 /*send mtk nl80211 vendor msg*/
5566 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
5567 if (ret) {
5568 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
5569 goto err;
5570 }
5571 /*deinit mtk nl80211 vendor msg*/
5572 mtk_nl80211_deint(&unl_ins);
5573 wifi_debug(DEBUG_INFO, "send cmd success.\n");
5574
5575 return RETURN_OK;
5576err:
5577 mtk_nl80211_deint(&unl_ins);
5578 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
5579 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005580}
5581
developer69b61b02023-03-07 17:17:44 +08005582//Get the running channel number
developerd1824452023-05-18 12:30:04 +08005583INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08005584{
developera3511852023-06-14 14:12:59 +08005585 char channel_str[16] = {0};
5586 char config_file[128] = {0};
developera3511852023-06-14 14:12:59 +08005587 wifi_band band = band_invalid;
developer408cde72023-10-19 13:44:02 +08005588 unsigned char channel;
developere40952c2023-06-15 18:46:43 +08005589 int res;
developer47a56bf2023-05-30 13:38:57 +08005590
developera3511852023-06-14 14:12:59 +08005591 if (output_ulong == NULL)
5592 return RETURN_ERR;
developerdfd270b2023-12-12 10:24:30 +08005593 band = radio_index_to_band(radioIndex);
developerb758dfd2023-06-21 17:32:07 +08005594 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08005595 if (os_snprintf_error(sizeof(config_file), res)) {
5596 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5597 return RETURN_ERR;
5598 }
5599
developera3511852023-06-14 14:12:59 +08005600 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
developerb14b3462023-07-01 18:02:42 +08005601 if (hal_strtoul(channel_str, 10, output_ulong) < 0) {
developerc14d83a2023-06-29 20:09:42 +08005602 wifi_debug(DEBUG_ERROR, "strtol fail\n");
5603 }
developera3511852023-06-14 14:12:59 +08005604 if (*output_ulong == 0) {
developer408cde72023-10-19 13:44:02 +08005605 if (mtk_wifi_get_radio_info(radioIndex, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL,
5606 get_channel_handler, &channel)!= RETURN_OK) {
5607 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL cmd fails\n");
developerd14dff12023-06-28 22:47:44 +08005608 return RETURN_ERR;
5609 }
developer408cde72023-10-19 13:44:02 +08005610 *output_ulong = channel;
developera3511852023-06-14 14:12:59 +08005611 }
developer72fb0bb2023-01-11 09:46:29 +08005612
developera3511852023-06-14 14:12:59 +08005613 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005614}
5615
developer72fb0bb2023-01-11 09:46:29 +08005616INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
5617{
developer8078acf2023-08-04 18:52:48 +08005618 char buf[5] = {0};
developera3511852023-06-14 14:12:59 +08005619 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08005620 int res;
developer72fb0bb2023-01-11 09:46:29 +08005621
developera3511852023-06-14 14:12:59 +08005622 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5623 if (NULL == output_ulong)
5624 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005625
developera3511852023-06-14 14:12:59 +08005626 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5627 return RETURN_ERR;
developer47a56bf2023-05-30 13:38:57 +08005628
developer8078acf2023-08-04 18:52:48 +08005629
5630 res = _syscmd_secure(buf, sizeof(buf), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
5631 if (res) {
5632 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
5633 }
developera3511852023-06-14 14:12:59 +08005634 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
5635 if (*output_ulong == 0) {
5636 return RETURN_ERR;
5637 }
developer72fb0bb2023-01-11 09:46:29 +08005638
developera3511852023-06-14 14:12:59 +08005639 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5640 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005641}
developer72fb0bb2023-01-11 09:46:29 +08005642//Storing the previous channel value
5643INT wifi_storeprevchanval(INT radioIndex)
5644{
developera3511852023-06-14 14:12:59 +08005645 char output[4]={'\0'};
5646 char config_file[MAX_BUF_SIZE] = {0};
5647 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08005648 int res;
developerd1824452023-05-18 12:30:04 +08005649
developerdfd270b2023-12-12 10:24:30 +08005650 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08005651 if (band == band_invalid) {
5652 return RETURN_ERR;
5653 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
5654 }
developere40952c2023-06-15 18:46:43 +08005655 res = snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
5656 if (os_snprintf_error(sizeof(config_file), res)) {
5657 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5658 return RETURN_ERR;
5659 }
5660
developera3511852023-06-14 14:12:59 +08005661 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
developerd1824452023-05-18 12:30:04 +08005662
developera3511852023-06-14 14:12:59 +08005663 if(band == band_2_4)
developer33f13ba2023-07-12 16:19:06 +08005664 res = v_secure_system("echo %s > /var/prevchanval2G_AutoChannelEnable", output);
developera3511852023-06-14 14:12:59 +08005665 else if(band == band_5)
developer33f13ba2023-07-12 16:19:06 +08005666 res = v_secure_system("echo %s > /var/prevchanval5G_AutoChannelEnable", output);
developera3511852023-06-14 14:12:59 +08005667 else
developer33f13ba2023-07-12 16:19:06 +08005668 res = v_secure_system("echo %s > /var/prevchanval6G_AutoChannelEnable", output);
developer75bd10c2023-06-27 11:34:08 +08005669
developer33f13ba2023-07-12 16:19:06 +08005670 if (res) {
5671 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developer75bd10c2023-06-27 11:34:08 +08005672 }
developera3511852023-06-14 14:12:59 +08005673 Radio_flag = FALSE;
5674 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005675}
5676
5677//Set the running channel number
5678INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
5679{
developera3511852023-06-14 14:12:59 +08005680 // We only write hostapd config here
5681 char str_channel[8]={0};
5682 char *list_channel;
5683 char possible_channels[256] = {0};
5684 char config_file_dat[128] = {0};
5685 struct params dat = {0};
5686 struct params acs = {0};
5687 wifi_band band = band_invalid;
5688 bool acs_channel = false;
developere40952c2023-06-15 18:46:43 +08005689 int res;
developereef7d562023-10-21 16:04:21 +08005690 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08005691
developera3511852023-06-14 14:12:59 +08005692 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005693
developera3511852023-06-14 14:12:59 +08005694 if (channel == 0)
5695 acs_channel = true;
5696 // Check valid
developer75bd10c2023-06-27 11:34:08 +08005697 res = snprintf(str_channel, sizeof(str_channel), "%lu", channel);
5698 if (os_snprintf_error(sizeof(str_channel), res)) {
5699 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5700 return RETURN_ERR;
5701 }
developer47a56bf2023-05-30 13:38:57 +08005702
developera3511852023-06-14 14:12:59 +08005703 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
5704 list_channel = strtok(possible_channels, ",");
5705 while(true)
5706 {
5707 if(list_channel == NULL) { // input not in the list
developer75bd10c2023-06-27 11:34:08 +08005708 wifi_debug(DEBUG_ERROR, "Channel %s is not in possible list\n", str_channel);
developera3511852023-06-14 14:12:59 +08005709 return RETURN_ERR;
5710 }
5711 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
5712 break;
5713 list_channel = strtok(NULL, ",");
5714 }
5715 /*
5716 list.name = "channel";
5717 list.value = str_channel;
5718 wifi_getMaxRadioNumber(&max_radio_num);
5719 for(int i=0; i<=MAX_APS/max_radio_num;i++)
5720 {
5721 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
5722 wifi_hostapdWrite(config_file, &list, 1);
5723 }
5724 */
5725 dat.name = "Channel";
5726 dat.value = str_channel;
developerdfd270b2023-12-12 10:24:30 +08005727 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08005728 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
5729 if (os_snprintf_error(sizeof(config_file_dat), res)) {
5730 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5731 return RETURN_ERR;
5732 }
developera3511852023-06-14 14:12:59 +08005733 wifi_datfileWrite(config_file_dat, &dat, 1);
developereef7d562023-10-21 16:04:21 +08005734
developera3511852023-06-14 14:12:59 +08005735 if (acs_channel == true) {
5736 acs.name = "AutoChannelSelect";
5737 acs.value = "3";
5738 } else {
5739 acs.name = "AutoChannelSelect";
5740 acs.value = "0";
5741 }
5742 wifi_datfileWrite(config_file_dat, &acs, 1);
developereef7d562023-10-21 16:04:21 +08005743
5744 /*do channel quick setting*/
5745 if (channel != 0) {
5746 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL, NULL, NULL);
5747 if (ret != RETURN_OK)
5748 wifi_debug(DEBUG_ERROR, "channel quick setting fail\n");
developer5b23cd02023-07-19 20:26:03 +08005749 }
5750
developera3511852023-06-14 14:12:59 +08005751 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5752 return RETURN_OK;
5753}
5754
5755INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
5756{
5757 struct params list[2];
5758 char str_idx[16];
5759 char config_file[64];
developerc3556192023-12-06 17:59:09 +08005760 int res, bss_idx, vap_idx;
developera3511852023-06-14 14:12:59 +08005761 wifi_band band = band_invalid;
5762
developerdfd270b2023-12-12 10:24:30 +08005763 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08005764 if (band == band_2_4)
5765 return RETURN_OK;
5766
developere40952c2023-06-15 18:46:43 +08005767 res = snprintf(str_idx, sizeof(str_idx), "%lu", channel);
5768 if (os_snprintf_error(sizeof(str_idx), res)) {
5769 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5770 return RETURN_ERR;
5771 }
5772
developera3511852023-06-14 14:12:59 +08005773 list[0].name = "vht_oper_centr_freq_seg0_idx";
5774 list[0].value = str_idx;
5775 list[1].name = "he_oper_centr_freq_seg0_idx";
5776 list[1].value = str_idx;
5777
developerc3556192023-12-06 17:59:09 +08005778 for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++)
developera3511852023-06-14 14:12:59 +08005779 {
developerc3556192023-12-06 17:59:09 +08005780 if (array_index_to_vap_index(radioIndex, bss_idx, &vap_idx) != RETURN_OK) {
5781 wifi_debug(DEBUG_ERROR, "invalid radioIndex[%d], bss_idx[%d]\n", radioIndex, bss_idx);
5782 return RETURN_ERR;
5783 }
5784 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_idx);
developere40952c2023-06-15 18:46:43 +08005785 if (os_snprintf_error(sizeof(config_file), res)) {
5786 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5787 return RETURN_ERR;
5788 }
developera3511852023-06-14 14:12:59 +08005789 if (band == band_6)
5790 wifi_hostapdWrite(config_file, &list[1], 1);
5791 else
5792 wifi_hostapdWrite(config_file, list, 2);
5793 }
5794
5795 return RETURN_OK;
5796}
5797
5798//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
5799//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
5800INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
5801{
5802 //Set to wifi config only. Wait for wifi reset to apply.
5803 ULONG Value = 0;
5804 char config_file_dat[128] = {0};
5805 struct params acs = {0};
5806 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08005807 int res;
developera3511852023-06-14 14:12:59 +08005808
5809 if(enable == TRUE) {
5810 wifi_setRadioChannel(radioIndex,Value);
5811 } else {
5812 acs.name = "AutoChannelSelect";
5813 acs.value = "0";
developerdfd270b2023-12-12 10:24:30 +08005814 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08005815 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
5816 if (os_snprintf_error(sizeof(config_file_dat), res)) {
5817 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5818 return RETURN_ERR;
5819 }
developera3511852023-06-14 14:12:59 +08005820 wifi_datfileWrite(config_file_dat, &acs, 1);
5821 }
5822 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005823}
5824
5825INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
5826{
developera3511852023-06-14 14:12:59 +08005827 if (output_bool == NULL)
5828 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005829
developera3511852023-06-14 14:12:59 +08005830 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08005831
developera3511852023-06-14 14:12:59 +08005832 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005833}
5834
5835INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
5836{
developera3511852023-06-14 14:12:59 +08005837 if (NULL == output_bool)
5838 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08005839 *output_bool=TRUE;
developera3511852023-06-14 14:12:59 +08005840 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005841}
5842
5843INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
5844{
developer326d4232023-06-15 16:45:30 +08005845 unsigned long period = 0;
5846
developera3511852023-06-14 14:12:59 +08005847 if (NULL == output_bool)
5848 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08005849
5850 if (wifi_getRadioAutoChannelRefreshPeriod(radioIndex, &period) != RETURN_OK)
developerb758dfd2023-06-21 17:32:07 +08005851 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08005852
5853 *output_bool = (period > 0) ? TRUE : FALSE;
5854
developera3511852023-06-14 14:12:59 +08005855 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005856}
5857
developer326d4232023-06-15 16:45:30 +08005858INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08005859{
developer326d4232023-06-15 16:45:30 +08005860 ULONG period = 1800;
5861
5862 if (enable == TRUE) {
5863 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, period) != RETURN_OK)
5864 return RETURN_ERR;
5865 }
5866 else {
5867 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, 0) != RETURN_OK)
5868 return RETURN_ERR;
5869 }
developera3511852023-06-14 14:12:59 +08005870 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005871}
5872
5873INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
5874{
developera3511852023-06-14 14:12:59 +08005875 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005876}
5877
5878INT wifi_factoryResetAP(int apIndex)
5879{
developerb149d9d2023-06-06 16:14:22 +08005880 char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
developer8078acf2023-08-04 18:52:48 +08005881
developer47cc27a2023-05-17 23:09:58 +08005882 char ret_buf[MAX_BUF_SIZE] = {0};
5883 int radio_idx = 0;
5884 int bss_idx = 0;
5885 char ssid[32] = {0};
5886 char interface[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08005887 char psk_file[MAX_SUB_CMD_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08005888 struct params params[3] = {0};
developere40952c2023-06-15 18:46:43 +08005889 int res;
developer72fb0bb2023-01-11 09:46:29 +08005890
developera3511852023-06-14 14:12:59 +08005891 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005892
developer47cc27a2023-05-17 23:09:58 +08005893 /*del old config file*/
developer9ce44382023-06-28 11:09:37 +08005894 res = snprintf(ap_config_file, sizeof(ap_config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd14dff12023-06-28 22:47:44 +08005895 if (os_snprintf_error(sizeof(ap_config_file), res)) {
developere40952c2023-06-15 18:46:43 +08005896 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5897 return RETURN_ERR;
5898 }
5899
developer8078acf2023-08-04 18:52:48 +08005900 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "rm %s", ap_config_file);
5901 if (res) {
5902 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08005903 }
5904
developer72fb0bb2023-01-11 09:46:29 +08005905
developer47cc27a2023-05-17 23:09:58 +08005906 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08005907
developerc3556192023-12-06 17:59:09 +08005908 vap_index_to_radio_array_index(apIndex, &radio_idx, &bss_idx);
developer47cc27a2023-05-17 23:09:58 +08005909
5910 /*prepare new config file*/
developer8078acf2023-08-04 18:52:48 +08005911
5912 res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
5913 if (res) {
5914 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08005915 }
5916
developer47cc27a2023-05-17 23:09:58 +08005917
5918 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08005919 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
5920 if (os_snprintf_error(sizeof(ssid), res)) {
5921 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5922 return RETURN_ERR;
5923 }
5924
5925 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
5926 if (os_snprintf_error(sizeof(interface), res)) {
5927 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5928 return RETURN_ERR;
5929 }
developer47cc27a2023-05-17 23:09:58 +08005930 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08005931 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
5932 if (os_snprintf_error(sizeof(ssid), res)) {
5933 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5934 return RETURN_ERR;
5935 }
5936
5937 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
5938 if (os_snprintf_error(sizeof(interface), res)) {
5939 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5940 return RETURN_ERR;
5941 }
developer47cc27a2023-05-17 23:09:58 +08005942 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08005943 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
5944 if (os_snprintf_error(sizeof(ssid), res)) {
5945 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5946 return RETURN_ERR;
5947 }
5948
5949 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
5950 if (os_snprintf_error(sizeof(interface), res)) {
5951 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5952 return RETURN_ERR;
5953 }
developer47cc27a2023-05-17 23:09:58 +08005954 }
5955
5956 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08005957 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
5958 if (os_snprintf_error(sizeof(psk_file), res)) {
5959 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5960 return RETURN_ERR;
5961 }
developer47cc27a2023-05-17 23:09:58 +08005962
5963 params[0].name = "ssid";
5964 params[0].value = ssid;
5965 params[1].name = "interface";
5966 params[1].value = interface;
5967 params[2].name = "wpa_psk_file";
5968 params[2].value = psk_file;
5969
5970 wifi_hostapdWrite(ap_config_file, params, 3);
5971
5972 /*clear psk file*/
developer8078acf2023-08-04 18:52:48 +08005973
developer47cc27a2023-05-17 23:09:58 +08005974 memset(ret_buf, 0, sizeof(ret_buf));
5975
developere40952c2023-06-15 18:46:43 +08005976 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
5977 if (os_snprintf_error(sizeof(psk_file), res)) {
5978 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5979 return RETURN_ERR;
5980 }
developer47cc27a2023-05-17 23:09:58 +08005981
5982 if (access(psk_file, F_OK) != 0) {
developer8078acf2023-08-04 18:52:48 +08005983 res = _syscmd_secure(ret_buf,sizeof(ret_buf), "touch %s", psk_file);
5984 if (res) {
5985 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08005986 }
5987
developer47cc27a2023-05-17 23:09:58 +08005988 } else {
developer8078acf2023-08-04 18:52:48 +08005989
5990 res = _syscmd_secure(ret_buf,sizeof(ret_buf), "echo '' > %s", psk_file);
5991 if (res) {
5992 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08005993 }
5994
developer47cc27a2023-05-17 23:09:58 +08005995 }
5996
developer429ba832023-05-31 11:03:35 +08005997 wifi_setApEnable(apIndex, FALSE);
5998 wifi_setApEnable(apIndex, TRUE);
developer47cc27a2023-05-17 23:09:58 +08005999 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6000
6001 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006002}
6003
developer72fb0bb2023-01-11 09:46:29 +08006004INT wifi_setBandSteeringApGroup(char *ApGroup)
6005{
developera3511852023-06-14 14:12:59 +08006006 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006007}
6008
6009INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
6010{
developera3511852023-06-14 14:12:59 +08006011 char config_file[128] = {'\0'};
6012 char buf[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +08006013 int res;
developerc14d83a2023-06-29 20:09:42 +08006014 long int tmp;
developer5b23cd02023-07-19 20:26:03 +08006015
developera3511852023-06-14 14:12:59 +08006016 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6017 if (dtimInterval == NULL)
6018 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006019
6020 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6021 if (os_snprintf_error(sizeof(config_file), res)) {
6022 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6023 return RETURN_ERR;
6024 }
developer72fb0bb2023-01-11 09:46:29 +08006025
developera3511852023-06-14 14:12:59 +08006026 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006027
developera3511852023-06-14 14:12:59 +08006028 if (strlen(buf) == 0) {
6029 *dtimInterval = 2;
6030 } else {
developerc14d83a2023-06-29 20:09:42 +08006031 if (hal_strtol(buf, 10, &tmp) < 0) {
6032 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08006033 }
developerc14d83a2023-06-29 20:09:42 +08006034 *dtimInterval = tmp;
developera3511852023-06-14 14:12:59 +08006035 }
developer72fb0bb2023-01-11 09:46:29 +08006036
developera3511852023-06-14 14:12:59 +08006037 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6038 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006039}
6040
6041INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
6042{
developera3511852023-06-14 14:12:59 +08006043 struct params params={0};
6044 char config_file[MAX_BUF_SIZE] = {'\0'};
6045 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08006046 int res;
developer72fb0bb2023-01-11 09:46:29 +08006047
developera3511852023-06-14 14:12:59 +08006048 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6049 if (dtimInterval < 1 || dtimInterval > 255) {
6050 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
6051 return RETURN_ERR;
6052 }
developer69b61b02023-03-07 17:17:44 +08006053
developera3511852023-06-14 14:12:59 +08006054 params.name = "dtim_period";
developere40952c2023-06-15 18:46:43 +08006055 res = snprintf(buf, sizeof(buf), "%d", dtimInterval);
6056 if (os_snprintf_error(sizeof(buf), res)) {
6057 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6058 return RETURN_ERR;
6059 }
developera3511852023-06-14 14:12:59 +08006060 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08006061
developer75bd10c2023-06-27 11:34:08 +08006062 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6063 if (os_snprintf_error(sizeof(config_file), res)) {
6064 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6065 return RETURN_ERR;
6066 }
developera3511852023-06-14 14:12:59 +08006067 wifi_hostapdWrite(config_file, &params, 1);
6068 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08006069
developera3511852023-06-14 14:12:59 +08006070 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6071 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006072}
6073
6074//Check if the driver support the Dfs
6075INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
6076{
developera3511852023-06-14 14:12:59 +08006077 wifi_band band = band_invalid;
6078 if (NULL == output_bool)
6079 return RETURN_ERR;
6080 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006081
developerdfd270b2023-12-12 10:24:30 +08006082 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08006083 if (band == band_5)
6084 *output_bool = TRUE;
6085 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006086}
6087
6088//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.
6089//The value of this parameter is a comma seperated list of channel number
6090INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
6091{
developer326d4232023-06-15 16:45:30 +08006092
6093 #define CHANNEL_AVAILABLE 0
6094 #define CHANNEL_INVALID 1
6095 #define CHANNEL_LIST_MAX_LENGTH 256
6096 #define MAX_CHANNEL_NUMBER 255
6097
6098 char config_file[MAX_BUF_SIZE] = {0};
6099 char possible_channels[CHANNEL_LIST_MAX_LENGTH] = {0};
6100 char skip_list[CHANNEL_LIST_MAX_LENGTH] = {0};
6101 int skip_table[MAX_CHANNEL_NUMBER +1] = {0};
6102 wifi_band band = band_invalid;
6103 char *token_channel = NULL, *token_skip = NULL;
developer75bd10c2023-06-27 11:34:08 +08006104 int res;
developere40952c2023-06-15 18:46:43 +08006105
developera3511852023-06-14 14:12:59 +08006106 if (NULL == output_pool)
6107 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08006108 // get skiplist, possible_channels list
6109 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
developerdfd270b2023-12-12 10:24:30 +08006110 band = radio_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08006111 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6112 if (os_snprintf_error(sizeof(config_file), res)) {
6113 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6114 return RETURN_ERR;
6115 }
developer326d4232023-06-15 16:45:30 +08006116 wifi_datfileRead(config_file, "AutoChannelSkipList", skip_list, sizeof(skip_list));
6117
6118 if (skip_list[0] != '\0') {
6119 int len = strlen(skip_list);
6120 for (int i = 0; i < len; i++) {
6121 if (skip_list[i] == ';') {
6122 skip_list[i] = ',';
6123 }
6124 }
6125 // skip list
6126 token_skip = strtok(skip_list, ",");
6127 while (token_skip != NULL) {
6128 int channel = atoi(token_skip);
6129 if (channel <= MAX_CHANNEL_NUMBER && strstr(possible_channels, token_skip) != NULL)
6130 skip_table[atoi(token_skip)] = CHANNEL_INVALID;
6131 token_skip = strtok(NULL, ",");
6132 }
developere40952c2023-06-15 18:46:43 +08006133 }
developer72fb0bb2023-01-11 09:46:29 +08006134
developer326d4232023-06-15 16:45:30 +08006135 int count = 0;
6136 token_channel = strtok(possible_channels, ",");
6137 while (token_channel != NULL) {
6138 int channel = atoi(token_channel);
6139 if (channel <= MAX_CHANNEL_NUMBER && skip_table[channel] == CHANNEL_AVAILABLE) {
6140 count += snprintf(&output_pool[count], CHANNEL_LIST_MAX_LENGTH-count, "%d,", channel);
6141 if (count >= CHANNEL_LIST_MAX_LENGTH-1)
6142 break;
6143 }
6144 token_channel = strtok(NULL, ",");
6145 }
6146 //delete the last one ','
6147 if (count >0 && output_pool[count-1] == ',')
6148 output_pool[count-1] = '\0';
developera3511852023-06-14 14:12:59 +08006149 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006150}
6151
6152INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
6153{
developer326d4232023-06-15 16:45:30 +08006154 char config_file_dat[128] = {0};
6155 struct params dat = {0};
6156 wifi_band band = band_invalid;
6157 char new_pool[128] = {0};
developer75bd10c2023-06-27 11:34:08 +08006158 int res;
developer326d4232023-06-15 16:45:30 +08006159
6160 if (NULL == pool)
6161 return RETURN_ERR;
6162
developer9ce44382023-06-28 11:09:37 +08006163 strncpy(new_pool, pool, sizeof(new_pool) - 1);
6164 new_pool[sizeof(new_pool) - 1] = '\0';
developer326d4232023-06-15 16:45:30 +08006165 for (int i = 0; new_pool[i] != '\0'; i++) {
6166 if (new_pool[i] == ',')
6167 new_pool[i] = ';';
6168 }
6169
6170 dat.name = "AutoChannelSkipList";
6171 dat.value = new_pool;
developerdfd270b2023-12-12 10:24:30 +08006172 band = radio_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08006173 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
6174 if (os_snprintf_error(sizeof(config_file_dat), res)) {
6175 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6176 return RETURN_ERR;
6177 }
developer326d4232023-06-15 16:45:30 +08006178 if (wifi_datfileWrite(config_file_dat, &dat, 1) != 0)
6179 return RETURN_ERR;
6180 wifi_reloadAp(radioIndex);
6181
developera3511852023-06-14 14:12:59 +08006182 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006183}
6184
6185INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
6186{
developera3511852023-06-14 14:12:59 +08006187 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
6188 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08006189 //Should refresh period time be filled in here? output_interval_seconds is INT type
6190 //wifi_getRadioAutoChannelRefreshPeriod is Ulong type
6191 *output_interval_seconds = 1800;
6192 *output_dwell_milliseconds = 200;
developer72fb0bb2023-01-11 09:46:29 +08006193
developera3511852023-06-14 14:12:59 +08006194 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006195}
6196
6197INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
6198{
developera3511852023-06-14 14:12:59 +08006199 //Set to wifi config. And apply instantly.
6200 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006201}
6202
6203INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
6204{
developera3511852023-06-14 14:12:59 +08006205 if (output_bool == NULL)
6206 return RETURN_ERR;
6207 *output_bool = true;
6208 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006209}
6210
6211INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
6212{
developera3511852023-06-14 14:12:59 +08006213 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006214}
6215
6216//Get the Dfs enable status
6217INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
6218{
developera3511852023-06-14 14:12:59 +08006219 char buf[16] = {0};
6220 char config_file_dat[128] = {0};
6221 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08006222 int res;
developer72fb0bb2023-01-11 09:46:29 +08006223
developera3511852023-06-14 14:12:59 +08006224 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006225
developera3511852023-06-14 14:12:59 +08006226 if (output_bool == NULL)
6227 return RETURN_ERR;
6228 *output_bool = TRUE; // default
developerdfd270b2023-12-12 10:24:30 +08006229 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08006230 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
6231 if (os_snprintf_error(sizeof(config_file_dat), res)) {
6232 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6233 return RETURN_ERR;
6234 }
developerd1824452023-05-18 12:30:04 +08006235
developera3511852023-06-14 14:12:59 +08006236 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08006237
developera3511852023-06-14 14:12:59 +08006238 if (strncmp(buf, "0", 1) == 0)
6239 *output_bool = FALSE;
6240 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6241 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006242}
6243
6244//Set the Dfs enable status
6245INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
6246{
developera3511852023-06-14 14:12:59 +08006247 char config_dat_file[128] = {0};
6248 FILE *f = NULL;
6249 struct params dat = {0};
6250 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08006251 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +08006252
developera3511852023-06-14 14:12:59 +08006253 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006254
developera3511852023-06-14 14:12:59 +08006255 f = fopen(DFS_ENABLE_FILE, "w");
6256 if (f == NULL)
6257 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08006258 ret = fprintf(f, "%d", enable);
6259 if (ret < 0)
6260 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developerd14dff12023-06-28 22:47:44 +08006261 if (fclose(f) != 0) {
6262 wifi_debug(DEBUG_ERROR, "fclose fail\n");
6263 return RETURN_ERR;
6264 }
developer72fb0bb2023-01-11 09:46:29 +08006265
developera3511852023-06-14 14:12:59 +08006266 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08006267
developera3511852023-06-14 14:12:59 +08006268 dat.name = "DfsEnable";
6269 dat.value = enable?"1":"0";
developerdfd270b2023-12-12 10:24:30 +08006270 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08006271 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6272 if (os_snprintf_error(sizeof(config_dat_file), res)) {
6273 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6274 return RETURN_ERR;
6275 }
6276
developera3511852023-06-14 14:12:59 +08006277 wifi_datfileWrite(config_dat_file, &dat, 1);
6278 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6279 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006280}
6281
6282//Check if the driver support the AutoChannelRefreshPeriod
6283INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
6284{
developera3511852023-06-14 14:12:59 +08006285 if (NULL == output_bool)
6286 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08006287 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08006288
developera3511852023-06-14 14:12:59 +08006289 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006290}
6291
developer326d4232023-06-15 16:45:30 +08006292
6293int get_ACS_RefreshPeriod_callback(struct nl_msg *msg, void *arg)
6294{
6295 ULONG *data = (ULONG *)arg;
6296 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6297 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
6298 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6299 int err = 0;
6300
6301 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6302 genlmsg_attrlen(gnlh, 0), NULL);
6303 if (err < 0)
6304 return NL_SKIP;
6305
6306 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6307 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
6308 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6309 if (err < 0)
6310 return NL_SKIP;
6311
6312 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]) {
6313 *data = nla_get_u32(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]);
6314 }
6315 }
6316
6317 return NL_OK;
6318}
6319
developer72fb0bb2023-01-11 09:46:29 +08006320//Get the ACS refresh period in seconds
6321INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
6322{
developer326d4232023-06-15 16:45:30 +08006323 char interface_name[IF_NAME_SIZE] = {0};
6324 int ret = -1;
6325 unsigned int if_idx = 0;
6326 struct unl unl_ins;
6327 struct nl_msg *msg = NULL;
6328 struct nlattr * msg_data = NULL;
6329 struct mtk_nl80211_param param;
6330 unsigned long checktime = 0;
developerc3556192023-12-06 17:59:09 +08006331 int main_vap_idx;
developer326d4232023-06-15 16:45:30 +08006332
6333 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08006334 if (NULL == output_ulong)
6335 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08006336
developerc3556192023-12-06 17:59:09 +08006337 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
6338 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
6339 return RETURN_ERR;
6340 }
6341
6342 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developer326d4232023-06-15 16:45:30 +08006343 return RETURN_ERR;
6344
6345 if_idx = if_nametoindex(interface_name);
6346 if (!if_idx) {
6347 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
6348 return RETURN_ERR;
6349 }
6350 /*init mtk nl80211 vendor cmd*/
6351 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
6352 param.if_type = NL80211_ATTR_IFINDEX;
6353 param.if_idx = if_idx;
developer72fb0bb2023-01-11 09:46:29 +08006354
developer326d4232023-06-15 16:45:30 +08006355 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6356 if (ret) {
6357 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6358 return RETURN_ERR;
6359 }
6360
6361 /*add mtk vendor cmd data*/
6362 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD, 0)) {
6363 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD attribute error\n");
6364 nlmsg_free(msg);
6365 goto err;
6366 }
6367
6368 /*send mtk nl80211 vendor msg*/
6369 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ACS_RefreshPeriod_callback, &checktime);
6370
6371 if (ret) {
6372 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6373 goto err;
6374 }
6375 /*deinit mtk nl80211 vendor msg*/
6376 mtk_nl80211_deint(&unl_ins);
6377 *output_ulong = checktime;
6378 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
6379
6380 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08006381 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08006382err:
6383 mtk_nl80211_deint(&unl_ins);
6384 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6385 return RETURN_ERR;
6386
developer72fb0bb2023-01-11 09:46:29 +08006387}
6388
6389//Set the ACS refresh period in seconds
6390INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
6391{
developer326d4232023-06-15 16:45:30 +08006392 char interface_name[IF_NAME_SIZE] = {0};
6393 int ret = -1;
6394 unsigned int if_idx = 0;
6395 struct unl unl_ins;
6396 struct nl_msg *msg = NULL;
6397 struct nlattr * msg_data = NULL;
6398 struct mtk_nl80211_param param;
developerc3556192023-12-06 17:59:09 +08006399 int main_vap_idx;
developer326d4232023-06-15 16:45:30 +08006400
6401 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6402
developerc3556192023-12-06 17:59:09 +08006403 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
6404 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
developer326d4232023-06-15 16:45:30 +08006405 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +08006406 }
6407
6408 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developer326d4232023-06-15 16:45:30 +08006409 return RETURN_ERR;
6410
6411 if_idx = if_nametoindex(interface_name);
6412 if (!if_idx) {
6413 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
6414 return RETURN_ERR;
6415 }
6416 /*init mtk nl80211 vendor cmd*/
6417 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
6418 param.if_type = NL80211_ATTR_IFINDEX;
6419 param.if_idx = if_idx;
6420
6421 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6422 if (ret) {
6423 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6424 return RETURN_ERR;
6425 }
6426
6427 /*add mtk vendor cmd data*/
6428 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
6429 wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME attribute error\n");
6430 nlmsg_free(msg);
6431 goto err;
6432 }
6433
6434 /*send mtk nl80211 vendor msg*/
6435 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6436
6437 if (ret) {
6438 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6439 goto err;
6440 }
6441 /*deinit mtk nl80211 vendor msg*/
6442 mtk_nl80211_deint(&unl_ins);
6443 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
6444
6445 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6446 return RETURN_OK;
6447err:
6448 mtk_nl80211_deint(&unl_ins);
6449 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developera3511852023-06-14 14:12:59 +08006450 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006451}
6452
developer408cde72023-10-19 13:44:02 +08006453int get_bandwidth_handler(struct nl_msg *msg, void *data)
6454{
6455 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6456 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX + 1];
6457 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6458 unsigned char *bw = (unsigned char *)data;
6459 int err = 0;
6460
6461 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6462 genlmsg_attrlen(gnlh, 0), NULL);
6463 if (err < 0)
6464 return err;
6465
6466 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6467 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX,
6468 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6469 if (err < 0)
6470 return err;
6471
6472 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_BANDWIDTH]) {
6473 *bw = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_BANDWIDTH]);
6474 }
6475 }
6476
6477 return 0;
6478}
6479
developer408cde72023-10-19 13:44:02 +08006480int bwidx_to_string(unsigned char bw, char *buf)
6481{
6482 int res;
6483 switch (bw) {
6484 case BAND_WIDTH_20:
6485 res = snprintf(buf, 32, "%s", "20");
6486 if (os_snprintf_error(64, res)) {
6487 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6488 return -1;
6489 }
6490 break;
6491 case BAND_WIDTH_40:
6492 res = snprintf(buf, 32, "%s", "40");
6493 if (os_snprintf_error(64, res)) {
6494 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6495 return -1;
6496 }
6497 break;
6498 case BAND_WIDTH_80:
6499 res = snprintf(buf, 32, "%s", "80");
6500 if (os_snprintf_error(64, res)) {
6501 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6502 return -1;
6503 }
6504 break;
6505 case BAND_WIDTH_160:
6506 res = snprintf(buf, 32, "%s", "160");
6507 if (os_snprintf_error(64, res)) {
6508 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6509 return -1;
6510 }
6511 break;
6512 case BAND_WIDTH_8080:
6513 res = snprintf(buf, 32, "%s", "80+80");
6514 if (os_snprintf_error(64, res)) {
6515 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6516 return -1;
6517 }
6518 break;
6519 case BAND_WIDTH_320:
6520 res = snprintf(buf, 32, "%s", "320");
6521 if (os_snprintf_error(64, res)) {
6522 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6523 return -1;
6524 }
6525 break;
6526 default:
6527 wifi_debug(DEBUG_ERROR, "unkown bw[%d]\n", bw);
6528 return -1;
6529 }
6530
6531 return 0;
6532}
developerb57e9a82023-11-22 18:29:55 +08006533
6534/*Calculate radio bw from ht_bw, vht_bw and eht bw*/
6535UCHAR calculate_radio_bw(UCHAR ht_bw, UCHAR vht_bw, UCHAR eht_bw) {
6536 UCHAR bw = BAND_WIDTH_20;
6537
6538 if (ht_bw == HT_BW_20)
6539 return bw;
6540
6541 if (ht_bw == HT_BW_40) {
6542 if (vht_bw == VHT_BW_2040)
6543 bw = BAND_WIDTH_40;
6544 else if (vht_bw == VHT_BW_80)
6545 bw = BAND_WIDTH_80;
6546 else if (vht_bw == VHT_BW_160) {
6547 if (eht_bw == EHT_BW_320)
6548 bw = BAND_WIDTH_320;
6549 else
6550 bw = BAND_WIDTH_160;
6551 } else if (vht_bw == VHT_BW_8080)
6552 bw = BAND_WIDTH_8080;
6553 }
6554
6555 return bw;
6556}
6557//Get the Configured Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
6558//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.
6559INT wifi_getRadioConfiguredChannelBandwidth(INT radioIndex, CHAR *output_string)
6560{
6561 char config_file[128] = {0};
6562 wifi_band band = band_invalid;
6563 char ht_bw_str[16] = {0};
6564 char vht_bw_str[16] = {0};
6565 char eht_bw_str[16] = {0};
6566 UCHAR ht_bw;
6567 UCHAR vht_bw;
6568 UCHAR eht_bw;
6569 UCHAR bw;
6570 char buf[32] = {0};
6571 int res;
6572 int ret;
6573
6574 if (output_string == NULL) {
6575 wifi_debug(DEBUG_ERROR, "output_string is NULL\n");
6576 return RETURN_ERR;
6577 }
6578
developerdfd270b2023-12-12 10:24:30 +08006579 band = radio_index_to_band(radioIndex);
developerb57e9a82023-11-22 18:29:55 +08006580 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6581 if (os_snprintf_error(sizeof(config_file), res)) {
6582 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6583 return RETURN_ERR;
6584 }
6585
6586 /*parse HT_BW*/
6587 wifi_datfileRead(config_file, "HT_BW", ht_bw_str, sizeof(ht_bw_str));
6588 if (strncmp(ht_bw_str, "1", 1) == 0)
6589 ht_bw = HT_BW_40;
6590 else
6591 ht_bw = HT_BW_20;
6592
6593 /*parse VHT_BW*/
6594 wifi_datfileRead(config_file, "VHT_BW", vht_bw_str, sizeof(vht_bw_str));
6595 if (strncmp(vht_bw_str, "0", 1) == 0)
6596 vht_bw = VHT_BW_2040;
6597 else if (strncmp(vht_bw_str, "1", 1) == 0)
6598 vht_bw = VHT_BW_80;
6599 else if (strncmp(vht_bw_str, "2", 1) == 0)
6600 vht_bw = VHT_BW_160;
6601 else if (strncmp(vht_bw_str, "3", 1) == 0)
6602 vht_bw = VHT_BW_8080;
6603 else
6604 vht_bw = VHT_BW_2040;
6605
6606 /*parse EHT_BW*/
6607 wifi_datfileRead(config_file, "EHT_ApBw", eht_bw_str, sizeof(eht_bw_str));
6608 if (strncmp(eht_bw_str, "0", 1) == 0)
6609 eht_bw = EHT_BW_20;
6610 else if (strncmp(eht_bw_str, "1", 1) == 0)
6611 eht_bw = EHT_BW_40;
6612 else if (strncmp(eht_bw_str, "2", 1) == 0)
6613 eht_bw = EHT_BW_80;
6614 else if (strncmp(eht_bw_str, "3", 1) == 0)
6615 eht_bw = EHT_BW_160;
6616 else if (strncmp(eht_bw_str, "4", 1) == 0)
6617 eht_bw = EHT_BW_320;
6618 else
6619 eht_bw = EHT_BW_20;
6620
6621 bw = calculate_radio_bw(ht_bw, vht_bw, eht_bw);
6622 ret = bwidx_to_string(bw, buf);
6623 if (ret) {
6624 wifi_debug(DEBUG_ERROR, "bwidx_to_string fails\n");
6625 return RETURN_ERR;
6626 }
6627
6628 res = snprintf(output_string, 64, "%sMHz", buf);
6629 if (os_snprintf_error(64, res)) {
6630 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6631 return RETURN_ERR;
6632 }
6633
6634 return RETURN_OK;
6635}
developer408cde72023-10-19 13:44:02 +08006636
developer72fb0bb2023-01-11 09:46:29 +08006637//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
6638//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.
6639INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
6640{
developer408cde72023-10-19 13:44:02 +08006641 char buf[32] = {0};
developer9e772fb2023-12-04 13:33:42 +08006642 int ret = 0, res, len = 0;
developera3511852023-06-14 14:12:59 +08006643 BOOL radio_enable = FALSE;
developer9e772fb2023-12-04 13:33:42 +08006644 //unsigned char bw;
6645 char interface_name[64] = {0};
developer166ae622023-12-21 15:27:09 +08006646 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08006647
developera3511852023-06-14 14:12:59 +08006648 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006649
developera3511852023-06-14 14:12:59 +08006650 if (NULL == output_string) {
6651 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
6652 return RETURN_ERR;
6653 }
6654 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
6655 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
6656 return RETURN_ERR;
6657 }
6658 if (radio_enable != TRUE) {
6659 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
6660 return RETURN_OK;
6661 }
developer9e772fb2023-12-04 13:33:42 +08006662
developer166ae622023-12-21 15:27:09 +08006663 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
6664 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
6665 return RETURN_ERR;
6666 }
6667
6668 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developere40952c2023-06-15 18:46:43 +08006669 return RETURN_ERR;
developer9e772fb2023-12-04 13:33:42 +08006670
6671 ret = _syscmd_secure(buf, sizeof(buf), "iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
6672 if(ret) {
6673 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08006674 }
developer8078acf2023-08-04 18:52:48 +08006675
developer9e772fb2023-12-04 13:33:42 +08006676 len = strlen(buf);
6677 if ((ret != 0) || (len == 0)) {
6678 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +08006679 return RETURN_ERR;
6680 }
developer8666b312023-03-24 14:05:31 +08006681
developere40952c2023-06-15 18:46:43 +08006682 res = snprintf(output_string, 64, "%sMHz", buf);
6683 if (os_snprintf_error(64, res)) {
6684 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6685 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08006686 }
developera3511852023-06-14 14:12:59 +08006687 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006688
developera3511852023-06-14 14:12:59 +08006689 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08006690}
6691
developer72fb0bb2023-01-11 09:46:29 +08006692//Set the Operating Channel Bandwidth.
6693INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
6694{
developera3511852023-06-14 14:12:59 +08006695 char config_file[128];
6696 char ht_value[16];
6697 char vht_value[16];
6698 char eht_value[16];
6699 struct params dat[3];
6700 wifi_band band = band_invalid;
6701 unsigned int bw = 20;
developere40952c2023-06-15 18:46:43 +08006702 int ret = 0, res1, res2, res3;
developer72fb0bb2023-01-11 09:46:29 +08006703
developera3511852023-06-14 14:12:59 +08006704 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006705
developera3511852023-06-14 14:12:59 +08006706 if(NULL == bandwidth)
6707 return RETURN_ERR;
developerdfd270b2023-12-12 10:24:30 +08006708 band = radio_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006709
developera3511852023-06-14 14:12:59 +08006710 if(strstr(bandwidth,"320") != NULL) {
developere40952c2023-06-15 18:46:43 +08006711 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
6712 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
6713 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developera3511852023-06-14 14:12:59 +08006714 bw = 320;
6715 } else if(strstr(bandwidth,"160") != NULL) {
developere40952c2023-06-15 18:46:43 +08006716 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
6717 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
6718 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developera3511852023-06-14 14:12:59 +08006719 bw = 160;
6720 } else if(strstr(bandwidth,"80") != NULL) {
developere40952c2023-06-15 18:46:43 +08006721 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
6722 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
6723 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developera3511852023-06-14 14:12:59 +08006724 bw = 80;
6725 } else if(strstr(bandwidth,"40") != NULL) {
developere40952c2023-06-15 18:46:43 +08006726 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
6727 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
6728 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developera3511852023-06-14 14:12:59 +08006729 bw = 40;
6730 } else if(strstr(bandwidth,"20") != NULL) {
developere40952c2023-06-15 18:46:43 +08006731 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
6732 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
6733 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developera3511852023-06-14 14:12:59 +08006734 bw = 20;
6735 } else {
developer37646972023-06-29 10:58:43 +08006736 if (fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth) < 0)
6737 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08006738 return RETURN_ERR;
6739 }
developer72fb0bb2023-01-11 09:46:29 +08006740
developer37646972023-06-29 10:58:43 +08006741 if (os_snprintf_error(sizeof(ht_value), res1) ||
6742 os_snprintf_error(sizeof(vht_value), res2) ||
6743 os_snprintf_error(sizeof(eht_value), res3)) {
developere40952c2023-06-15 18:46:43 +08006744 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6745 return RETURN_ERR;
6746 }
6747
6748 res1 = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6749 if (os_snprintf_error(sizeof(config_file), res1)) {
6750 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6751 return RETURN_ERR;
6752 }
developera3511852023-06-14 14:12:59 +08006753 dat[0].name = "HT_BW";
6754 dat[0].value = ht_value;
6755 dat[1].name = "VHT_BW";
6756 dat[1].value = vht_value;
6757 dat[2].name = "EHT_ApBw";
6758 dat[2].value = eht_value;
6759 wifi_datfileWrite(config_file, dat, 3);
developereef7d562023-10-21 16:04:21 +08006760
6761 /*do bw quick setting*/
6762 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw, NULL, NULL);
developerfead3972023-05-25 20:15:02 +08006763 if (ret != RETURN_OK) {
developereef7d562023-10-21 16:04:21 +08006764 wifi_debug(DEBUG_ERROR, "bw quick setting fail\n");
developer37646972023-06-29 10:58:43 +08006765 if (fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__) < 0)
6766 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08006767 }
developer72fb0bb2023-01-11 09:46:29 +08006768
developera3511852023-06-14 14:12:59 +08006769 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6770 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006771}
6772
developer72fb0bb2023-01-11 09:46:29 +08006773//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
6774//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.
6775INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
6776{
developera3511852023-06-14 14:12:59 +08006777 char buf[64] = {0};
6778 char cmd[MAX_CMD_SIZE] = {0};
6779 char interface_name[64] = {0};
developer96d86a02023-12-22 10:42:01 +08006780 int ret = 0, len = 0;
developera3511852023-06-14 14:12:59 +08006781 ULONG channel = 0;
6782 int centr_channel = 0;
developer96d86a02023-12-22 10:42:01 +08006783 int freq = 0, res;
developerc3556192023-12-06 17:59:09 +08006784 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08006785
developera3511852023-06-14 14:12:59 +08006786 if (output_string == NULL)
6787 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006788
developer96d86a02023-12-22 10:42:01 +08006789 /*default output_string is "Auto"*/
6790 res = snprintf(output_string, 64, "Auto");
6791 if (os_snprintf_error(64, res)) {
6792 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +08006793 return RETURN_ERR;
developer96d86a02023-12-22 10:42:01 +08006794 }
developerc3556192023-12-06 17:59:09 +08006795
6796 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
6797 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
developera3511852023-06-14 14:12:59 +08006798 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +08006799 }
developer72fb0bb2023-01-11 09:46:29 +08006800
developerc3556192023-12-06 17:59:09 +08006801 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
6802 return RETURN_ERR;
6803
developer96d86a02023-12-22 10:42:01 +08006804 /*get primary ch*/
6805 wifi_getRadioChannel(radioIndex, &channel);
6806 if (channel == 0) {
6807 wifi_debug(DEBUG_ERROR, "RadioChannel is 0, return\n");
developere40952c2023-06-15 18:46:43 +08006808 return RETURN_ERR;
6809 }
6810
developer96d86a02023-12-22 10:42:01 +08006811 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
6812 if (os_snprintf_error(sizeof(cmd), res)) {
developere40952c2023-06-15 18:46:43 +08006813 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6814 return RETURN_ERR;
6815 }
developer72fb0bb2023-01-11 09:46:29 +08006816
developer96d86a02023-12-22 10:42:01 +08006817 /*get center ch freq*/
6818 ret = _syscmd_secure(buf, sizeof(buf), "iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
6819 if(ret)
6820 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
6821 len = strlen(buf);
6822 if((ret != 0) || (len == 0))
6823 {
6824 wifi_debug(DEBUG_ERROR, "failed with Command %s %s:%d\n", cmd, __func__, __LINE__);
6825 return RETURN_ERR;
6826 }
developerd1824452023-05-18 12:30:04 +08006827
developer96d86a02023-12-22 10:42:01 +08006828 sscanf(buf, "%d", &freq);
6829 centr_channel = ieee80211_frequency_to_channel(freq);
developer8078acf2023-08-04 18:52:48 +08006830
developer96d86a02023-12-22 10:42:01 +08006831 /*compare centr_channel and primary ch*/
6832 if (centr_channel > (int)channel)
6833 res = snprintf(output_string, 64, "AboveControlChannel");
6834 else
6835 res = snprintf(output_string, 64, "BelowControlChannel");
developere40952c2023-06-15 18:46:43 +08006836
developer96d86a02023-12-22 10:42:01 +08006837 if (os_snprintf_error(64, res)) {
6838 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6839 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08006840 }
developer72fb0bb2023-01-11 09:46:29 +08006841
developera3511852023-06-14 14:12:59 +08006842 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006843}
6844
6845//Set the extension channel.
6846INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08006847{
developera3511852023-06-14 14:12:59 +08006848 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6849 struct params params={0};
6850 char config_file[64] = {0};
6851 char config_dat_file[64] = {0};
6852 char ext_channel[64] = {0};
developereef7d562023-10-21 16:04:21 +08006853 unsigned char ext_ch;
developera3511852023-06-14 14:12:59 +08006854 char buf[128] = {0};
developer630fa042023-12-22 15:01:43 +08006855 int ret = 0;
developerc14d83a2023-06-29 20:09:42 +08006856 long int bandwidth = 0;
developera3511852023-06-14 14:12:59 +08006857 unsigned long channel = 0;
developera3511852023-06-14 14:12:59 +08006858 params.name = "ht_capab";
6859 wifi_band band;
developera47dfe22023-12-21 16:02:31 +08006860 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08006861
developera47dfe22023-12-21 16:02:31 +08006862 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
6863 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
6864 return RETURN_ERR;
6865 }
6866 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer75bd10c2023-06-27 11:34:08 +08006867 if (os_snprintf_error(sizeof(config_file), res)) {
6868 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6869 return RETURN_ERR;
6870 }
6871
developera3511852023-06-14 14:12:59 +08006872 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
6873 return RETURN_ERR;
developerc14d83a2023-06-29 20:09:42 +08006874 if (hal_strtol(buf, 10, &bandwidth) < 0) {
6875 wifi_debug(DEBUG_ERROR, "strtol fail\n");
6876 }
developera3511852023-06-14 14:12:59 +08006877 // TDK expected to get error with 20MHz
6878 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
6879 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
6880 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006881
developerdfd270b2023-12-12 10:24:30 +08006882 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08006883 if (band == band_invalid)
6884 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006885
developera3511852023-06-14 14:12:59 +08006886 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
6887 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006888
developerc14d83a2023-06-29 20:09:42 +08006889 res = snprintf(buf, sizeof(buf), "HT%ld", bandwidth);
developere40952c2023-06-15 18:46:43 +08006890 if (os_snprintf_error(sizeof(buf), res)) {
6891 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6892 return RETURN_ERR;
6893 }
developera3511852023-06-14 14:12:59 +08006894 ret = util_get_sec_chan_offset(channel, buf);
6895 if (ret == -EINVAL)
6896 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006897
developera3511852023-06-14 14:12:59 +08006898 if(NULL!= strstr(string,"Above")) {
6899 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
6900 return RETURN_OK;
developerb14b3462023-07-01 18:02:42 +08006901 memcpy(ext_channel, "1", strlen("1"));
developereef7d562023-10-21 16:04:21 +08006902 ext_ch = 1;
developera3511852023-06-14 14:12:59 +08006903 } else if(NULL!= strstr(string,"Below")) {
6904 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
6905 return RETURN_OK;
developerb14b3462023-07-01 18:02:42 +08006906 memcpy(ext_channel, "0", strlen("0"));
developereef7d562023-10-21 16:04:21 +08006907 ext_ch = 0;
developera3511852023-06-14 14:12:59 +08006908 } else {
6909 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developereef7d562023-10-21 16:04:21 +08006910 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08006911 }
6912 params.name = "HT_EXTCHA";
6913 params.value = ext_channel;
developer72fb0bb2023-01-11 09:46:29 +08006914
developere75ba632023-06-29 16:03:33 +08006915 res = snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08006916 if (os_snprintf_error(sizeof(config_dat_file), res)) {
6917 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6918 return RETURN_ERR;
6919 }
developera3511852023-06-14 14:12:59 +08006920 wifi_datfileWrite(config_dat_file, &params, 1);
developerd1824452023-05-18 12:30:04 +08006921
developereef7d562023-10-21 16:04:21 +08006922 /*do ext_ch quicking setting*/
6923 if (ext_ch != -1) {
6924 ret = wifi_setChannel_netlink(radioIndex, NULL, NULL, &ext_ch, NULL);
6925 if (ret != RETURN_OK)
6926 wifi_debug(DEBUG_ERROR, "ext_ch quicking setting fail\n");
6927 }
6928
developera3511852023-06-14 14:12:59 +08006929 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6930 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006931}
6932
6933//Get the guard interval value. eg "400nsec" or "800nsec"
6934//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.
6935INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
6936{
developera3511852023-06-14 14:12:59 +08006937 wifi_guard_interval_t GI;
developer32f2a182023-06-27 19:50:41 +08006938 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08006939
developera3511852023-06-14 14:12:59 +08006940 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006941
developera3511852023-06-14 14:12:59 +08006942 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
6943 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006944
developer32f2a182023-06-27 19:50:41 +08006945 if (GI == wifi_guard_interval_400) {
6946 len = strlen("400nsec");
6947 memcpy(output_string, "400nsec", len);
developer5b23cd02023-07-19 20:26:03 +08006948 } else if (GI == wifi_guard_interval_800) {
developer32f2a182023-06-27 19:50:41 +08006949 len = strlen("800nsec");
6950 memcpy(output_string, "800nsec", strlen("800nsec"));
6951 } else if (GI == wifi_guard_interval_1600) {
6952 len = strlen("1600nsec");
6953 memcpy(output_string, "1600nsec", strlen("1600nsec"));
6954 } else if (GI == wifi_guard_interval_3200) {
6955 len = strlen("3200nsec");
6956 memcpy(output_string, "3200nsec", strlen("3200nsec"));
6957 } else {
6958 len = strlen("Auto");
6959 memcpy(output_string, "Auto", strlen("Auto"));
6960 }
6961 output_string[len] = '\0';
developera3511852023-06-14 14:12:59 +08006962 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6963 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006964}
6965
6966//Set the guard interval value.
6967INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
6968{
developera3511852023-06-14 14:12:59 +08006969 wifi_guard_interval_t GI;
6970 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08006971
developera3511852023-06-14 14:12:59 +08006972 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006973
developera3511852023-06-14 14:12:59 +08006974 if (strcmp(string, "400nsec") == 0)
6975 GI = wifi_guard_interval_400;
6976 else if (strcmp(string , "800nsec") == 0)
6977 GI = wifi_guard_interval_800;
6978 else if (strcmp(string , "1600nsec") == 0)
6979 GI = wifi_guard_interval_1600;
6980 else if (strcmp(string , "3200nsec") == 0)
6981 GI = wifi_guard_interval_3200;
6982 else
6983 GI = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +08006984
developera3511852023-06-14 14:12:59 +08006985 ret = wifi_setGuardInterval(radioIndex, GI);
developer72fb0bb2023-01-11 09:46:29 +08006986
developera3511852023-06-14 14:12:59 +08006987 if (ret == RETURN_ERR) {
6988 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
6989 return RETURN_ERR;
6990 }
developer72fb0bb2023-01-11 09:46:29 +08006991
developera3511852023-06-14 14:12:59 +08006992 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6993 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006994}
6995
6996//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
6997INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
6998{
developera3511852023-06-14 14:12:59 +08006999 char buf[32]={0};
7000 char mcs_file[64] = {0};
developer8078acf2023-08-04 18:52:48 +08007001
developera3511852023-06-14 14:12:59 +08007002 UINT mode_bitmap = 0;
developere40952c2023-06-15 18:46:43 +08007003 int res;
developerc14d83a2023-06-29 20:09:42 +08007004 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08007005
developera3511852023-06-14 14:12:59 +08007006 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7007 if(output_int == NULL)
7008 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08007009 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
7010 if (os_snprintf_error(sizeof(mcs_file), res)) {
7011 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7012 return RETURN_ERR;
7013 }
7014
developer8078acf2023-08-04 18:52:48 +08007015 res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null", mcs_file);
7016 if (res) {
7017 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08007018 }
developer72fb0bb2023-01-11 09:46:29 +08007019
developerd14dff12023-06-28 22:47:44 +08007020 if (strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +08007021 if (hal_strtol(buf, 10, &tmp) < 0) {
7022 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08007023 }
developerc14d83a2023-06-29 20:09:42 +08007024 *output_int = tmp;
developerd14dff12023-06-28 22:47:44 +08007025 } else {
developera3511852023-06-14 14:12:59 +08007026 // output the max MCS for the current radio mode
7027 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
7028 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
7029 return RETURN_ERR;
7030 }
7031 if (mode_bitmap & WIFI_MODE_AX) {
7032 *output_int = 11;
7033 } else if (mode_bitmap & WIFI_MODE_AC) {
7034 *output_int = 9;
7035 } else if (mode_bitmap & WIFI_MODE_N) {
7036 *output_int = 7;
7037 }
7038 }
7039 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007040
developera3511852023-06-14 14:12:59 +08007041 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007042}
7043
7044//Set the Modulation Coding Scheme index
7045INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
7046{
developera3511852023-06-14 14:12:59 +08007047 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
7048 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
7049 char config_file[64] = {0};
7050 char set_value[16] = {0};
7051 char mcs_file[32] = {0};
7052 struct params set_config = {0};
7053 FILE *f = NULL;
7054 INT nss = 0;
7055 int ant_bitmap = 0;
7056 unsigned short cal_value = 0;
7057 UCHAR tval = 0, i = 0;
developera47dfe22023-12-21 16:02:31 +08007058 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007059
developera3511852023-06-14 14:12:59 +08007060 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera47dfe22023-12-21 16:02:31 +08007061 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7062 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7063 return RETURN_ERR;
7064 }
7065 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developere40952c2023-06-15 18:46:43 +08007066 if (os_snprintf_error(sizeof(config_file), res)) {
7067 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7068 return RETURN_ERR;
7069 }
developer72fb0bb2023-01-11 09:46:29 +08007070
developera3511852023-06-14 14:12:59 +08007071 // -1 means auto
7072 if (MCS > 15 || MCS < -1) {
developer75bd10c2023-06-27 11:34:08 +08007073 wifi_debug(DEBUG_ERROR, "invalid MCS %d\n", MCS);
developera3511852023-06-14 14:12:59 +08007074 return RETURN_ERR;
7075 }
7076 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
7077 for(; ant_bitmap > 0; ant_bitmap >>= 1)
7078 nss += 1;
7079 //printf("%s:nss = %d\n", __func__, nss);
7080 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
7081 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
7082 if (MCS > 9 || MCS == -1)
7083 tval = 2;/*one stream value*/
7084 else if (MCS > 7)
7085 tval = 1;
7086 else
7087 tval = 0;
7088 for (i = 0; i < nss; i++)
7089 cal_value |= (tval << (2*i));
developere40952c2023-06-15 18:46:43 +08007090 res = snprintf(set_value, sizeof(set_value), "%x", cal_value);
7091 if (os_snprintf_error(sizeof(set_value), res)) {
7092 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7093 return RETURN_ERR;
7094 }
7095
developera3511852023-06-14 14:12:59 +08007096 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
7097 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
7098 set_config.value = set_value;
developer72fb0bb2023-01-11 09:46:29 +08007099
developera3511852023-06-14 14:12:59 +08007100 wifi_hostapdWrite(config_file, &set_config, 1);
7101 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
developer72fb0bb2023-01-11 09:46:29 +08007102
developera3511852023-06-14 14:12:59 +08007103 // 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 +08007104 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
7105 if (os_snprintf_error(sizeof(mcs_file), res)) {
7106 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7107 return RETURN_ERR;
7108 }
7109
developera3511852023-06-14 14:12:59 +08007110 f = fopen(mcs_file, "w");
7111 if (f == NULL) {
developere75ba632023-06-29 16:03:33 +08007112 if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
7113 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08007114 return RETURN_ERR;
7115 }
developere75ba632023-06-29 16:03:33 +08007116 if (fprintf(f, "%d", MCS) < 0)
7117 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
7118 if (fclose(f) == EOF) {
7119 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
7120 return RETURN_ERR;
7121 }
developer72fb0bb2023-01-11 09:46:29 +08007122
developera3511852023-06-14 14:12:59 +08007123 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7124 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007125}
7126
7127//Get supported Transmit Power list, eg : "0,25,50,75,100"
7128//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.
7129INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
7130{
developere40952c2023-06-15 18:46:43 +08007131 int res;
7132 if (NULL == output_list)
7133 return RETURN_ERR;
7134 res = snprintf(output_list, 64,"0,25,50,75,100");
7135 if (os_snprintf_error(64, res)) {
7136 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7137 return RETURN_ERR;
7138 }
7139
7140 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007141}
7142
7143//Get current Transmit Power in dBm units.
7144//The transmite power level is in units of full power for this radio.
7145INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
7146{
developera3511852023-06-14 14:12:59 +08007147 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +08007148 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08007149 char pwr_file[128]={0};
developere40952c2023-06-15 18:46:43 +08007150 int res;
developerc3556192023-12-06 17:59:09 +08007151 int main_vap_idx;
developera1255e42023-05-13 17:45:02 +08007152
developera3511852023-06-14 14:12:59 +08007153 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007154
developera3511852023-06-14 14:12:59 +08007155 if(output_ulong == NULL)
7156 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007157
developerc3556192023-12-06 17:59:09 +08007158 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7159 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7160 return RETURN_ERR;
7161 }
7162
7163 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08007164 return RETURN_ERR;
developer179a1522023-11-14 13:52:36 +08007165 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radio_index_to_band(radioIndex));
developere40952c2023-06-15 18:46:43 +08007166 if (os_snprintf_error(sizeof(pwr_file), res)) {
7167 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7168 return RETURN_ERR;
7169 }
7170
developer8078acf2023-08-04 18:52:48 +08007171 res = _syscmd_secure(buf, sizeof(buf),"cat %s 2> /dev/null", pwr_file);
7172 if(res) {
7173 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08007174 }
7175
developer5b23cd02023-07-19 20:26:03 +08007176 if (strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +08007177 if (hal_strtoul(buf, 10, output_ulong) < 0) {
7178 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08007179 }
7180 } else
developera1255e42023-05-13 17:45:02 +08007181 *output_ulong = 100;
developera3511852023-06-14 14:12:59 +08007182 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7183 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007184}
7185
7186//Set Transmit Power
7187//The transmite power level is in units of full power for this radio.
7188INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
7189{
developera3511852023-06-14 14:12:59 +08007190 char interface_name[16] = {0};
7191 char *support;
7192 char buf[128]={0};
7193 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08007194 char pwr_file[128]={0};
developera3511852023-06-14 14:12:59 +08007195 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08007196 int if_idx, ret = 0;
7197 struct nl_msg *msg = NULL;
7198 struct nlattr * msg_data = NULL;
7199 struct mtk_nl80211_param param;
7200 struct unl unl_ins;
developere40952c2023-06-15 18:46:43 +08007201 int res;
developerc3556192023-12-06 17:59:09 +08007202 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007203
developera3511852023-06-14 14:12:59 +08007204 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007205
developerc3556192023-12-06 17:59:09 +08007206 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7207 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7208 return RETURN_ERR;
7209 }
7210
7211 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08007212 return RETURN_ERR;
7213 // Get the Tx power supported list and check that is the input in the list
developere40952c2023-06-15 18:46:43 +08007214 res = snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
7215 if (os_snprintf_error(sizeof(txpower_str), res)) {
7216 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7217 return RETURN_ERR;
7218 }
developera3511852023-06-14 14:12:59 +08007219 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
7220 support = strtok(buf, ",");
7221 while(true)
7222 {
7223 if(support == NULL) { // input not in the list
7224 wifi_dbg_printf("Input value is invalid.\n");
7225 return RETURN_ERR;
7226 }
7227 if (strncmp(txpower_str, support, strlen(support)) == 0) {
7228 break;
7229 }
7230 support = strtok(NULL, ",");
7231 }
developerfead3972023-05-25 20:15:02 +08007232
7233 if_idx = if_nametoindex(interface_name);
7234 /*init mtk nl80211 vendor cmd*/
7235 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
7236 param.if_type = NL80211_ATTR_IFINDEX;
7237 param.if_idx = if_idx;
7238 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7239 if (ret) {
7240 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7241 return RETURN_ERR;
7242 }
7243 /*add mtk vendor cmd data*/
7244 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
7245 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7246 nlmsg_free(msg);
7247 goto err;
7248 }
7249
7250 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
7251 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7252 nlmsg_free(msg);
7253 goto err;
7254 }
7255
7256 /*send mtk nl80211 vendor msg*/
7257 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7258 if (ret) {
7259 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7260 goto err;
7261 }
7262 /*deinit mtk nl80211 vendor msg*/
7263 mtk_nl80211_deint(&unl_ins);
7264 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
7265
developer179a1522023-11-14 13:52:36 +08007266 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radio_index_to_band(radioIndex));
developere40952c2023-06-15 18:46:43 +08007267 if (os_snprintf_error(sizeof(pwr_file), res)) {
7268 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7269 return RETURN_ERR;
7270 }
7271
developera3511852023-06-14 14:12:59 +08007272 f = fopen(pwr_file, "w");
7273 if (f == NULL) {
developerc14d83a2023-06-29 20:09:42 +08007274 wifi_debug(DEBUG_ERROR, "%s: fopen failed\n", __func__);
developera3511852023-06-14 14:12:59 +08007275 return RETURN_ERR;
7276 }
7277 fprintf(f, "%lu", TransmitPower);
developerc14d83a2023-06-29 20:09:42 +08007278 if (fclose(f) == EOF)
7279 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera1255e42023-05-13 17:45:02 +08007280 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08007281err:
7282 mtk_nl80211_deint(&unl_ins);
7283 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7284 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007285}
7286
7287//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
7288INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
7289{
developera3511852023-06-14 14:12:59 +08007290 if (NULL == Supported)
7291 return RETURN_ERR;
7292 *Supported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08007293
developera3511852023-06-14 14:12:59 +08007294 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007295}
7296
7297//Get 80211h feature enable
7298INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
7299{
developera3511852023-06-14 14:12:59 +08007300 char buf[64]={'\0'};
developer3d899672023-11-15 15:57:01 +08007301 char config_dat_file[64] = {'\0'};
developer75bd10c2023-06-27 11:34:08 +08007302 int res;
developer72fb0bb2023-01-11 09:46:29 +08007303
developera3511852023-06-14 14:12:59 +08007304 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7305 if(enable == NULL)
7306 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007307
developer3d899672023-11-15 15:57:01 +08007308 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7309 if (os_snprintf_error(sizeof(config_dat_file), res)) {
developer75bd10c2023-06-27 11:34:08 +08007310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7311 return RETURN_ERR;
7312 }
developera3511852023-06-14 14:12:59 +08007313 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
developer3d899672023-11-15 15:57:01 +08007314 wifi_datfileRead(config_dat_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007315
developera3511852023-06-14 14:12:59 +08007316 if (strncmp(buf, "1", 1) == 0)
7317 *enable = TRUE;
7318 else
7319 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08007320
developera3511852023-06-14 14:12:59 +08007321 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7322 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007323}
7324
7325//Set 80211h feature enable
7326INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
7327{
developera3511852023-06-14 14:12:59 +08007328 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7329 struct params params={'\0'};
7330 struct params dat={0};
developera3511852023-06-14 14:12:59 +08007331 char config_dat_file[MAX_BUF_SIZE] = {0};
7332 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007333 int res;
developereef7d562023-10-21 16:04:21 +08007334 int ret = -1;
7335 unsigned char en_80211h;
developer72fb0bb2023-01-11 09:46:29 +08007336
developera3511852023-06-14 14:12:59 +08007337 if (enable) {
7338 params.value = "1";
developereef7d562023-10-21 16:04:21 +08007339 en_80211h = 1;
developera3511852023-06-14 14:12:59 +08007340 } else {
7341 params.value = "0";
developereef7d562023-10-21 16:04:21 +08007342 en_80211h = 0;
developera3511852023-06-14 14:12:59 +08007343 }
developer72fb0bb2023-01-11 09:46:29 +08007344
developera3511852023-06-14 14:12:59 +08007345 dat.name = "IEEE80211H";
7346 dat.value = params.value;
developerd1824452023-05-18 12:30:04 +08007347
developerdfd270b2023-12-12 10:24:30 +08007348 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08007349
7350 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7351 if (os_snprintf_error(sizeof(config_dat_file), res)) {
7352 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7353 return RETURN_ERR;
7354 }
developer69b61b02023-03-07 17:17:44 +08007355
developera3511852023-06-14 14:12:59 +08007356 wifi_datfileWrite(config_dat_file, &dat, 1);
developereef7d562023-10-21 16:04:21 +08007357
7358 /*do IEEE80211h quick setting*/
7359 ret = wifi_set80211h_netlink(radioIndex, en_80211h);
7360 if (ret != RETURN_OK)
7361 wifi_debug(DEBUG_ERROR, "IEEE80211h quick setting fail\n");
7362
developera3511852023-06-14 14:12:59 +08007363 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7364 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007365}
7366
7367//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.
7368INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
7369{
developera3511852023-06-14 14:12:59 +08007370 if (NULL == output)
7371 return RETURN_ERR;
7372 *output=100;
developer72fb0bb2023-01-11 09:46:29 +08007373
developera3511852023-06-14 14:12:59 +08007374 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007375}
7376
7377//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.
7378INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
7379{
developera3511852023-06-14 14:12:59 +08007380 if (NULL == output)
7381 return RETURN_ERR;
7382 *output = -99;
developer72fb0bb2023-01-11 09:46:29 +08007383
developera3511852023-06-14 14:12:59 +08007384 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007385}
7386
7387INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
7388{
developera3511852023-06-14 14:12:59 +08007389 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007390}
7391
7392
7393//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
7394INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
7395{
developera3511852023-06-14 14:12:59 +08007396 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +08007397 char buf[MAX_CMD_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08007398 int res;
developerc3556192023-12-06 17:59:09 +08007399 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007400
developera3511852023-06-14 14:12:59 +08007401 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7402 if(output == NULL)
7403 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007404
developerc3556192023-12-06 17:59:09 +08007405 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7406 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
developera3511852023-06-14 14:12:59 +08007407 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +08007408 }
7409
7410 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08007411 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +08007412
7413 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
7414 if(res) {
7415 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08007416 }
7417
developera3511852023-06-14 14:12:59 +08007418 *output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08007419
developera3511852023-06-14 14:12:59 +08007420 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7421 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007422}
developer69b61b02023-03-07 17:17:44 +08007423
developer72fb0bb2023-01-11 09:46:29 +08007424INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
7425{
developera3511852023-06-14 14:12:59 +08007426 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7427 struct params params={'\0'};
7428 char buf[MAX_BUF_SIZE] = {'\0'};
7429 char config_file[MAX_BUF_SIZE] = {'\0'};
developera47dfe22023-12-21 16:02:31 +08007430 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007431
developera3511852023-06-14 14:12:59 +08007432 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
7433 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007434
developera3511852023-06-14 14:12:59 +08007435 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08007436 res = snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
7437 if (os_snprintf_error(sizeof(buf), res)) {
7438 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7439 return RETURN_ERR;
7440 }
7441
developera3511852023-06-14 14:12:59 +08007442 params.value = buf;
developera47dfe22023-12-21 16:02:31 +08007443 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7444 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7445 return RETURN_ERR;
7446 }
7447 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer75bd10c2023-06-27 11:34:08 +08007448 if (os_snprintf_error(sizeof(config_file), res)) {
7449 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7450 return RETURN_ERR;
7451 }
developera3511852023-06-14 14:12:59 +08007452 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08007453
developera3511852023-06-14 14:12:59 +08007454 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
7455 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7456 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007457}
7458
7459//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.
7460INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
7461{
developera3511852023-06-14 14:12:59 +08007462 //TODO: need to revisit below implementation
7463 char *temp;
7464 char temp_output[128] = {0};
7465 char temp_TransmitRates[64] = {0};
7466 char config_file[64] = {0};
developera47dfe22023-12-21 16:02:31 +08007467 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007468
developera3511852023-06-14 14:12:59 +08007469 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7470 if (NULL == output)
7471 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08007472
developera47dfe22023-12-21 16:02:31 +08007473 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7474 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7475 return RETURN_ERR;
7476 }
7477 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developer75bd10c2023-06-27 11:34:08 +08007478 if (os_snprintf_error(sizeof(config_file), res)) {
7479 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7480 return RETURN_ERR;
7481 }
developera3511852023-06-14 14:12:59 +08007482 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08007483
developera3511852023-06-14 14:12:59 +08007484 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
7485 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
7486 } else {
7487 temp = strtok(temp_TransmitRates," ");
7488 while(temp!=NULL)
7489 {
7490 // Convert 100 kbps to Mbps
7491 temp[strlen(temp)-1]=0;
7492 if((temp[0]=='5') && (temp[1]=='\0'))
7493 {
7494 temp="5.5";
7495 }
developer32f2a182023-06-27 19:50:41 +08007496 if (strlen(temp) >= sizeof(temp_output))
7497 return RETURN_ERR;
7498 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08007499 temp = strtok(NULL," ");
7500 if(temp!=NULL)
7501 {
developer32f2a182023-06-27 19:50:41 +08007502 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
7503 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08007504 }
7505 }
developer32f2a182023-06-27 19:50:41 +08007506 memcpy(output, temp_output, strlen(temp_output));
7507 output[strlen(temp_output)] = '\0';
developera3511852023-06-14 14:12:59 +08007508 }
7509 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7510 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007511}
7512
7513INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
7514{
developera3511852023-06-14 14:12:59 +08007515 char *temp;
developer32f2a182023-06-27 19:50:41 +08007516 char temp1[128] = {0};
7517 char temp_output[128] = {0};
7518 char temp_TransmitRates[128] = {0};
7519 char set[128] = {0};
7520 char sub_set[128] = {0};
developera3511852023-06-14 14:12:59 +08007521 int set_count=0,subset_count=0;
7522 int set_index=0,subset_index=0;
7523 char *token;
7524 int flag=0, i=0;
7525 struct params params={'\0'};
7526 char config_file[MAX_BUF_SIZE] = {0};
developerdfd270b2023-12-12 10:24:30 +08007527 wifi_band band = radio_index_to_band(radioIndex);
developera47dfe22023-12-21 16:02:31 +08007528 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007529
developera3511852023-06-14 14:12:59 +08007530 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer9f2358c2023-09-22 18:42:12 +08007531
developera3511852023-06-14 14:12:59 +08007532 if(NULL == TransmitRates)
7533 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +08007534 if (strlen(TransmitRates) >= sizeof(sub_set))
7535 return RETURN_ERR;
7536
7537 memcpy(sub_set, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08007538
developera3511852023-06-14 14:12:59 +08007539 //Allow only supported Data transmit rate to be set
7540 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
7541 token = strtok(sub_set,",");
7542 while( token != NULL ) /* split the basic rate to be set, by comma */
7543 {
7544 sub_set[subset_count]=atoi(token);
7545 subset_count++;
7546 token=strtok(NULL,",");
7547 }
7548 token=strtok(set,",");
7549 while(token!=NULL) /* split the supported rate by comma */
7550 {
7551 set[set_count]=atoi(token);
7552 set_count++;
7553 token=strtok(NULL,",");
7554 }
7555 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
7556 {
7557 for(set_index=0;set_index < set_count;set_index++)
7558 {
7559 flag=0;
7560 if(sub_set[subset_index]==set[set_index])
7561 break;
7562 else
7563 flag=1; /* No match found */
7564 }
7565 if(flag==1)
7566 return RETURN_ERR; //If value not found return Error
7567 }
developer5b23cd02023-07-19 20:26:03 +08007568
developer32f2a182023-06-27 19:50:41 +08007569 if (strlen(TransmitRates) >= sizeof(temp_TransmitRates))
7570 return RETURN_ERR;
7571
7572 memcpy(temp_TransmitRates, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08007573
developera3511852023-06-14 14:12:59 +08007574 for(i=0;i<strlen(temp_TransmitRates);i++)
7575 {
7576 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
7577 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
7578 {
7579 continue;
7580 }
7581 else
7582 {
7583 return RETURN_ERR;
7584 }
7585 }
developera3511852023-06-14 14:12:59 +08007586 temp = strtok(temp_TransmitRates,",");
7587 while(temp!=NULL)
7588 {
developer32f2a182023-06-27 19:50:41 +08007589 if (strlen(temp) >= sizeof(temp1))
7590 return RETURN_ERR;
7591 strncpy(temp1, temp, strlen(temp));
developera3511852023-06-14 14:12:59 +08007592 if(band == band_5)
7593 {
7594 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
7595 {
7596 return RETURN_ERR;
7597 }
7598 }
developer72fb0bb2023-01-11 09:46:29 +08007599
developera3511852023-06-14 14:12:59 +08007600 if(strcmp(temp,"5.5")==0)
7601 {
developer32f2a182023-06-27 19:50:41 +08007602 memcpy(temp1, "55", 2);
developera3511852023-06-14 14:12:59 +08007603 }
7604 else
7605 {
developer32f2a182023-06-27 19:50:41 +08007606 if (strlen(temp1) >= (sizeof(temp1) - 1))
7607 return RETURN_ERR;
7608 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +08007609 }
developer32f2a182023-06-27 19:50:41 +08007610 if (strlen(temp1) >= (sizeof(temp_output) - strlen(temp_output)))
7611 return RETURN_ERR;
7612 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08007613 temp = strtok(NULL,",");
7614 if(temp!=NULL)
7615 {
developer32f2a182023-06-27 19:50:41 +08007616 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
7617 return RETURN_ERR;
7618 strncat(temp_output," ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08007619 }
7620 }
developer32f2a182023-06-27 19:50:41 +08007621 memcpy(TransmitRates, temp_output, strlen(temp_output));
7622 TransmitRates[strlen(temp_output)] = '\0';
developer5b23cd02023-07-19 20:26:03 +08007623
developera3511852023-06-14 14:12:59 +08007624 params.name= "basic_rates";
7625 params.value =TransmitRates;
developer72fb0bb2023-01-11 09:46:29 +08007626
developera3511852023-06-14 14:12:59 +08007627 wifi_dbg_printf("\n%s:",__func__);
7628 wifi_dbg_printf("\nparams.value=%s\n",params.value);
7629 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
developera47dfe22023-12-21 16:02:31 +08007630 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7631 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7632 return RETURN_ERR;
7633 }
7634 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,main_vap_idx);
developer32f2a182023-06-27 19:50:41 +08007635 if (os_snprintf_error(sizeof(config_file), res)) {
7636 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7637 return RETURN_ERR;
7638 }
developer5b23cd02023-07-19 20:26:03 +08007639
developera3511852023-06-14 14:12:59 +08007640 wifi_hostapdWrite(config_file,&params,1);
developer9f2358c2023-09-22 18:42:12 +08007641 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
7642 wifi_quick_reload_ap(radioIndex);
developer9f2358c2023-09-22 18:42:12 +08007643
developera3511852023-06-14 14:12:59 +08007644 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7645 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007646}
7647
developer72fb0bb2023-01-11 09:46:29 +08007648INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
7649{
developera3511852023-06-14 14:12:59 +08007650 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
7651 output_struct->radio_BytesSent = 0;
7652 output_struct->radio_BytesReceived = 0;
7653 output_struct->radio_PacketsSent = 0;
7654 output_struct->radio_PacketsReceived = 0;
7655 output_struct->radio_ErrorsSent = 0;
7656 output_struct->radio_ErrorsReceived = 0;
7657 output_struct->radio_DiscardPacketsSent = 0;
7658 output_struct->radio_DiscardPacketsReceived = 0;
7659 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
7660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007661}
7662
7663
7664INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
7665{
developera3511852023-06-14 14:12:59 +08007666 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer8078acf2023-08-04 18:52:48 +08007667
developera3511852023-06-14 14:12:59 +08007668 CHAR Value[MAX_BUF_SIZE] = {0};
7669 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08007670 int res;
developer37646972023-06-29 10:58:43 +08007671 unsigned long ret;
developer72fb0bb2023-01-11 09:46:29 +08007672
developera3511852023-06-14 14:12:59 +08007673 if (ifname == NULL || strlen(ifname) <= 1)
7674 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007675
developer33f13ba2023-07-12 16:19:06 +08007676 res = v_secure_system("ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
7677 if (res) {
7678 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developere40952c2023-06-15 18:46:43 +08007679 return RETURN_ERR;
7680 }
7681
developera3511852023-06-14 14:12:59 +08007682 fp = fopen("/tmp/Radio_Stats.txt", "r");
7683 if(fp == NULL)
7684 {
7685 printf("/tmp/Radio_Stats.txt not exists \n");
7686 return RETURN_ERR;
7687 }
developerd14dff12023-06-28 22:47:44 +08007688 if (fclose(fp) != 0) {
7689 wifi_debug(DEBUG_ERROR, "fclose fail\n");
7690 return RETURN_ERR;
7691 }
developer72fb0bb2023-01-11 09:46:29 +08007692
developer8078acf2023-08-04 18:52:48 +08007693 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
7694 if(res) {
7695 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +08007696 }
developer5b23cd02023-07-19 20:26:03 +08007697
developerc14d83a2023-06-29 20:09:42 +08007698 if (hal_strtoul(Value, 10, &ret) < 0) {
developer37646972023-06-29 10:58:43 +08007699 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developer37646972023-06-29 10:58:43 +08007700 }
developerc14d83a2023-06-29 20:09:42 +08007701
developer37646972023-06-29 10:58:43 +08007702 pStats->radio_PacketsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08007703
developer8078acf2023-08-04 18:52:48 +08007704 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
7705 if(res) {
7706 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007707 }
developer5b23cd02023-07-19 20:26:03 +08007708
developerc14d83a2023-06-29 20:09:42 +08007709 if (hal_strtoul(Value, 10, &ret) < 0) {
7710 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007711 }
developer5b23cd02023-07-19 20:26:03 +08007712
developer37646972023-06-29 10:58:43 +08007713 pStats->radio_PacketsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08007714
developer8078acf2023-08-04 18:52:48 +08007715 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
7716 if(res) {
7717 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007718 }
developer8078acf2023-08-04 18:52:48 +08007719
developerc14d83a2023-06-29 20:09:42 +08007720 if (hal_strtoul(Value, 10, &ret) < 0) {
7721 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007722 }
7723 pStats->radio_BytesReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08007724
developer8078acf2023-08-04 18:52:48 +08007725 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
7726 if(res) {
7727 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007728 }
developer8078acf2023-08-04 18:52:48 +08007729
developerc14d83a2023-06-29 20:09:42 +08007730 if (hal_strtoul(Value, 10, &ret) < 0) {
7731 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007732 }
7733 pStats->radio_BytesSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08007734
developer8078acf2023-08-04 18:52:48 +08007735 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
7736 if(res) {
7737 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007738 }
developer8078acf2023-08-04 18:52:48 +08007739
developerc14d83a2023-06-29 20:09:42 +08007740 if (hal_strtoul(Value, 10, &ret) < 0) {
7741 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007742 }
7743 pStats->radio_ErrorsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08007744
developer8078acf2023-08-04 18:52:48 +08007745 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
7746 if(res) {
7747 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007748 }
developer8078acf2023-08-04 18:52:48 +08007749
developerc14d83a2023-06-29 20:09:42 +08007750 if (hal_strtoul(Value, 10, &ret) < 0) {
7751 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007752 }
7753 pStats->radio_ErrorsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08007754
developer8078acf2023-08-04 18:52:48 +08007755 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
7756 if(res) {
7757 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007758 }
developer8078acf2023-08-04 18:52:48 +08007759
developerc14d83a2023-06-29 20:09:42 +08007760 if (hal_strtoul(Value, 10, &ret) < 0) {
7761 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007762 }
7763 pStats->radio_DiscardPacketsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08007764
developer8078acf2023-08-04 18:52:48 +08007765 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
7766 if(res) {
7767 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer86035662023-06-28 19:21:12 +08007768 }
developer8078acf2023-08-04 18:52:48 +08007769
developerc14d83a2023-06-29 20:09:42 +08007770 if (hal_strtoul(Value, 10, &ret) < 0) {
7771 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08007772 }
7773 pStats->radio_DiscardPacketsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08007774
developera3511852023-06-14 14:12:59 +08007775 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
7776 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007777}
7778
7779INT GetIfacestatus(CHAR *interface_name, CHAR *status)
7780{
developer75bd10c2023-06-27 11:34:08 +08007781 int res;
developer72fb0bb2023-01-11 09:46:29 +08007782
developer7e4a2a62023-04-06 19:56:03 +08007783 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
7784
7785 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
developer8078acf2023-08-04 18:52:48 +08007786
developerd08b7d52023-08-22 15:41:36 +08007787 res = _syscmd_secure(status, sizeof(status), "ifconfig -a %s | grep %s | wc -l",
7788 interface_name, interface_name);
7789 if(res) {
7790 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
7791 }
developer75bd10c2023-06-27 11:34:08 +08007792
developer7e4a2a62023-04-06 19:56:03 +08007793 }
7794
7795 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
7796 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007797}
7798
7799//Get detail radio traffic static info
7800INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
7801{
developera3511852023-06-14 14:12:59 +08007802 CHAR interface_name[64] = {0};
7803 BOOL iface_status = FALSE;
7804 wifi_radioTrafficStats2_t radioTrafficStats = {0};
developerc3556192023-12-06 17:59:09 +08007805 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08007806
developera3511852023-06-14 14:12:59 +08007807 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
7808 if (NULL == output_struct)
7809 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007810
developerc3556192023-12-06 17:59:09 +08007811 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7812 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7813 return RETURN_ERR;
7814 }
developer72fb0bb2023-01-11 09:46:29 +08007815
developerc3556192023-12-06 17:59:09 +08007816 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08007817 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007818
developerc3556192023-12-06 17:59:09 +08007819 wifi_getApEnable(main_vap_idx, &iface_status);
developer72fb0bb2023-01-11 09:46:29 +08007820
developera3511852023-06-14 14:12:59 +08007821 if (iface_status == TRUE)
7822 wifi_halGetIfStats(interface_name, &radioTrafficStats);
7823 else
7824 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
developer72fb0bb2023-01-11 09:46:29 +08007825
developera3511852023-06-14 14:12:59 +08007826 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
7827 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
7828 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
7829 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
7830 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
7831 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
7832 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
7833 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +08007834
developera3511852023-06-14 14:12:59 +08007835 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
7836 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].
7837 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
7838 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.
7839 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
7840 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
7841 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
7842 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
7843 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 +08007844
developera3511852023-06-14 14:12:59 +08007845 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
7846 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
7847 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
7848 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 +08007849
developera3511852023-06-14 14:12:59 +08007850 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007851
developera3511852023-06-14 14:12:59 +08007852 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007853}
7854
7855//Set radio traffic static Measureing rules
7856INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
7857{
developera39cfb22023-06-20 16:28:17 +08007858 char inf_name[IF_NAME_SIZE] = {0};
7859 unsigned int if_idx = 0;
7860 int ret = -1;
7861 struct unl unl_ins;
7862 struct nl_msg *msg = NULL;
7863 struct nlattr * msg_data = NULL;
7864 struct mtk_nl80211_param param;
developerc3556192023-12-06 17:59:09 +08007865 int main_vap_idx;
developera39cfb22023-06-20 16:28:17 +08007866
developerc3556192023-12-06 17:59:09 +08007867 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7868 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7869 return RETURN_ERR;
7870 }
developera39cfb22023-06-20 16:28:17 +08007871
developerc3556192023-12-06 17:59:09 +08007872 if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
developera39cfb22023-06-20 16:28:17 +08007873 return RETURN_ERR;
7874 if_idx = if_nametoindex(inf_name);
7875 if (!if_idx) {
7876 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
7877 return RETURN_ERR;
7878 }
7879 /*init mtk nl80211 vendor cmd*/
7880 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
7881 param.if_type = NL80211_ATTR_IFINDEX;
7882 param.if_idx = if_idx;
7883
7884 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7885 if (ret) {
7886 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7887 return RETURN_ERR;
7888 }
7889 /*add mtk vendor cmd data*/
7890 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD,
7891 sizeof(wifi_radioTrafficStatsMeasure_t), input_struct)) {
7892 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
7893 MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD);
7894 nlmsg_free(msg);
7895 goto err;
7896 }
7897
7898 /*send mtk nl80211 vendor msg*/
7899 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7900 if (ret) {
7901 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7902 goto err;
7903 }
7904 /*deinit mtk nl80211 vendor msg*/
7905 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08007906 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08007907err:
7908 mtk_nl80211_deint(&unl_ins);
7909 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
7910 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007911}
7912
7913//To start or stop RadioTrafficStats
7914INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
7915{
developera39cfb22023-06-20 16:28:17 +08007916 char inf_name[IF_NAME_SIZE] = {0};
7917 unsigned int if_idx = 0;
7918 int ret = -1;
7919 struct unl unl_ins;
7920 struct nl_msg *msg = NULL;
7921 struct nlattr * msg_data = NULL;
7922 struct mtk_nl80211_param param;
developerc3556192023-12-06 17:59:09 +08007923 int main_vap_idx;
developera39cfb22023-06-20 16:28:17 +08007924
developerc3556192023-12-06 17:59:09 +08007925 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
7926 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
7927 return RETURN_ERR;
7928 }
7929
7930 if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
developera39cfb22023-06-20 16:28:17 +08007931 return RETURN_ERR;
7932 if_idx = if_nametoindex(inf_name);
7933 if (!if_idx) {
7934 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
7935 return RETURN_ERR;
7936 }
7937 /*init mtk nl80211 vendor cmd*/
7938 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
7939 param.if_type = NL80211_ATTR_IFINDEX;
7940 param.if_idx = if_idx;
7941
7942 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7943 if (ret) {
7944 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7945 return RETURN_ERR;
7946 }
7947 /*add mtk vendor cmd data*/
7948 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL, enable)) {
7949 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
7950 MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL);
7951 nlmsg_free(msg);
7952 goto err;
7953 }
7954
7955 /*send mtk nl80211 vendor msg*/
7956 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7957 if (ret) {
7958 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7959 goto err;
7960 }
7961 /*deinit mtk nl80211 vendor msg*/
7962 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08007963 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08007964err:
7965 mtk_nl80211_deint(&unl_ins);
7966 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
7967 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007968}
7969
7970//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
7971INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
7972{
developera3511852023-06-14 14:12:59 +08007973 if (NULL == SignalLevel)
7974 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08007975
developer9ce44382023-06-28 11:09:37 +08007976 *SignalLevel = -19;
developer72fb0bb2023-01-11 09:46:29 +08007977
developera3511852023-06-14 14:12:59 +08007978 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007979}
7980
7981//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
7982INT wifi_applyRadioSettings(INT radioIndex)
7983{
developera3511852023-06-14 14:12:59 +08007984 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007985}
7986
7987//Get the radio index assocated with this SSID entry
7988INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
7989{
developerc3556192023-12-06 17:59:09 +08007990 int bss_idx;
7991
developera3511852023-06-14 14:12:59 +08007992 if(NULL == radioIndex)
7993 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +08007994
7995 if (vap_index_to_radio_array_index(ssidIndex, radioIndex, &bss_idx) != RETURN_OK) {
7996 wifi_debug(DEBUG_ERROR, "invalid ssidIndex[%d]\n", ssidIndex);
developer9ce44382023-06-28 11:09:37 +08007997 return RETURN_ERR;
7998 }
developerc3556192023-12-06 17:59:09 +08007999
developera3511852023-06-14 14:12:59 +08008000 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008001}
8002
8003//Device.WiFi.SSID.{i}.Enable
8004//Get SSID enable configuration parameters (not the SSID enable status)
8005INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
8006{
developera3511852023-06-14 14:12:59 +08008007 if (NULL == output_bool)
8008 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008009
developera3511852023-06-14 14:12:59 +08008010 return wifi_getApEnable(ssidIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08008011}
8012
8013//Device.WiFi.SSID.{i}.Enable
8014//Set SSID enable configuration parameters
8015INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
8016{
developera3511852023-06-14 14:12:59 +08008017 return wifi_setApEnable(ssidIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08008018}
8019
8020//Device.WiFi.SSID.{i}.Status
8021//Get the SSID enable status
8022INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
8023{
developer9ce44382023-06-28 11:09:37 +08008024 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +08008025 int res;
developer72fb0bb2023-01-11 09:46:29 +08008026
developera3511852023-06-14 14:12:59 +08008027 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8028 if (NULL == output_string)
8029 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08008030
developera3511852023-06-14 14:12:59 +08008031 wifi_getApEnable(ssidIndex,&output_bool);
developere40952c2023-06-15 18:46:43 +08008032 res = snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
8033 if (os_snprintf_error(32, res)) {
8034 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8035 return RETURN_ERR;
8036 }
developer72fb0bb2023-01-11 09:46:29 +08008037
developera3511852023-06-14 14:12:59 +08008038 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8039 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008040}
8041
8042// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
8043INT wifi_getSSIDName(INT apIndex, CHAR *output)
8044{
developera3511852023-06-14 14:12:59 +08008045 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008046 int res;
developer72fb0bb2023-01-11 09:46:29 +08008047
developera3511852023-06-14 14:12:59 +08008048 if (NULL == output)
8049 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008050
developer75bd10c2023-06-27 11:34:08 +08008051 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8052 if (os_snprintf_error(sizeof(config_file), res)) {
8053 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8054 return RETURN_ERR;
8055 }
developera19a38f2023-11-27 19:30:48 +08008056 wifi_hostapdRead(config_file,"ssid",output, MAX_SSID_NAME_LEN);
developer72fb0bb2023-01-11 09:46:29 +08008057
developera3511852023-06-14 14:12:59 +08008058 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
8059 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008060}
8061
developer69b61b02023-03-07 17:17:44 +08008062// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08008063INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
8064{
developera3511852023-06-14 14:12:59 +08008065 struct params params;
8066 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008067 int res;
developer72fb0bb2023-01-11 09:46:29 +08008068
developera3511852023-06-14 14:12:59 +08008069 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera19a38f2023-11-27 19:30:48 +08008070 if(NULL == ssid_string || strlen(ssid_string) > 32 || strlen(ssid_string) == 0 )
developera3511852023-06-14 14:12:59 +08008071 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008072
developera3511852023-06-14 14:12:59 +08008073 params.name = "ssid";
8074 params.value = ssid_string;
developer75bd10c2023-06-27 11:34:08 +08008075
8076 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8077 if (os_snprintf_error(sizeof(config_file), res)) {
8078 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8079 return RETURN_ERR;
8080 }
8081
developera3511852023-06-14 14:12:59 +08008082 wifi_hostapdWrite(config_file, &params, 1);
8083 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8084 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008085
developera3511852023-06-14 14:12:59 +08008086 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008087}
8088
8089//Get the BSSID
8090INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
8091{
developer7e4a2a62023-04-06 19:56:03 +08008092 char inf_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08008093 int res;
developer72fb0bb2023-01-11 09:46:29 +08008094
developera3511852023-06-14 14:12:59 +08008095 if (!output_string)
developerdaf24792023-06-06 11:40:04 +08008096 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008097
developer47cc27a2023-05-17 23:09:58 +08008098 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
8099 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08008100
developer5b2f10c2023-05-25 17:02:21 +08008101 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
8102 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
8103 strncpy(output_string, "\0", 1);
8104 return RETURN_ERR;
8105 }
developere40952c2023-06-15 18:46:43 +08008106
developer8078acf2023-08-04 18:52:48 +08008107 res = _syscmd_secure(output_string,64,"hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
8108 if(res) {
8109 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
8110 }
developer7e4a2a62023-04-06 19:56:03 +08008111
developer5b2f10c2023-05-25 17:02:21 +08008112 /* if hostapd does not control interface even if this interface has been brought up,
8113 * try to get its mac address by iw command.
8114 */
8115 if(strlen(output_string) == 0) {
developer8078acf2023-08-04 18:52:48 +08008116 res = _syscmd_secure(output_string, 64, "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
8117 if(res) {
8118 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08008119 }
developer5b2f10c2023-05-25 17:02:21 +08008120 }
developer72fb0bb2023-01-11 09:46:29 +08008121
developer5b2f10c2023-05-25 17:02:21 +08008122 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008123}
8124
8125//Get the MAC address associated with this Wifi SSID
8126INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
8127{
developera3511852023-06-14 14:12:59 +08008128 wifi_getBaseBSSID(ssidIndex,output_string);
8129 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008130}
8131
8132//Get the basic SSID traffic static info
8133//Apply SSID and AP (in the case of Acess Point devices) to the hardware
8134//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
8135INT wifi_applySSIDSettings(INT ssidIndex)
8136{
developera3511852023-06-14 14:12:59 +08008137 char interface_name[16] = {0};
8138 BOOL status = false;
developera3511852023-06-14 14:12:59 +08008139 char buf[MAX_CMD_SIZE] = {0};
8140 int apIndex, ret;
developerc3556192023-12-06 17:59:09 +08008141 int radioIndex = 0, bss_idx;
developere40952c2023-06-15 18:46:43 +08008142 int res;
developer72fb0bb2023-01-11 09:46:29 +08008143
developera3511852023-06-14 14:12:59 +08008144 wifi_getApEnable(ssidIndex,&status);
8145 // Do not apply when ssid index is disabled
8146 if (status == false)
8147 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008148
developera3511852023-06-14 14:12:59 +08008149 /* Doing full remove and add for ssid Index
8150 * Not all hostapd options are supported with reload
8151 * for example macaddr_acl
8152 */
8153 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
8154 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008155
developera3511852023-06-14 14:12:59 +08008156 ret = wifi_setApEnable(ssidIndex,true);
developer72fb0bb2023-01-11 09:46:29 +08008157
developera3511852023-06-14 14:12:59 +08008158 /* Workaround for hostapd issue with multiple bss definitions
8159 * when first created interface will be removed
8160 * then all vaps other vaps on same phy are removed
8161 * after calling setApEnable to false readd all enabled vaps */
developerc3556192023-12-06 17:59:09 +08008162 if (vap_index_to_radio_array_index(ssidIndex, &radioIndex, &bss_idx) != RETURN_OK) {
8163 wifi_debug(DEBUG_ERROR, "invalid ssidIndex[%d]\n", ssidIndex);
8164 return RETURN_ERR;
8165 }
8166
8167 for (bss_idx=0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
8168 if (array_index_to_vap_index(radioIndex, bss_idx, &apIndex) != RETURN_OK) {
8169 wifi_debug(DEBUG_ERROR, "invalid radioIndex[%d] bss_idx[%d]\n", radioIndex, bss_idx);
8170 continue;
8171 }
developera3511852023-06-14 14:12:59 +08008172 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8173 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008174
developer8078acf2023-08-04 18:52:48 +08008175 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
8176 if(res) {
8177 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
8178 }
developera3511852023-06-14 14:12:59 +08008179 if(*buf == '1')
8180 wifi_setApEnable(apIndex, true);
8181 }
developer72fb0bb2023-01-11 09:46:29 +08008182
developera3511852023-06-14 14:12:59 +08008183 return ret;
developer72fb0bb2023-01-11 09:46:29 +08008184}
8185
8186struct channels_noise {
developera3511852023-06-14 14:12:59 +08008187 int channel;
8188 int noise;
developer72fb0bb2023-01-11 09:46:29 +08008189};
8190
8191// Return noise array for each channel
8192int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
8193{
developera3511852023-06-14 14:12:59 +08008194 char interface_name[16] = {0};
8195 FILE *f = NULL;
8196 char cmd[128] = {0};
8197 char line[256] = {0};
developer75bd10c2023-06-27 11:34:08 +08008198 int tmp = 0, arr_index = -1, res;
developerc3556192023-12-06 17:59:09 +08008199 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08008200
developerc3556192023-12-06 17:59:09 +08008201 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
8202 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
8203 return RETURN_ERR;
8204 }
developer72fb0bb2023-01-11 09:46:29 +08008205
developerc3556192023-12-06 17:59:09 +08008206 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08008207 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08008208
8209 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
8210 if (os_snprintf_error(sizeof(cmd), res)) {
8211 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8212 return RETURN_ERR;
8213 }
developer8078acf2023-08-04 18:52:48 +08008214 f = v_secure_popen("r", "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
8215 if (f == NULL) {
8216 wifi_dbg_printf("%s: v_secure_popen %s error\n", __func__, cmd);
developera3511852023-06-14 14:12:59 +08008217 return RETURN_ERR;
8218 }
developer69b61b02023-03-07 17:17:44 +08008219
developera3511852023-06-14 14:12:59 +08008220 while(fgets(line, sizeof(line), f) != NULL) {
8221 if(arr_index < channels_num){
developer37646972023-06-29 10:58:43 +08008222 if (sscanf(line, "%d", &tmp) == EOF)
8223 continue;
developera3511852023-06-14 14:12:59 +08008224 if (tmp > 0) { // channel frequency, the first line must be frequency
8225 arr_index++;
8226 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
8227 } else { // noise
8228 channels_noise_arr[arr_index].noise = tmp;
8229 }
8230 }else{
8231 break;
8232 }
8233 }
developer8078acf2023-08-04 18:52:48 +08008234 v_secure_pclose(f);
developera3511852023-06-14 14:12:59 +08008235 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008236}
8237
8238//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
8239//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08008240INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08008241{
developera3511852023-06-14 14:12:59 +08008242 int index = -1;
8243 wifi_neighbor_ap2_t *scan_array = NULL;
8244 char cmd[256]={0};
8245 char buf[128]={0};
8246 char file_name[32] = {0};
8247 char filter_SSID[32] = {0};
8248 char line[256] = {0};
8249 char interface_name[16] = {0};
8250 char *ret = NULL;
8251 int freq=0;
8252 FILE *f = NULL;
developerc14d83a2023-06-29 20:09:42 +08008253 unsigned long channels_num = 0;
developera3511852023-06-14 14:12:59 +08008254 int vht_channel_width = 0;
8255 int get_noise_ret = RETURN_ERR;
8256 bool filter_enable = false;
8257 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
developere40952c2023-06-15 18:46:43 +08008258 int phyId = 0, res;
developerc14d83a2023-06-29 20:09:42 +08008259 unsigned long len, tmp;
developerb717e062023-11-17 14:13:19 +08008260 unsigned int DTIM_count;
developerc3556192023-12-06 17:59:09 +08008261 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08008262
developera3511852023-06-14 14:12:59 +08008263 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008264
developerc3556192023-12-06 17:59:09 +08008265 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
8266 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
8267 return RETURN_ERR;
8268 }
8269
8270 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08008271 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008272
developerc3556192023-12-06 17:59:09 +08008273 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, main_vap_idx);
developere40952c2023-06-15 18:46:43 +08008274 if (os_snprintf_error(sizeof(file_name), res)) {
8275 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8276 return RETURN_ERR;
8277 }
developer72fb0bb2023-01-11 09:46:29 +08008278
developera3511852023-06-14 14:12:59 +08008279 f = fopen(file_name, "r");
8280 if (f != NULL) {
developerd14dff12023-06-28 22:47:44 +08008281 if (fgets(buf, sizeof(file_name), f) == NULL)
8282 wifi_debug(DEBUG_ERROR, "fgets failed\n");
developera3511852023-06-14 14:12:59 +08008283 if ((strncmp(buf, "0", 1)) != 0) {
developerd14dff12023-06-28 22:47:44 +08008284 if (fgets(filter_SSID, sizeof(file_name), f) == NULL)
8285 wifi_debug(DEBUG_ERROR, "fgets failed\n");
developera3511852023-06-14 14:12:59 +08008286 if (strlen(filter_SSID) != 0)
8287 filter_enable = true;
8288 }
developerd14dff12023-06-28 22:47:44 +08008289 if (fclose(f) != 0) {
8290 wifi_debug(DEBUG_ERROR, "fclose fail\n");
8291 return RETURN_ERR;
8292 }
developera3511852023-06-14 14:12:59 +08008293 }
developer72fb0bb2023-01-11 09:46:29 +08008294
developera3511852023-06-14 14:12:59 +08008295 phyId = radio_index_to_phy(radioIndex);
developer8078acf2023-08-04 18:52:48 +08008296
8297 res = _syscmd_secure(buf, sizeof(buf), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
8298 if (res) {
8299 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08008300 }
8301
developerc14d83a2023-06-29 20:09:42 +08008302 if (hal_strtoul(buf, 10, &tmp) < 0) {
8303 wifi_debug(DEBUG_ERROR, "strtol fail\n");
8304 }
developer72fb0bb2023-01-11 09:46:29 +08008305
developerc14d83a2023-06-29 20:09:42 +08008306 channels_num = tmp;
developer32f2a182023-06-27 19:50:41 +08008307 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 +08008308 // 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 +08008309 if (os_snprintf_error(sizeof(cmd), res)) {
8310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8311 return RETURN_ERR;
8312 }
developer86035662023-06-28 19:21:12 +08008313 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developer8078acf2023-08-04 18:52:48 +08008314
8315 f = v_secure_popen("r", "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
8316 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
8317
8318 if (f == NULL) {
8319 wifi_debug(DEBUG_ERROR, "v_secure_popen error\n");
developera3511852023-06-14 14:12:59 +08008320 return RETURN_ERR;
8321 }
developer9ce44382023-06-28 11:09:37 +08008322 struct channels_noise *channels_noise_arr = NULL;
8323 if(channels_num > 0 && channels_num <= 243){
8324 channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
8325 } else{
developerb14b3462023-07-01 18:02:42 +08008326 wifi_debug(DEBUG_ERROR, "channel num = %ld!!\n", channels_num);
developer9ce44382023-06-28 11:09:37 +08008327 }
developer5b23cd02023-07-19 20:26:03 +08008328
developer9ce44382023-06-28 11:09:37 +08008329 if(channels_noise_arr != NULL){
8330 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
8331 } else{
developerb14b3462023-07-01 18:02:42 +08008332 wifi_debug(DEBUG_ERROR, "channels_noise_arr is NULL!!\n");
developer9ce44382023-06-28 11:09:37 +08008333 }
developer5b23cd02023-07-19 20:26:03 +08008334
developer69b61b02023-03-07 17:17:44 +08008335
developera3511852023-06-14 14:12:59 +08008336 ret = fgets(line, sizeof(line), f);
8337 while (ret != NULL) {
8338 if(strstr(line, "BSS") != NULL) { // new neighbor info
8339 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
8340 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
8341 // 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 +08008342
developera3511852023-06-14 14:12:59 +08008343 if (!filter_BSS) {
8344 index++;
8345 wifi_neighbor_ap2_t *tmp;
8346 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
8347 if (tmp == NULL) { // no more memory to use
8348 index--;
8349 wifi_dbg_printf("%s: realloc failed\n", __func__);
8350 break;
8351 }
8352 scan_array = tmp;
8353 }
8354 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +08008355
developera3511852023-06-14 14:12:59 +08008356 filter_BSS = false;
developer86035662023-06-28 19:21:12 +08008357 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
8358 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
8359 goto err;
8360 }
developerc79e9172023-06-06 19:48:03 +08008361 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +08008362 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +08008363 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +08008364 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +08008365 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +08008366 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
developerb717e062023-11-17 14:13:19 +08008367 } else if (strstr(line, "freq:") != NULL) {
developer86035662023-06-28 19:21:12 +08008368 if (sscanf(line," freq: %d", &freq) != 1) {
8369 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developer86035662023-06-28 19:21:12 +08008370 }
developerb717e062023-11-17 14:13:19 +08008371
developera3511852023-06-14 14:12:59 +08008372 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +08008373
developera3511852023-06-14 14:12:59 +08008374 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +08008375 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08008376 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +08008377 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08008378 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +08008379 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08008380 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
8381 }
8382 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +08008383 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08008384 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +08008385 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08008386 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +08008387 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08008388 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
8389 }
developer72fb0bb2023-01-11 09:46:29 +08008390
developera3511852023-06-14 14:12:59 +08008391 scan_array[index].ap_Noise = 0;
8392 if (get_noise_ret == RETURN_OK) {
8393 for (int i = 0; i < channels_num; i++) {
8394 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
8395 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
8396 break;
8397 }
8398 }
8399 }
8400 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +08008401 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
8402 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
8403 goto err;
8404 }
developera3511852023-06-14 14:12:59 +08008405 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +08008406 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
8407 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
8408 goto err;
8409 }
developerb717e062023-11-17 14:13:19 +08008410 } else if (strstr(line," SSID:") != NULL) {
developer86035662023-06-28 19:21:12 +08008411 if (sscanf(line," SSID: %32s", scan_array[index].ap_SSID) != 1) {
8412 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developerb14b3462023-07-01 18:02:42 +08008413 //goto err;
developer86035662023-06-28 19:21:12 +08008414 }
developera3511852023-06-14 14:12:59 +08008415 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
8416 filter_BSS = true;
8417 }
8418 } else if (strstr(line, "Supported rates") != NULL) {
8419 char SRate[80] = {0}, *tmp = NULL;
8420 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08008421 if (strlen(line) >= sizeof(SRate))
developer86035662023-06-28 19:21:12 +08008422 goto err;
developer32f2a182023-06-27 19:50:41 +08008423 strncpy(SRate, line, strlen(line));
developera3511852023-06-14 14:12:59 +08008424 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +08008425 if (tmp == NULL)
8426 goto err;
developera3511852023-06-14 14:12:59 +08008427 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +08008428 if (tmp == NULL)
8429 goto err;
developer32f2a182023-06-27 19:50:41 +08008430 if (strlen(tmp) >= sizeof(buf))
developer86035662023-06-28 19:21:12 +08008431 goto err;
developer32f2a182023-06-27 19:50:41 +08008432 strncpy(buf, tmp, strlen(tmp));
developera3511852023-06-14 14:12:59 +08008433 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +08008434
developera3511852023-06-14 14:12:59 +08008435 tmp = strtok(buf, " \n");
8436 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +08008437 if (strlen(tmp) >= (sizeof(SRate) - strlen(SRate)))
developer86035662023-06-28 19:21:12 +08008438 goto err;
developer32f2a182023-06-27 19:50:41 +08008439 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +08008440 if (SRate[strlen(SRate) - 1] == '*') {
8441 SRate[strlen(SRate) - 1] = '\0';
8442 }
developer32f2a182023-06-27 19:50:41 +08008443 if (strlen(SRate) >= (sizeof(SRate) - 1))
developer86035662023-06-28 19:21:12 +08008444 goto err;
developer32f2a182023-06-27 19:50:41 +08008445 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +08008446
developera3511852023-06-14 14:12:59 +08008447 tmp = strtok(NULL, " \n");
8448 }
8449 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +08008450 if (sizeof(scan_array[index].ap_SupportedDataTransferRates) <= strlen(SRate))
developer86035662023-06-28 19:21:12 +08008451 goto err;
developer32f2a182023-06-27 19:50:41 +08008452 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, strlen(SRate));
developera3511852023-06-14 14:12:59 +08008453 } else if (strstr(line, "DTIM") != NULL) {
developerb717e062023-11-17 14:13:19 +08008454 if (sscanf(line," TIM: DTIM Count %u DTIM Period %u", &DTIM_count, &(scan_array[index].ap_DTIMPeriod)) != 2) {
developer86035662023-06-28 19:21:12 +08008455 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developer86035662023-06-28 19:21:12 +08008456 }
developera3511852023-06-14 14:12:59 +08008457 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08008458 if (sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) <= 4)
developer86035662023-06-28 19:21:12 +08008459 goto err;
developer32f2a182023-06-27 19:50:41 +08008460 strncat(scan_array[index].ap_SupportedStandards, ",ac",
8461 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
8462 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
8463 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +08008464 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08008465 strncat(scan_array[index].ap_SupportedStandards, ",n", sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
8466 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
8467 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +08008468 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08008469 if (fgets(line, sizeof(line), f) == NULL) {
8470 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +08008471 break;
developer86035662023-06-28 19:21:12 +08008472 }
8473 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
8474 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
8475 goto err;
8476 }
developera3511852023-06-14 14:12:59 +08008477 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +08008478 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +08008479 } else {
developere40952c2023-06-15 18:46:43 +08008480 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +08008481 }
developere40952c2023-06-15 18:46:43 +08008482 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
8483 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +08008484 goto err;
developere40952c2023-06-15 18:46:43 +08008485 }
8486
developera3511852023-06-14 14:12:59 +08008487 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
8488 continue;
8489 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08008490 if (fgets(line, sizeof(line), f) == NULL) {
8491 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +08008492 break;
developer86035662023-06-28 19:21:12 +08008493 }
developerc14d83a2023-06-29 20:09:42 +08008494 if (sscanf(line," * secondary channel offset: %127s", buf) != 1) {
developer86035662023-06-28 19:21:12 +08008495 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
8496 goto err;
8497 }
developera3511852023-06-14 14:12:59 +08008498 if (!strcmp(buf, "above")) {
8499 //40Mhz +
developere40952c2023-06-15 18:46:43 +08008500 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 +08008501 }
8502 else if (!strcmp(buf, "below")) {
8503 //40Mhz -
developere40952c2023-06-15 18:46:43 +08008504 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 +08008505 } else {
8506 //20Mhz
developere40952c2023-06-15 18:46:43 +08008507 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
8508 }
8509 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
8510 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +08008511 goto err;
developera3511852023-06-14 14:12:59 +08008512 }
developere40952c2023-06-15 18:46:43 +08008513
developera3511852023-06-14 14:12:59 +08008514 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
8515 continue;
8516 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08008517 strncat(scan_array[index].ap_SupportedStandards, ",ax",
8518 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
8519 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
8520 scan_array[index].ap_OperatingStandards[2] = '\0';
developer86035662023-06-28 19:21:12 +08008521 if (fgets(line, sizeof(line), f) == NULL) {
8522 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +08008523 break;
developer86035662023-06-28 19:21:12 +08008524 }
developera3511852023-06-14 14:12:59 +08008525 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +08008526 if (strstr(line, "HE40/2.4GHz") != NULL) {
8527 len = strlen("11AXHE40PLUS");
8528 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
8529 } else {
8530 len = strlen("11AXHE20");
8531 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
8532 }
8533 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +08008534 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
8535 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +08008536 len = strlen("11AXHE80");
8537 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
8538 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developer86035662023-06-28 19:21:12 +08008539 if (fgets(line, sizeof(line), f) == NULL) {
8540 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +08008541 break;
developer86035662023-06-28 19:21:12 +08008542 }
developera3511852023-06-14 14:12:59 +08008543 } else
8544 continue;
developer32f2a182023-06-27 19:50:41 +08008545 if (strstr(line, "HE160/5GHz") != NULL) {
8546 len = strlen("11AXHE160");
8547 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
8548 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
8549 }
developera3511852023-06-14 14:12:59 +08008550 }
8551 continue;
8552 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +08008553 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
8554 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08008555 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +08008556 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
8557 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08008558 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +08008559 if (sscanf(line, " * Group cipher: %64s", scan_array[index].ap_EncryptionMode) != 1) {
8560 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
8561 goto err;
8562 }
developera3511852023-06-14 14:12:59 +08008563 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +08008564 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
8565 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +08008566 }
8567 }
developerb14b3462023-07-01 18:02:42 +08008568 ret = fgets(line, sizeof(line), f);
developera3511852023-06-14 14:12:59 +08008569 }
developer72fb0bb2023-01-11 09:46:29 +08008570
developera3511852023-06-14 14:12:59 +08008571 if (!filter_BSS) {
8572 *output_array_size = index + 1;
8573 } else {
8574 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
8575 *output_array_size = index;
8576 }
8577 *neighbor_ap_array = scan_array;
developer8078acf2023-08-04 18:52:48 +08008578 v_secure_pclose(f);
developera3511852023-06-14 14:12:59 +08008579 free(channels_noise_arr);
8580 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8581 return RETURN_OK;
developer86035662023-06-28 19:21:12 +08008582err:
developer8078acf2023-08-04 18:52:48 +08008583 v_secure_pclose(f);
developer86035662023-06-28 19:21:12 +08008584 free(channels_noise_arr);
developerc14d83a2023-06-29 20:09:42 +08008585 if (scan_array)
8586 free(scan_array);
developer86035662023-06-28 19:21:12 +08008587 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8588 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008589}
8590
8591//>> Deprecated: used for old RDKB code.
8592INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
8593{
developera3511852023-06-14 14:12:59 +08008594 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008595
developera3511852023-06-14 14:12:59 +08008596 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8597 output_struct->wifi_PLCPErrorCount = 0;
8598 output_struct->wifi_FCSErrorCount = 0;
8599 output_struct->wifi_InvalidMACCount = 0;
8600 output_struct->wifi_PacketsOtherReceived = 0;
8601 output_struct->wifi_Noise = 0;
8602 status = RETURN_OK;
8603 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8604 return status;
developer72fb0bb2023-01-11 09:46:29 +08008605}
8606
8607INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
8608{
developera3511852023-06-14 14:12:59 +08008609 char interface_name[16] = {0};
developer8078acf2023-08-04 18:52:48 +08008610
developera3511852023-06-14 14:12:59 +08008611 char buf[1280] = {0};
8612 char *pos = NULL;
developere40952c2023-06-15 18:46:43 +08008613 int res;
developer72fb0bb2023-01-11 09:46:29 +08008614
developera3511852023-06-14 14:12:59 +08008615 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8616 if (NULL == output_struct)
8617 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008618
developera3511852023-06-14 14:12:59 +08008619 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8620 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008621
developera3511852023-06-14 14:12:59 +08008622 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08008623
developer8078acf2023-08-04 18:52:48 +08008624 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s", interface_name);
8625 if (res) {
8626 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08008627 }
8628
developera3511852023-06-14 14:12:59 +08008629 pos = buf;
8630 if ((pos = strstr(pos, "RX packets:")) == NULL)
8631 return RETURN_ERR;
8632 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08008633
developera3511852023-06-14 14:12:59 +08008634 if ((pos = strstr(pos, "TX packets:")) == NULL)
8635 return RETURN_ERR;
8636 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08008637
developera3511852023-06-14 14:12:59 +08008638 if ((pos = strstr(pos, "RX bytes:")) == NULL)
8639 return RETURN_ERR;
8640 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08008641
developera3511852023-06-14 14:12:59 +08008642 if ((pos = strstr(pos, "TX bytes:")) == NULL)
8643 return RETURN_ERR;
8644 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08008645
developer8078acf2023-08-04 18:52:48 +08008646 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
8647 if (res) {
8648 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer37646972023-06-29 10:58:43 +08008649 }
developer8078acf2023-08-04 18:52:48 +08008650
developer37646972023-06-29 10:58:43 +08008651 if (sscanf(buf, "%lu", &output_struct->wifi_Associations) == EOF)
8652 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developer72fb0bb2023-01-11 09:46:29 +08008653
developera3511852023-06-14 14:12:59 +08008654 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8655 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008656}
8657
8658INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
8659{
developera3511852023-06-14 14:12:59 +08008660 char interface_name[IF_NAME_SIZE] = {0};
8661 char interface_status[MAX_BUF_SIZE] = {0};
8662 char Value[MAX_BUF_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08008663 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08008664 int res;
developerc14d83a2023-06-29 20:09:42 +08008665 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +08008666
developera3511852023-06-14 14:12:59 +08008667 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8668 if (NULL == output_struct)
8669 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008670
developera3511852023-06-14 14:12:59 +08008671 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08008672
developera3511852023-06-14 14:12:59 +08008673 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
8674 return RETURN_ERR;
8675 GetIfacestatus(interface_name, interface_status);
developer72fb0bb2023-01-11 09:46:29 +08008676
developerd08b7d52023-08-22 15:41:36 +08008677 if(0 != strncmp(interface_status, "1", 1))
developera3511852023-06-14 14:12:59 +08008678 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008679
developer33f13ba2023-07-12 16:19:06 +08008680 res = v_secure_system("ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
8681 if (res) {
8682 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developere40952c2023-06-15 18:46:43 +08008683 return RETURN_ERR;
8684 }
developer72fb0bb2023-01-11 09:46:29 +08008685
developera3511852023-06-14 14:12:59 +08008686 fp = fopen("/tmp/SSID_Stats.txt", "r");
8687 if(fp == NULL)
8688 {
8689 printf("/tmp/SSID_Stats.txt not exists \n");
8690 return RETURN_ERR;
8691 }
developer37646972023-06-29 10:58:43 +08008692 if (fclose(fp) == EOF) {
8693 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
8694 return RETURN_ERR;
8695 }
developer72fb0bb2023-01-11 09:46:29 +08008696
developer8078acf2023-08-04 18:52:48 +08008697 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
8698 if(res) {
8699 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer37646972023-06-29 10:58:43 +08008700 }
developer5b23cd02023-07-19 20:26:03 +08008701
developerc14d83a2023-06-29 20:09:42 +08008702 if (hal_strtoul(Value, 10, &tmp) < 0) {
8703 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08008704 }
developerc14d83a2023-06-29 20:09:42 +08008705 output_struct->wifi_ErrorsReceived = tmp;
developer72fb0bb2023-01-11 09:46:29 +08008706
developer8078acf2023-08-04 18:52:48 +08008707 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
8708 if(res) {
8709 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer37646972023-06-29 10:58:43 +08008710 }
developerc14d83a2023-06-29 20:09:42 +08008711
8712 if (hal_strtoul(Value, 10, &tmp) < 0) {
8713 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08008714 }
developerc14d83a2023-06-29 20:09:42 +08008715 output_struct->wifi_ErrorsSent = tmp;
developer72fb0bb2023-01-11 09:46:29 +08008716
developer8078acf2023-08-04 18:52:48 +08008717 res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
8718 if(res) {
8719 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer37646972023-06-29 10:58:43 +08008720 }
developerc14d83a2023-06-29 20:09:42 +08008721
8722 if (hal_strtoul(Value, 10, &tmp) < 0) {
8723 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08008724 }
developerc14d83a2023-06-29 20:09:42 +08008725 output_struct->wifi_DiscardedPacketsReceived = tmp;
developer72fb0bb2023-01-11 09:46:29 +08008726
developer8078acf2023-08-04 18:52:48 +08008727 res = _syscmd_secure(Value, sizeof(Value),"cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
8728 if(res) {
8729 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer37646972023-06-29 10:58:43 +08008730 }
developerc14d83a2023-06-29 20:09:42 +08008731
8732 if (hal_strtoul(Value, 10, &tmp) < 0) {
8733 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +08008734 }
developerc14d83a2023-06-29 20:09:42 +08008735 output_struct->wifi_DiscardedPacketsSent = tmp;
developer72fb0bb2023-01-11 09:46:29 +08008736
developera3511852023-06-14 14:12:59 +08008737 output_struct->wifi_UnicastPacketsSent = 0;
8738 output_struct->wifi_UnicastPacketsReceived = 0;
8739 output_struct->wifi_MulticastPacketsSent = 0;
8740 output_struct->wifi_MulticastPacketsReceived = 0;
8741 output_struct->wifi_BroadcastPacketsSent = 0;
8742 output_struct->wifi_BroadcastPacketsRecevied = 0;
8743 output_struct->wifi_UnknownPacketsReceived = 0;
developer72fb0bb2023-01-11 09:46:29 +08008744
developera3511852023-06-14 14:12:59 +08008745 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8746 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008747}
8748
8749INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
8750{
developera3511852023-06-14 14:12:59 +08008751 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008752
developera3511852023-06-14 14:12:59 +08008753 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8754 //Below values should get updated from hal
8755 output_struct->wifi_RetransCount=0;
8756 output_struct->wifi_FailedRetransCount=0;
8757 output_struct->wifi_RetryCount=0;
8758 output_struct->wifi_MultipleRetryCount=0;
8759 output_struct->wifi_ACKFailureCount=0;
8760 output_struct->wifi_AggregatedPacketCount=0;
developer72fb0bb2023-01-11 09:46:29 +08008761
developera3511852023-06-14 14:12:59 +08008762 status = RETURN_OK;
8763 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008764
developera3511852023-06-14 14:12:59 +08008765 return status;
developer72fb0bb2023-01-11 09:46:29 +08008766}
8767
8768INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
8769{
developera3511852023-06-14 14:12:59 +08008770 INT status = RETURN_ERR;
8771 UINT index;
8772 wifi_neighbor_ap_t *pt=NULL;
developer72fb0bb2023-01-11 09:46:29 +08008773
developera3511852023-06-14 14:12:59 +08008774 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8775 *output_array_size=2;
8776 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
8777 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
developer86035662023-06-28 19:21:12 +08008778 if (*neighbor_ap_array == NULL) {
8779 wifi_debug(DEBUG_ERROR, "calloc fail!\n");
8780 return RETURN_ERR;
8781 }
developera3511852023-06-14 14:12:59 +08008782 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
developer32f2a182023-06-27 19:50:41 +08008783 pt->ap_Radio[0] = '\0';
8784 pt->ap_SSID[0] = '\0';
8785 pt->ap_BSSID[0] = '\0';
8786 pt->ap_Mode[0] = '\0';
developera3511852023-06-14 14:12:59 +08008787 pt->ap_Channel=1;
8788 pt->ap_SignalStrength=0;
developer32f2a182023-06-27 19:50:41 +08008789 pt->ap_SecurityModeEnabled[0] = '\0';
8790 pt->ap_EncryptionMode[0] = '\0';
8791 pt->ap_OperatingFrequencyBand[0] = '\0';
8792 pt->ap_SupportedStandards[0] = '\0';
8793 pt->ap_OperatingStandards[0] = '\0';
8794 pt->ap_OperatingChannelBandwidth[0] = '\0';
8795 pt->ap_BasicDataTransferRates[0] = '\0';
8796 pt->ap_SupportedDataTransferRates[0] = '\0';
developera3511852023-06-14 14:12:59 +08008797 pt->ap_BeaconPeriod=1;
8798 pt->ap_Noise=0;
developera3511852023-06-14 14:12:59 +08008799 pt->ap_DTIMPeriod=1;
8800 pt->ap_ChannelUtilization = 1;
8801 }
developer72fb0bb2023-01-11 09:46:29 +08008802
developera3511852023-06-14 14:12:59 +08008803 status = RETURN_OK;
8804 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008805
developera3511852023-06-14 14:12:59 +08008806 return status;
developer72fb0bb2023-01-11 09:46:29 +08008807}
8808
8809//----------------- AP HAL -------------------------------
8810
8811//>> Deprecated: used for old RDKB code.
8812INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
8813{
developera3511852023-06-14 14:12:59 +08008814 if (NULL == output_ulong || NULL == output_struct)
8815 return RETURN_ERR;
8816 *output_ulong = 0;
8817 *output_struct = NULL;
8818 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008819}
8820
8821#ifdef HAL_NETLINK_IMPL
8822static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +08008823 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8824 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developerc14d83a2023-06-29 20:09:42 +08008825 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
8826 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
developera3511852023-06-14 14:12:59 +08008827 char mac_addr[20];
8828 static int count=0;
8829 int rate=0;
developer72fb0bb2023-01-11 09:46:29 +08008830
developera3511852023-06-14 14:12:59 +08008831 wifi_device_info_t *out = (wifi_device_info_t*)arg;
developer72fb0bb2023-01-11 09:46:29 +08008832
developera3511852023-06-14 14:12:59 +08008833 nla_parse(tb,
8834 NL80211_ATTR_MAX,
8835 genlmsg_attrdata(gnlh, 0),
8836 genlmsg_attrlen(gnlh, 0),
8837 NULL);
developer72fb0bb2023-01-11 09:46:29 +08008838
developera3511852023-06-14 14:12:59 +08008839 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +08008840 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +08008841 return NL_SKIP;
8842 }
developer72fb0bb2023-01-11 09:46:29 +08008843
8844
developera3511852023-06-14 14:12:59 +08008845 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +08008846 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +08008847 return NL_SKIP;
8848 }
developer72fb0bb2023-01-11 09:46:29 +08008849
developera3511852023-06-14 14:12:59 +08008850 //devIndex starts from 1
8851 if( ++count == out->wifi_devIndex )
8852 {
8853 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
8854 //Getting the mac addrress
8855 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
developer12fb9f62023-06-30 15:26:27 +08008856 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
8857 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
8858 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
8859 return NL_SKIP;
8860 }
developera3511852023-06-14 14:12:59 +08008861 }
developer72fb0bb2023-01-11 09:46:29 +08008862
developera3511852023-06-14 14:12:59 +08008863 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
8864 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
8865 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
8866 out->wifi_devTxRate = rate/10;
8867 }
8868 }
developer72fb0bb2023-01-11 09:46:29 +08008869
developer12fb9f62023-06-30 15:26:27 +08008870 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
8871 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
8872 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
8873 return NL_SKIP;
8874 }
developera3511852023-06-14 14:12:59 +08008875 }
developera3511852023-06-14 14:12:59 +08008876 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
8877 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
8878 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
8879 out->wifi_devRxRate = rate/10;
8880 }
8881 }
8882 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
8883 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
developer72fb0bb2023-01-11 09:46:29 +08008884
developera3511852023-06-14 14:12:59 +08008885 out->wifi_devAssociatedDeviceAuthentiationState = 1;
8886 count = 0; //starts the count for next cycle
8887 return NL_STOP;
8888 }
developer72fb0bb2023-01-11 09:46:29 +08008889
developera3511852023-06-14 14:12:59 +08008890 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08008891
8892}
8893#endif
8894
8895INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
8896{
developera3511852023-06-14 14:12:59 +08008897 Netlink nl = {0};
8898 char if_name[IF_NAME_SIZE] = {0};
8899 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08008900 int res;
developer72fb0bb2023-01-11 09:46:29 +08008901
developera3511852023-06-14 14:12:59 +08008902 wifi_device_info_t info = {0};
8903 info.wifi_devIndex = devIndex;
developer72fb0bb2023-01-11 09:46:29 +08008904
developera3511852023-06-14 14:12:59 +08008905 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8906 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008907
developere40952c2023-06-15 18:46:43 +08008908 res = snprintf(if_name,sizeof(if_name),"%s", interface_name);
8909 if (os_snprintf_error(sizeof(if_name), res)) {
8910 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8911 return RETURN_ERR;
8912 }
developer72fb0bb2023-01-11 09:46:29 +08008913
developera3511852023-06-14 14:12:59 +08008914 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +08008915
developera3511852023-06-14 14:12:59 +08008916 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +08008917 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +08008918 return -1;
8919 }
developer72fb0bb2023-01-11 09:46:29 +08008920
developera3511852023-06-14 14:12:59 +08008921 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +08008922
developera3511852023-06-14 14:12:59 +08008923 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +08008924 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +08008925 nlfree(&nl);
8926 return -2;
8927 }
developer72fb0bb2023-01-11 09:46:29 +08008928
developera3511852023-06-14 14:12:59 +08008929 genlmsg_put(msg,
8930 NL_AUTO_PID,
8931 NL_AUTO_SEQ,
8932 nl.id,
8933 0,
8934 NLM_F_DUMP,
8935 NL80211_CMD_GET_STATION,
8936 0);
developer72fb0bb2023-01-11 09:46:29 +08008937
developera3511852023-06-14 14:12:59 +08008938 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
8939 nl_send_auto_complete(nl.socket, msg);
8940 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
8941 nl_recvmsgs(nl.socket, nl.cb);
8942 nlmsg_free(msg);
8943 nlfree(&nl);
developer72fb0bb2023-01-11 09:46:29 +08008944
developera3511852023-06-14 14:12:59 +08008945 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
8946 output_struct->wifi_devRxRate = info.wifi_devRxRate;
8947 output_struct->wifi_devTxRate = info.wifi_devTxRate;
8948 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
8949 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
8950 return RETURN_OK;
8951}
developer72fb0bb2023-01-11 09:46:29 +08008952
developera3511852023-06-14 14:12:59 +08008953INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
8954{
8955 if (NULL == device)
8956 return RETURN_ERR;
8957 return RETURN_OK;
8958}
8959//<<
developer72fb0bb2023-01-11 09:46:29 +08008960
developer72fb0bb2023-01-11 09:46:29 +08008961
8962//--------------wifi_ap_hal-----------------------------
8963//enables CTS protection for the radio used by this AP
8964INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
8965{
developera3511852023-06-14 14:12:59 +08008966 //save config and Apply instantly
8967 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008968}
8969
8970// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
8971INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
8972{
developera3511852023-06-14 14:12:59 +08008973 char config_file[64] = {'\0'};
8974 char config_dat_file[64] = {'\0'};
8975 char buf[64] = {'\0'};
8976 struct params list = {0};
8977 struct params dat = {0};
8978 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08008979 int res;
developereef7d562023-10-21 16:04:21 +08008980 unsigned char ht_coex = 0;
8981 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08008982
developera3511852023-06-14 14:12:59 +08008983 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developereef7d562023-10-21 16:04:21 +08008984
8985 if (enable)
8986 ht_coex = 1;
8987
developera3511852023-06-14 14:12:59 +08008988 list.name = "ht_coex";
developere40952c2023-06-15 18:46:43 +08008989 res = snprintf(buf, sizeof(buf), "%d", enable);
8990 if (os_snprintf_error(sizeof(buf), res)) {
8991 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8992 return RETURN_ERR;
8993 }
8994
developera3511852023-06-14 14:12:59 +08008995 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08008996
developera3511852023-06-14 14:12:59 +08008997 dat.name = "HT_BSSCoexistence";
8998 dat.value = buf;
developerd1824452023-05-18 12:30:04 +08008999
developera3511852023-06-14 14:12:59 +08009000 band = wifi_index_to_band(apIndex);
developere40952c2023-06-15 18:46:43 +08009001 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9002 if (os_snprintf_error(sizeof(config_file), res)) {
9003 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9004 return RETURN_ERR;
9005 }
9006
9007 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
9008 if (os_snprintf_error(sizeof(config_dat_file), res)) {
9009 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9010 return RETURN_ERR;
9011 }
9012
developera3511852023-06-14 14:12:59 +08009013 wifi_hostapdWrite(config_file, &list, 1);
9014 wifi_datfileWrite(config_dat_file, &dat, 1);
9015 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08009016
developereef7d562023-10-21 16:04:21 +08009017 /*do ht_coex quick setting*/
9018 ret = wifi_setChannel_netlink(band, NULL, NULL, NULL, &ht_coex);
9019 if (ret != RETURN_OK)
9020 wifi_debug(DEBUG_ERROR, "ht_coex quick setting fail\n");
developer72fb0bb2023-01-11 09:46:29 +08009021
developereef7d562023-10-21 16:04:21 +08009022 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08009023 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009024}
9025
9026//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
9027INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
9028{
developera3511852023-06-14 14:12:59 +08009029 char config_file[MAX_BUF_SIZE] = {'\0'};
9030 char buf[MAX_BUF_SIZE] = {'\0'};
9031 struct params list;
developere40952c2023-06-15 18:46:43 +08009032 int res;
developer72fb0bb2023-01-11 09:46:29 +08009033
developera3511852023-06-14 14:12:59 +08009034 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9035 if (threshold < 256 || threshold > 2346 )
9036 return RETURN_ERR;
9037 list.name = "fragm_threshold";
developere40952c2023-06-15 18:46:43 +08009038 res = snprintf(buf, sizeof(buf), "%d", threshold);
9039 if (os_snprintf_error(sizeof(buf), res)) {
9040 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9041 return RETURN_ERR;
9042 }
9043
developera3511852023-06-14 14:12:59 +08009044 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08009045
developere40952c2023-06-15 18:46:43 +08009046 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9047 if (os_snprintf_error(sizeof(config_file), res)) {
9048 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9049 return RETURN_ERR;
9050 }
9051
developera3511852023-06-14 14:12:59 +08009052 wifi_hostapdWrite(config_file, &list, 1);
9053 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08009054
developera3511852023-06-14 14:12:59 +08009055 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009056
developera3511852023-06-14 14:12:59 +08009057 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009058}
9059
9060// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
9061INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
9062{
developera3511852023-06-14 14:12:59 +08009063 char config_file[64] = {'\0'};
developer8078acf2023-08-04 18:52:48 +08009064
developera3511852023-06-14 14:12:59 +08009065 char buf[512] = {'\0'};
developera3511852023-06-14 14:12:59 +08009066 wifi_band band;
9067 int iterator = 0;
developera3511852023-06-14 14:12:59 +08009068 int ant_count = 0;
9069 int ant_bitmap = 0;
9070 struct params list;
9071 char dat_file[64] = {'\0'};
developera47dfe22023-12-21 16:02:31 +08009072 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08009073
developera3511852023-06-14 14:12:59 +08009074 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009075
developerdfd270b2023-12-12 10:24:30 +08009076 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08009077 if (band == band_invalid)
9078 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009079
developera3511852023-06-14 14:12:59 +08009080 if (band == band_2_4)
9081 iterator = 1;
9082 else if ((band == band_5) || (band == band_6))
9083 iterator = 2;
9084 else
9085 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009086
developera3511852023-06-14 14:12:59 +08009087 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
9088 for (; ant_bitmap > 0; ant_bitmap >>= 1)
9089 ant_count += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08009090
developera3511852023-06-14 14:12:59 +08009091 if (ant_count == 1 && STBC_Enable == TRUE) {
developer75bd10c2023-06-27 11:34:08 +08009092 wifi_debug(DEBUG_ERROR, "can not enable STBC when using only one antenna\n");
developera3511852023-06-14 14:12:59 +08009093 return RETURN_OK;
9094 }
developer72fb0bb2023-01-11 09:46:29 +08009095
developera47dfe22023-12-21 16:02:31 +08009096 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
9097 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
9098 return RETURN_ERR;
9099 }
9100 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developere40952c2023-06-15 18:46:43 +08009101 if (os_snprintf_error(sizeof(config_file), res)) {
9102 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9103 return RETURN_ERR;
9104 }
developera3511852023-06-14 14:12:59 +08009105 // set ht and vht config
9106 for (int i = 0; i < iterator; i++) {
developer8078acf2023-08-04 18:52:48 +08009107
developera3511852023-06-14 14:12:59 +08009108 memset(buf, 0, sizeof(buf));
9109 list.name = (i == 0)?"ht_capab":"vht_capab";
developera3511852023-06-14 14:12:59 +08009110 if (STBC_Enable == TRUE) {
9111 // Append the STBC flags in capab config
developer8078acf2023-08-04 18:52:48 +08009112
developera3511852023-06-14 14:12:59 +08009113 if (i == 0)
developer8078acf2023-08-04 18:52:48 +08009114 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
developera3511852023-06-14 14:12:59 +08009115 else
developer8078acf2023-08-04 18:52:48 +08009116 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
9117 if (res) {
9118 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009119 }
9120
developera3511852023-06-14 14:12:59 +08009121 } else if (STBC_Enable == FALSE) {
9122 // Remove the STBC flags and remain other flags in capab
developer8078acf2023-08-04 18:52:48 +08009123 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
9124 if (res) {
9125 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009126 }
developer8078acf2023-08-04 18:52:48 +08009127 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
9128 if (res) {
9129 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009130 }
9131
developera3511852023-06-14 14:12:59 +08009132 }
9133 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
9134 list.value = buf;
9135 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
9136 }
developere40952c2023-06-15 18:46:43 +08009137 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
9138 if (os_snprintf_error(sizeof(dat_file), res)) {
9139 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9140 return RETURN_ERR;
9141 }
9142
developer8078acf2023-08-04 18:52:48 +08009143 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
9144 if (res) {
9145 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009146 }
9147
developera1255e42023-05-13 17:45:02 +08009148 if ((band == band_5) || (band == band_6)) {
developer8078acf2023-08-04 18:52:48 +08009149 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
9150 if (res) {
9151 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009152 }
9153
developera1255e42023-05-13 17:45:02 +08009154 }
developera3511852023-06-14 14:12:59 +08009155 /*wifi_reloadAp(radioIndex);
developera1255e42023-05-13 17:45:02 +08009156 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08009157
developera3511852023-06-14 14:12:59 +08009158 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9159 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009160}
9161
developer37ad6bf2023-10-09 11:31:05 +08009162int mtk_get_ap_amsdu_callback(struct nl_msg *msg, void *data) {
9163 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9164 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX + 1];
9165 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9166 unsigned char status;
9167 unsigned char *out_status = data;
9168 int err = 0;
9169
9170 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9171 genlmsg_attrlen(gnlh, 0), NULL);
9172 if (err < 0){
9173 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
9174 return err;
9175 }
9176
9177 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9178 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX,
9179 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9180 if (err < 0){
9181 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
9182 return err;
9183 }
9184
9185 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN]) {
9186 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN]);
9187 if (status == 0) {
9188 wifi_debug(DEBUG_INFO, "disabled\n");
9189 } else {
9190 wifi_debug(DEBUG_INFO, "enabled\n");
9191 }
9192 *out_status = status;
9193 }
9194 }
9195 return 0;
9196}
9197
developer72fb0bb2023-01-11 09:46:29 +08009198// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
9199INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
9200{
developer37ad6bf2023-10-09 11:31:05 +08009201 char inf_name[IF_NAME_SIZE] = {0};
9202 unsigned int if_idx = 0;
9203 int ret = -1;
9204 struct unl unl_ins;
9205 struct nl_msg *msg = NULL;
9206 struct nlattr * msg_data = NULL;
9207 struct mtk_nl80211_param param;
developerc3556192023-12-06 17:59:09 +08009208 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08009209
developerc3556192023-12-06 17:59:09 +08009210 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
9211 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
9212 return RETURN_ERR;
9213 }
developer72fb0bb2023-01-11 09:46:29 +08009214
developerc3556192023-12-06 17:59:09 +08009215 if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
developer37ad6bf2023-10-09 11:31:05 +08009216 return RETURN_ERR;
9217 if_idx = if_nametoindex(inf_name);
9218 /*init mtk nl80211 vendor cmd*/
9219 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
9220 param.if_type = NL80211_ATTR_IFINDEX;
9221 param.if_idx = if_idx;
developer72fb0bb2023-01-11 09:46:29 +08009222
developer37ad6bf2023-10-09 11:31:05 +08009223 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9224 if (ret) {
9225 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer2c22d832023-05-18 17:46:26 +08009226 return RETURN_ERR;
9227 }
developer37ad6bf2023-10-09 11:31:05 +08009228 /*add mtk vendor cmd data*/
9229 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN, 0xf)) {
9230 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
9231 nlmsg_free(msg);
9232 goto err;
developere40952c2023-06-15 18:46:43 +08009233 }
9234
developer37ad6bf2023-10-09 11:31:05 +08009235 /*send mtk nl80211 vendor msg*/
9236 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_amsdu_callback, output_bool);
9237 if (ret) {
9238 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9239 goto err;
9240 }
9241 /*deinit mtk nl80211 vendor msg*/
9242 mtk_nl80211_deint(&unl_ins);
9243 wifi_debug(DEBUG_INFO,"send cmd success, get output_bool:%d\n", *output_bool);
developer2c22d832023-05-18 17:46:26 +08009244 return RETURN_OK;
developer37ad6bf2023-10-09 11:31:05 +08009245err:
9246 mtk_nl80211_deint(&unl_ins);
9247 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
9248 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009249}
9250
9251// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
9252INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
9253{
developer37ad6bf2023-10-09 11:31:05 +08009254 char inf_name[IF_NAME_SIZE] = {0};
9255 unsigned int if_idx = 0;
9256 struct unl unl_ins;
9257 struct nl_msg *msg = NULL;
9258 struct nlattr * msg_data = NULL;
9259 struct mtk_nl80211_param param;
9260 int ret = -1;
developerc3556192023-12-06 17:59:09 +08009261 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08009262
developerc3556192023-12-06 17:59:09 +08009263 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
9264 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
9265 return RETURN_ERR;
9266 }
developer72fb0bb2023-01-11 09:46:29 +08009267
developerc3556192023-12-06 17:59:09 +08009268 if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
developer2c22d832023-05-18 17:46:26 +08009269 return RETURN_ERR;
developer37ad6bf2023-10-09 11:31:05 +08009270 if_idx = if_nametoindex(inf_name);
9271 /*init mtk nl80211 vendor cmd*/
9272 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
9273 param.if_type = NL80211_ATTR_IFINDEX;
9274 param.if_idx = if_idx;
9275 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9276 if (ret) {
9277 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developere40952c2023-06-15 18:46:43 +08009278 return RETURN_ERR;
9279 }
developer37ad6bf2023-10-09 11:31:05 +08009280 /*add mtk vendor cmd data*/
9281 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN, amsduEnable)) {
9282 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
9283 nlmsg_free(msg);
9284 goto err;
9285 }
developer72fb0bb2023-01-11 09:46:29 +08009286
developer37ad6bf2023-10-09 11:31:05 +08009287 /*send mtk nl80211 vendor msg*/
9288 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9289 if (ret) {
9290 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9291 goto err;
9292 }
9293 /*deinit mtk nl80211 vendor msg*/
9294 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08009295 return RETURN_OK;
developer37ad6bf2023-10-09 11:31:05 +08009296err:
9297 mtk_nl80211_deint(&unl_ins);
9298 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
9299 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009300}
9301
9302//P2 // outputs the number of Tx streams
9303INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
9304{
developera3511852023-06-14 14:12:59 +08009305 char buf[8] = {0};
developera3511852023-06-14 14:12:59 +08009306 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08009307 int res;
developerc14d83a2023-06-29 20:09:42 +08009308 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08009309
developera3511852023-06-14 14:12:59 +08009310 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009311
developera3511852023-06-14 14:12:59 +08009312 phyId = radio_index_to_phy(radioIndex);
developer8078acf2023-08-04 18:52:48 +08009313
9314 res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
9315 if (res) {
9316 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009317 }
9318
developer72fb0bb2023-01-11 09:46:29 +08009319
developerc14d83a2023-06-29 20:09:42 +08009320 if (hal_strtol(buf, 16, &tmp) < 0) {
9321 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08009322 }
developerc14d83a2023-06-29 20:09:42 +08009323 *output_int = tmp;
developer72fb0bb2023-01-11 09:46:29 +08009324
developera3511852023-06-14 14:12:59 +08009325 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009326
developera3511852023-06-14 14:12:59 +08009327 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009328}
9329
9330INT fitChainMask(INT radioIndex, int antcount)
9331{
developera3511852023-06-14 14:12:59 +08009332 char buf[128] = {0};
developer8078acf2023-08-04 18:52:48 +08009333
developera3511852023-06-14 14:12:59 +08009334 char config_file[64] = {0};
9335 wifi_band band;
9336 struct params list[2] = {0};
developera47dfe22023-12-21 16:02:31 +08009337 int res, main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +08009338
developerdfd270b2023-12-12 10:24:30 +08009339 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +08009340 if (band == band_invalid)
9341 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009342
developera3511852023-06-14 14:12:59 +08009343 list[0].name = "he_mu_beamformer";
9344 list[1].name = "he_su_beamformer";
developer72fb0bb2023-01-11 09:46:29 +08009345
developera47dfe22023-12-21 16:02:31 +08009346 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
9347 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
9348 return RETURN_ERR;
9349 }
9350 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
developere40952c2023-06-15 18:46:43 +08009351 if (os_snprintf_error(sizeof(config_file), res)) {
9352 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9353 return RETURN_ERR;
9354 }
9355
developera3511852023-06-14 14:12:59 +08009356 if (antcount == 1) {
9357 // remove config about multiple antennas
developer8078acf2023-08-04 18:52:48 +08009358 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
9359 if (res) {
9360 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009361 }
9362
developer8078acf2023-08-04 18:52:48 +08009363 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
9364 if (res) {
9365 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009366 }
9367
developer8078acf2023-08-04 18:52:48 +08009368 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
9369 if (res) {
9370 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009371 }
9372
developer8078acf2023-08-04 18:52:48 +08009373 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
9374 if (res) {
9375 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009376 }
9377
developera3511852023-06-14 14:12:59 +08009378 list[0].value = "0";
9379 list[1].value = "0";
9380 } else {
9381 // 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.
9382 if (band == band_2_4 || band == band_5) {
developer8078acf2023-08-04 18:52:48 +08009383 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
9384 if (res) {
9385 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009386 }
9387
developera3511852023-06-14 14:12:59 +08009388 if (strlen(buf) > 0) {
developer8078acf2023-08-04 18:52:48 +08009389 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
9390 if (res) {
9391 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009392 }
developera3511852023-06-14 14:12:59 +08009393 }
9394 }
9395 if (band == band_5) {
developer8078acf2023-08-04 18:52:48 +08009396 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
9397 if (res) {
9398 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009399 }
developera3511852023-06-14 14:12:59 +08009400 if (strlen(buf) > 0) {
developer8078acf2023-08-04 18:52:48 +08009401 res = _syscmd_secure(buf, sizeof(buf) , "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
9402 if (res) {
9403 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009404 }
developera3511852023-06-14 14:12:59 +08009405 }
9406 }
developer72fb0bb2023-01-11 09:46:29 +08009407
developer8078acf2023-08-04 18:52:48 +08009408 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
9409 if (res) {
9410 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009411 }
9412
developera3511852023-06-14 14:12:59 +08009413 if (strlen(buf) == 0) {
developer8078acf2023-08-04 18:52:48 +08009414 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
9415 if (res) {
9416 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009417 }
developera3511852023-06-14 14:12:59 +08009418 }
developer72fb0bb2023-01-11 09:46:29 +08009419
developer8078acf2023-08-04 18:52:48 +08009420 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
9421 if (res) {
9422 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developerc14d83a2023-06-29 20:09:42 +08009423 }
developera3511852023-06-14 14:12:59 +08009424 if (strlen(buf) == 0) {
developer8078acf2023-08-04 18:52:48 +08009425 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
9426 if (res) {
9427 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +08009428 }
developere40952c2023-06-15 18:46:43 +08009429 }
9430
developer8078acf2023-08-04 18:52:48 +08009431 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
9432 if (res) {
9433 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developera3511852023-06-14 14:12:59 +08009434 }
developera3511852023-06-14 14:12:59 +08009435 if (strlen(buf) == 0) {
developer8078acf2023-08-04 18:52:48 +08009436 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
developera3511852023-06-14 14:12:59 +08009437 } else {
developer8078acf2023-08-04 18:52:48 +08009438 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
developere40952c2023-06-15 18:46:43 +08009439 }
developer8078acf2023-08-04 18:52:48 +08009440 if (res) {
9441 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developera3511852023-06-14 14:12:59 +08009442 }
developere40952c2023-06-15 18:46:43 +08009443
developera3511852023-06-14 14:12:59 +08009444 list[0].value = "1";
9445 list[1].value = "1";
9446 }
9447 wifi_hostapdWrite(config_file, list, 2);
developerdaf24792023-06-06 11:40:04 +08009448 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009449}
9450
9451//P2 // sets the number of Tx streams to an enviornment variable
9452INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
9453{
developera3511852023-06-14 14:12:59 +08009454 char cmd[128] = {0};
9455 char buf[128] = {0};
9456 int phyId = 0;
9457 int cur_mask = 0;
9458 int antcountmsk = 0;
developera1255e42023-05-13 17:45:02 +08009459 INT cur_nss = 0;
developer863a4a62023-06-06 16:55:59 +08009460 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +08009461 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08009462 int res;
developer72fb0bb2023-01-11 09:46:29 +08009463
developera3511852023-06-14 14:12:59 +08009464 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009465
developera3511852023-06-14 14:12:59 +08009466 if (numStreams <= 0) {
developer75bd10c2023-06-27 11:34:08 +08009467 wifi_debug(DEBUG_ERROR, "chainmask is not supported %d.\n", numStreams);
developera3511852023-06-14 14:12:59 +08009468 return RETURN_ERR;
9469 }
developer72fb0bb2023-01-11 09:46:29 +08009470
developera3511852023-06-14 14:12:59 +08009471 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
developera1255e42023-05-13 17:45:02 +08009472 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
9473 cur_nss += 1;
9474 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
developera3511852023-06-14 14:12:59 +08009475 if (cur_nss == numStreams)
9476 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009477
developera3511852023-06-14 14:12:59 +08009478 wifi_setRadioEnable(radioIndex, FALSE);
developer72fb0bb2023-01-11 09:46:29 +08009479
developera3511852023-06-14 14:12:59 +08009480 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08009481 //iw need mask value.
9482 for (;numStreams > 0; numStreams--)
9483 antcountmsk |= 0x1 << (numStreams - 1);
developere40952c2023-06-15 18:46:43 +08009484 res = snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
9485 if (os_snprintf_error(sizeof(cmd), res)) {
9486 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9487 return RETURN_ERR;
9488 }
developerb758dfd2023-06-21 17:32:07 +08009489
developer8078acf2023-08-04 18:52:48 +08009490 res=_syscmd_secure(buf, sizeof(buf), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
9491 if (res) {
9492 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
9493 }
9494
developera3511852023-06-14 14:12:59 +08009495 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08009496 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08009497 return RETURN_ERR;
9498 }
developerdfd270b2023-12-12 10:24:30 +08009499 band = radio_index_to_band(radioIndex);
developera1255e42023-05-13 17:45:02 +08009500 if (band == band_invalid) {
9501 printf("%s:Band Error\n", __func__);
9502 return RETURN_ERR;
9503 }
developere40952c2023-06-15 18:46:43 +08009504 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
9505 if (os_snprintf_error(sizeof(dat_file), res)) {
9506 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9507 return RETURN_ERR;
9508 }
developerb758dfd2023-06-21 17:32:07 +08009509
developere40952c2023-06-15 18:46:43 +08009510 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
9511 if (os_snprintf_error(sizeof(cmd), res)) {
9512 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9513 return RETURN_ERR;
9514 }
developerb758dfd2023-06-21 17:32:07 +08009515
developer8078acf2023-08-04 18:52:48 +08009516 res=_syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
9517 if (res) {
9518 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
9519 }
9520
developera3511852023-06-14 14:12:59 +08009521 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08009522 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08009523 return RETURN_ERR;
9524 }
developer8078acf2023-08-04 18:52:48 +08009525
developere40952c2023-06-15 18:46:43 +08009526 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
9527 if (os_snprintf_error(sizeof(cmd), res)) {
9528 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9529 return RETURN_ERR;
9530 }
developerb758dfd2023-06-21 17:32:07 +08009531
developer8078acf2023-08-04 18:52:48 +08009532 res=_syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
9533 if (res) {
9534 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
9535 }
9536
developera3511852023-06-14 14:12:59 +08009537 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08009538 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08009539 return RETURN_ERR;
9540 }
9541 fitChainMask(radioIndex, numStreams);
9542 wifi_setRadioEnable(radioIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +08009543
developera3511852023-06-14 14:12:59 +08009544 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9545 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009546}
9547
9548//P2 // outputs the number of Rx streams
9549INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
9550{
developera3511852023-06-14 14:12:59 +08009551 char buf[8] = {0};
developera3511852023-06-14 14:12:59 +08009552 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +08009553 int res;
developerc14d83a2023-06-29 20:09:42 +08009554 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +08009555
developera3511852023-06-14 14:12:59 +08009556 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009557
developera3511852023-06-14 14:12:59 +08009558 phyId = radio_index_to_phy(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08009559
developer8078acf2023-08-04 18:52:48 +08009560 res=_syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
9561 if (res) {
9562 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +08009563 }
developer72fb0bb2023-01-11 09:46:29 +08009564
developerc14d83a2023-06-29 20:09:42 +08009565 if (hal_strtol(buf, 16, &tmp) < 0) {
9566 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +08009567 }
developerc14d83a2023-06-29 20:09:42 +08009568 *output_int = tmp;
developer72fb0bb2023-01-11 09:46:29 +08009569
developera3511852023-06-14 14:12:59 +08009570 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009571
developera3511852023-06-14 14:12:59 +08009572 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009573}
9574
9575//P2 // sets the number of Rx streams to an enviornment variable
9576INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
9577{
developera3511852023-06-14 14:12:59 +08009578 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9579 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08009580 wifi_debug(DEBUG_ERROR, "wifi_setRadioTxChainMask return error.\n");
developera3511852023-06-14 14:12:59 +08009581 return RETURN_ERR;
9582 }
9583 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9584 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009585}
9586
9587//Get radio RDG enable setting
9588INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
9589{
developer47cc27a2023-05-17 23:09:58 +08009590 if (NULL == output_bool)
9591 return RETURN_ERR;
9592
9593 *output_bool = TRUE;
9594 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009595}
9596
9597//Get radio RDG enable setting
9598INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
9599{
developer47cc27a2023-05-17 23:09:58 +08009600 char rdg_status[2] = {0};
9601 char dat_file[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08009602 int res;
developer47cc27a2023-05-17 23:09:58 +08009603
9604 if (NULL == output_bool)
9605 return RETURN_ERR;
9606
9607 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08009608 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
9609 if (os_snprintf_error(sizeof(dat_file), res)) {
9610 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9611 return RETURN_ERR;
9612 }
developer47cc27a2023-05-17 23:09:58 +08009613
9614 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
9615 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
9616 *output_bool = TRUE;
9617 else
9618 *output_bool = FALSE;
9619
9620 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009621}
9622
9623//Set radio RDG enable setting
9624INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
9625{
developer47cc27a2023-05-17 23:09:58 +08009626 char dat_file[MAX_CMD_SIZE] = {0};
9627 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08009628 int res;
developer47cc27a2023-05-17 23:09:58 +08009629
9630 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08009631 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
9632 if (os_snprintf_error(sizeof(dat_file), res)) {
9633 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9634 return RETURN_ERR;
9635 }
developer47cc27a2023-05-17 23:09:58 +08009636
9637 params.name = "HT_RDG";
9638
developera3511852023-06-14 14:12:59 +08009639 if (enable) {
9640 params.value = "1";
9641 } else {
9642 params.value = "0";
9643 }
developer47cc27a2023-05-17 23:09:58 +08009644
9645 wifi_datfileWrite(dat_file, &params, 1);
9646
9647 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009648}
9649
developer5cd4c862023-05-26 09:34:42 +08009650
9651int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08009652{
developer5cd4c862023-05-26 09:34:42 +08009653 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9654 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
9655 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9656 unsigned char status;
9657 unsigned char *out_status = data;
9658 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08009659
developer5cd4c862023-05-26 09:34:42 +08009660 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9661 genlmsg_attrlen(gnlh, 0), NULL);
9662 if (err < 0){
9663 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
9664 return err;
9665 }
developer8e6583c2023-05-23 13:36:06 +08009666
developer5cd4c862023-05-26 09:34:42 +08009667 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9668 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
9669 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9670 if (err < 0){
9671 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
9672 return err;
9673 }
developer8e6583c2023-05-23 13:36:06 +08009674
developer5cd4c862023-05-26 09:34:42 +08009675 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
9676 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
9677 if (status == 0) {
9678 wifi_debug(DEBUG_NOTICE, "disabled\n");
9679 } else {
9680 wifi_debug(DEBUG_NOTICE, "enabled\n");
9681 }
9682 *out_status = status;
9683 }
9684 }
developer8e6583c2023-05-23 13:36:06 +08009685
developer5cd4c862023-05-26 09:34:42 +08009686 return 0;
9687}
developer8e6583c2023-05-23 13:36:06 +08009688
developer5cd4c862023-05-26 09:34:42 +08009689int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
9690{
9691 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9692 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
9693 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9694 unsigned char status;
9695 unsigned char *out_status = data;
9696 int err = 0;
9697
9698 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9699 genlmsg_attrlen(gnlh, 0), NULL);
9700 if (err < 0) {
9701 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
9702 return err;
9703 }
9704
9705 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9706 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
9707 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9708 if (err < 0) {
9709 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
9710 return err;
9711 }
9712
9713 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
9714 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
9715 if (status == 0) {
9716 wifi_debug(DEBUG_NOTICE, "disabled\n");
9717 } else {
9718 wifi_debug(DEBUG_NOTICE, "enabled\n");
9719 }
9720 *out_status = status;
9721 }
9722 }
9723
9724 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08009725}
9726
developer5cd4c862023-05-26 09:34:42 +08009727INT mtk_wifi_get_ba_decl_auto_status(
9728 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
9729{
9730 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08009731 unsigned int if_idx = 0;
9732 int ret = -1;
9733 struct unl unl_ins;
9734 struct nl_msg *msg = NULL;
9735 struct nlattr * msg_data = NULL;
9736 struct mtk_nl80211_param param;
9737
9738 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9739 return RETURN_ERR;
9740 if_idx = if_nametoindex(inf_name);
9741 if (!if_idx) {
9742 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
9743 return RETURN_ERR;
9744 }
9745 /*init mtk nl80211 vendor cmd*/
9746 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
9747 param.if_type = NL80211_ATTR_IFINDEX;
9748 param.if_idx = if_idx;
9749
9750 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9751 if (ret) {
9752 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9753 return RETURN_ERR;
9754 }
9755 /*add mtk vendor cmd data*/
9756 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
9757 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
9758 nlmsg_free(msg);
9759 goto err;
9760 }
9761
9762 /*send mtk nl80211 vendor msg*/
9763 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
9764 if (ret) {
9765 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9766 goto err;
9767 }
9768 /*deinit mtk nl80211 vendor msg*/
9769 mtk_nl80211_deint(&unl_ins);
9770 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
9771 return RETURN_OK;
9772err:
9773 mtk_nl80211_deint(&unl_ins);
9774 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
9775 return RETURN_ERR;
9776}
developere0ff7232023-06-08 16:33:14 +08009777
9778INT mtk_wifi_set_auto_ba_en(
9779 INT apIndex, INT vendor_data_attr, BOOL enable)
9780{
9781 char inf_name[IF_NAME_SIZE] = {0};
9782 unsigned int if_idx = 0;
9783 int ret = -1;
9784 struct unl unl_ins;
9785 struct nl_msg *msg = NULL;
9786 struct nlattr * msg_data = NULL;
9787 struct mtk_nl80211_param param;
9788
9789 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9790 return RETURN_ERR;
9791 if_idx = if_nametoindex(inf_name);
9792 if (!if_idx) {
9793 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
9794 return RETURN_ERR;
9795 }
9796 /*init mtk nl80211 vendor cmd*/
9797 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
9798 param.if_type = NL80211_ATTR_IFINDEX;
9799 param.if_idx = if_idx;
9800
9801 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9802 if (ret) {
9803 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9804 return RETURN_ERR;
9805 }
9806 /*add mtk vendor cmd data*/
9807 if (nla_put_u8(msg, vendor_data_attr, enable)) {
9808 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
9809 nlmsg_free(msg);
9810 goto err;
9811 }
9812
9813 /*send mtk nl80211 vendor msg*/
9814 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9815 if (ret) {
9816 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9817 goto err;
9818 }
9819 /*deinit mtk nl80211 vendor msg*/
9820 mtk_nl80211_deint(&unl_ins);
9821 return RETURN_OK;
9822err:
9823 mtk_nl80211_deint(&unl_ins);
9824 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
9825 return RETURN_ERR;
9826}
9827
developer5cd4c862023-05-26 09:34:42 +08009828//Get radio ADDBA enable setting
9829INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
9830{
9831 if (output_bool == NULL) {
9832 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
9833 return RETURN_ERR;
9834 }
9835 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
9836 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
9837 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
9838 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
9839 return RETURN_ERR;
9840 }
9841 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
9842 return RETURN_OK;
9843}
9844
developer72fb0bb2023-01-11 09:46:29 +08009845//Set radio ADDBA enable setting
9846INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
9847{
developera3511852023-06-14 14:12:59 +08009848 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009849}
9850
9851//Get radio auto block ack enable setting
9852INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
9853{
developer5cd4c862023-05-26 09:34:42 +08009854 if (output_bool == NULL) {
9855 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
9856 return RETURN_ERR;
9857 }
developer8e6583c2023-05-23 13:36:06 +08009858
developera3511852023-06-14 14:12:59 +08009859 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
developer5cd4c862023-05-26 09:34:42 +08009860 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
9861 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
9862 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
9863 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
9864 return RETURN_ERR;
9865 }
9866 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
9867 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009868}
9869
9870//Set radio auto block ack enable setting
9871INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
9872{
developera3511852023-06-14 14:12:59 +08009873 if (mtk_wifi_set_auto_ba_en
developere0ff7232023-06-08 16:33:14 +08009874 (radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
9875 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
9876 return RETURN_ERR;
9877 }
9878 wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08009879 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009880}
9881
9882//Get radio 11n pure mode enable support
9883INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
9884{
developera3511852023-06-14 14:12:59 +08009885 if (NULL == output_bool)
9886 return RETURN_ERR;
9887 *output_bool = TRUE;
9888 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009889}
9890
9891//Get radio 11n pure mode enable setting
9892INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
9893{
developera3511852023-06-14 14:12:59 +08009894 if (NULL == output_bool)
9895 return RETURN_ERR;
9896 *output_bool = TRUE;
9897 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009898}
9899
9900//Set radio 11n pure mode enable setting
developer86035662023-06-28 19:21:12 +08009901INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
developer72fb0bb2023-01-11 09:46:29 +08009902{
developer82533be2023-06-28 17:21:01 +08009903 char interface_name[16] = {0};
9904 int if_idx, ret = 0;
9905 struct nl_msg *msg = NULL;
9906 struct nlattr * msg_data = NULL;
9907 struct mtk_nl80211_param param;
9908 struct unl unl_ins;
developerc3556192023-12-06 17:59:09 +08009909 int main_vap_idx;
developer82533be2023-06-28 17:21:01 +08009910
9911 if (radioIndex > MAX_APS) {
9912 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", radioIndex);
9913 return RETURN_ERR;
9914 }
9915 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerc3556192023-12-06 17:59:09 +08009916
9917 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
9918 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
9919 return RETURN_ERR;
9920 }
9921
9922 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developer82533be2023-06-28 17:21:01 +08009923 return RETURN_ERR;
developerd14dff12023-06-28 22:47:44 +08009924
developer82533be2023-06-28 17:21:01 +08009925 if_idx = if_nametoindex(interface_name);
9926 /*init mtk nl80211 vendor cmd*/
9927 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
9928 param.if_type = NL80211_ATTR_IFINDEX;
9929 param.if_idx = if_idx;
9930 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9931 if (ret) {
9932 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9933 return RETURN_ERR;
9934 }
9935 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_HT_OP_MODE, enable)) {
9936 printf("Nla put attribute error\n");
9937 nlmsg_free(msg);
9938 goto err;
9939 }
9940 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9941 if (ret) {
9942 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9943 goto err;
9944 }
9945 mtk_nl80211_deint(&unl_ins);
9946 //wifi_debug(DEBUG_NOTICE, "set Gf cmd success.\n");
9947 printf("set gf=%d cmd success.\n", enable);
9948 return RETURN_OK;
9949err:
9950 mtk_nl80211_deint(&unl_ins);
9951 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08009952 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009953}
9954
developer5cd4c862023-05-26 09:34:42 +08009955int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08009956{
developer5cd4c862023-05-26 09:34:42 +08009957 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9958 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
9959 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9960 unsigned char status = 0, *out_status = data;
9961 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08009962
developer5cd4c862023-05-26 09:34:42 +08009963 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9964 genlmsg_attrlen(gnlh, 0), NULL);
9965 if (err < 0) {
9966 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
9967 return err;
9968 }
developer72fb0bb2023-01-11 09:46:29 +08009969
developer5cd4c862023-05-26 09:34:42 +08009970 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9971 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
9972 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9973 if (err < 0){
9974 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
9975 return err;
9976 }
developer72fb0bb2023-01-11 09:46:29 +08009977
developer5cd4c862023-05-26 09:34:42 +08009978 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
9979 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
9980 if (status == 0) {
9981 wifi_debug(DEBUG_NOTICE, "disabled\n");
9982 } else {
9983 wifi_debug(DEBUG_NOTICE, "enabled\n");
9984 }
9985 *out_status = status;
9986 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
9987 }
9988 }
9989
9990 return 0;
9991}
9992
9993INT mtk_wifi_set_igmp_en_status(
9994 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
9995 unsigned char in_en_stat, BOOL *output_bool)
9996{
9997 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08009998 unsigned int if_idx = 0;
9999 int ret = -1;
10000 struct unl unl_ins;
10001 struct nl_msg *msg = NULL;
10002 struct nlattr * msg_data = NULL;
10003 struct mtk_nl80211_param param;
10004
10005 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
10006 return RETURN_ERR;
10007 if_idx = if_nametoindex(inf_name);
10008 if (!if_idx) {
10009 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
10010 return RETURN_ERR;
10011 }
10012 /*init mtk nl80211 vendor cmd*/
10013 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
10014 param.if_type = NL80211_ATTR_IFINDEX;
10015 param.if_idx = if_idx;
10016
10017 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10018 if (ret) {
10019 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10020 return RETURN_ERR;
10021 }
10022 /*add mtk vendor cmd data*/
10023 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
10024 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
10025 nlmsg_free(msg);
10026 goto err;
10027 }
10028
10029 /*send mtk nl80211 vendor msg*/
10030 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
10031 if (ret) {
10032 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
10033 goto err;
10034 }
10035 /*deinit mtk nl80211 vendor msg*/
10036 mtk_nl80211_deint(&unl_ins);
10037 if (output_bool) {
10038 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
10039 } else {
10040 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
10041 }
10042 return RETURN_OK;
10043err:
10044 mtk_nl80211_deint(&unl_ins);
10045 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
10046 return RETURN_ERR;
10047}
10048
10049
10050//Get radio IGMP snooping enable setting
10051INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
10052{
10053 if (output_bool == NULL) {
10054 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
10055 return RETURN_ERR;
10056 }
developera3511852023-06-14 14:12:59 +080010057 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +080010058 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
10059 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
10060 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
10061 return RETURN_ERR;
10062 }
10063 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developera3511852023-06-14 14:12:59 +080010064 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010065}
10066
10067//Set radio IGMP snooping enable setting
10068INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
10069{
developera3511852023-06-14 14:12:59 +080010070 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +080010071 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
10072 NULL, enable, NULL) != RETURN_OK) {
10073 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
10074 return RETURN_ERR;
10075 }
10076 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +080010077 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010078}
10079
10080//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +080010081INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +080010082{
developera3511852023-06-14 14:12:59 +080010083 if (NULL == output_int)
10084 return RETURN_ERR;
10085 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080010086
developera3511852023-06-14 14:12:59 +080010087 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010088}
10089
10090
10091//---------------------------------------------------------------------------------------------------
10092//
10093// Additional Wifi AP level APIs used for Access Point devices
10094//
10095//---------------------------------------------------------------------------------------------------
10096
10097// creates a new ap and pushes these parameters to the hardware
10098INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
10099{
developera3511852023-06-14 14:12:59 +080010100 // Deprecated when use hal version 3, use wifi_createVap() instead.
10101 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010102}
10103
10104// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
10105INT wifi_deleteAp(INT apIndex)
10106{
developer7e4a2a62023-04-06 19:56:03 +080010107 char interface_name[16] = {0};
10108 char buf[MAX_BUF_SIZE];
developere40952c2023-06-15 18:46:43 +080010109 int res;
developer72fb0bb2023-01-11 09:46:29 +080010110
developer7e4a2a62023-04-06 19:56:03 +080010111 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10112 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +080010113
developer8078acf2023-08-04 18:52:48 +080010114 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
10115 if (res) {
10116 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080010117 }
developer72fb0bb2023-01-11 09:46:29 +080010118
developer7e4a2a62023-04-06 19:56:03 +080010119 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010120
developer7e4a2a62023-04-06 19:56:03 +080010121 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010122}
10123
10124// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
10125INT wifi_getApName(INT apIndex, CHAR *output_string)
10126{
developer7e4a2a62023-04-06 19:56:03 +080010127 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +080010128 int radio_idx = 0;
10129 int bss_idx = 0;
developere40952c2023-06-15 18:46:43 +080010130 int res;
developer72fb0bb2023-01-11 09:46:29 +080010131
developer7e4a2a62023-04-06 19:56:03 +080010132 if(!output_string)
10133 return RETURN_ERR;
10134
10135 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
developerc3556192023-12-06 17:59:09 +080010136 vap_index_to_radio_array_index(apIndex, &radio_idx, &bss_idx);
developer7e4a2a62023-04-06 19:56:03 +080010137
developere40952c2023-06-15 18:46:43 +080010138 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 +080010139 } else
developere40952c2023-06-15 18:46:43 +080010140 res = snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
10141
10142 if (os_snprintf_error(IF_NAME_SIZE, res)) {
10143 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10144 return RETURN_ERR;
10145 }
developer7e4a2a62023-04-06 19:56:03 +080010146
10147 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010148}
10149
10150// Outputs the index number in that corresponds to the SSID string
10151INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
10152{
developer7e4a2a62023-04-06 19:56:03 +080010153 char buf[32] = {0};
developerc3556192023-12-06 17:59:09 +080010154 int ap_idx = 0;
developer7e4a2a62023-04-06 19:56:03 +080010155 char *apIndex_str = NULL;
10156 char radio_idx = 0;
10157 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +080010158 int res;
developerc14d83a2023-06-29 20:09:42 +080010159 long int tmp;
developer72fb0bb2023-01-11 09:46:29 +080010160
developer8078acf2023-08-04 18:52:48 +080010161 res = _syscmd_secure(buf, sizeof(buf), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'", inputSsidString);
10162 if (res) {
10163 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080010164 }
10165
developer7e4a2a62023-04-06 19:56:03 +080010166 if (strlen(buf)) {
10167 apIndex_str = strtok(buf, "\n");
developerd14dff12023-06-28 22:47:44 +080010168 if (apIndex_str == NULL) {
10169 wifi_debug(DEBUG_ERROR, "strtok fail\n");
10170 return RETURN_ERR;
10171 }
developerc14d83a2023-06-29 20:09:42 +080010172 if (hal_strtol(apIndex_str, 10, &tmp) < 0) {
10173 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080010174 }
developerc14d83a2023-06-29 20:09:42 +080010175 *output_int = tmp;
developer7e4a2a62023-04-06 19:56:03 +080010176 return RETURN_OK;
10177 }
developer72fb0bb2023-01-11 09:46:29 +080010178
developer7e4a2a62023-04-06 19:56:03 +080010179 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
10180 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
10181 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
10182 radio_idx = 2;
10183 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
10184 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
10185 radio_idx = 1;
10186 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
10187 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
10188 radio_idx = 0;
10189 } else {
10190 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
10191 __func__, inputSsidString, ap_idx);
developera3511852023-06-14 14:12:59 +080010192 *output_int = -1;
10193 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080010194 }
10195
developerc3556192023-12-06 17:59:09 +080010196 if(array_index_to_vap_index(radio_idx, bss_idx, &ap_idx) != RETURN_OK) {
10197 wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radio_idx, bss_idx);
10198 return RETURN_ERR;
10199 }
developer7e4a2a62023-04-06 19:56:03 +080010200
developer6c6ef372023-11-08 10:59:14 +080010201 if (ap_idx >= 0 && ap_idx < MAX_APS) {
developer7e4a2a62023-04-06 19:56:03 +080010202 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
10203 __func__, inputSsidString, ap_idx);
10204 *output_int = ap_idx;
10205 return RETURN_OK;
10206 }
10207
10208 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010209}
10210
10211INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
10212{
developera3511852023-06-14 14:12:59 +080010213 return wifi_getIndexFromName(inputSsidString, output_int);
developer72fb0bb2023-01-11 09:46:29 +080010214}
10215
10216// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
10217INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
10218{
developera3511852023-06-14 14:12:59 +080010219 char buf[MAX_BUF_SIZE] = {0};
10220 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080010221 int res;
developer72fb0bb2023-01-11 09:46:29 +080010222
developera3511852023-06-14 14:12:59 +080010223 if(NULL == output_string)
10224 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010225
developer32f2a182023-06-27 19:50:41 +080010226 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10227 if (os_snprintf_error(sizeof(config_file), res)) {
10228 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10229 return RETURN_ERR;
10230 }
developera3511852023-06-14 14:12:59 +080010231 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
10232 if((strcmp(buf,"3")==0))
developere40952c2023-06-15 18:46:43 +080010233 res = snprintf(output_string, 32, "WPAand11i");
developera3511852023-06-14 14:12:59 +080010234 else if((strcmp(buf,"2")==0))
developere40952c2023-06-15 18:46:43 +080010235 res = snprintf(output_string, 32, "11i");
developera3511852023-06-14 14:12:59 +080010236 else if((strcmp(buf,"1")==0))
developere40952c2023-06-15 18:46:43 +080010237 res = snprintf(output_string, 32, "WPA");
developera3511852023-06-14 14:12:59 +080010238 else
developere40952c2023-06-15 18:46:43 +080010239 res = snprintf(output_string, 32, "None");
10240 if (os_snprintf_error(32, res)) {
10241 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10242 return RETURN_ERR;
10243 }
developer72fb0bb2023-01-11 09:46:29 +080010244
developera3511852023-06-14 14:12:59 +080010245 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010246}
10247
10248// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
10249INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
10250{
developera3511852023-06-14 14:12:59 +080010251 char config_file[MAX_BUF_SIZE] = {0};
10252 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010253 int res;
developer72fb0bb2023-01-11 09:46:29 +080010254
developera3511852023-06-14 14:12:59 +080010255 if (NULL == beaconTypeString)
10256 return RETURN_ERR;
10257 list.name = "wpa";
10258 list.value = "0";
developer72fb0bb2023-01-11 09:46:29 +080010259
developera3511852023-06-14 14:12:59 +080010260 if((strcmp(beaconTypeString,"WPAand11i")==0))
10261 list.value="3";
10262 else if((strcmp(beaconTypeString,"11i")==0))
10263 list.value="2";
10264 else if((strcmp(beaconTypeString,"WPA")==0))
10265 list.value="1";
developer72fb0bb2023-01-11 09:46:29 +080010266
developer75bd10c2023-06-27 11:34:08 +080010267 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10268 if (os_snprintf_error(sizeof(config_file), res)) {
10269 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10270 return RETURN_ERR;
10271 }
developera3511852023-06-14 14:12:59 +080010272 wifi_hostapdWrite(config_file, &list, 1);
10273 wifi_hostapdProcessUpdate(apIndex, &list, 1);
10274 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
10275 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010276}
10277
10278// sets the beacon interval on the hardware for this AP
10279INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
10280{
developera3511852023-06-14 14:12:59 +080010281 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10282 struct params params={'\0'};
10283 char buf[MAX_BUF_SIZE] = {'\0'};
10284 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +080010285 int res;
developer72fb0bb2023-01-11 09:46:29 +080010286
developera3511852023-06-14 14:12:59 +080010287 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +080010288 res = snprintf(buf, sizeof(buf), "%u", beaconInterval);
10289 if (os_snprintf_error(sizeof(buf), res)) {
10290 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10291 return RETURN_ERR;
10292 }
developera3511852023-06-14 14:12:59 +080010293 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +080010294
developer75bd10c2023-06-27 11:34:08 +080010295 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10296 if (os_snprintf_error(sizeof(config_file), res)) {
10297 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10298 return RETURN_ERR;
10299 }
developera3511852023-06-14 14:12:59 +080010300 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +080010301
developera3511852023-06-14 14:12:59 +080010302 wifi_hostapdProcessUpdate(apIndex, &params, 1);
10303 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10304 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010305}
10306
10307INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
10308{
developera3511852023-06-14 14:12:59 +080010309 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
10310 return RETURN_ERR;
10311 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010312}
10313
10314// Get the packet size threshold supported.
10315INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
10316{
developera3511852023-06-14 14:12:59 +080010317 //save config and apply instantly
10318 if (NULL == output_bool)
10319 return RETURN_ERR;
10320 *output_bool = TRUE;
10321 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010322}
10323
10324// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
10325INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
10326{
developera3511852023-06-14 14:12:59 +080010327 char buf[16] = {0};
10328 char config_file[128] = {0};
10329 struct params param = {0};
developere40952c2023-06-15 18:46:43 +080010330 int res;
developer72fb0bb2023-01-11 09:46:29 +080010331
developera3511852023-06-14 14:12:59 +080010332 if (threshold > 65535) {
developer75bd10c2023-06-27 11:34:08 +080010333 wifi_debug(DEBUG_ERROR, "rts threshold %u is too big.\n", threshold);
developera3511852023-06-14 14:12:59 +080010334 return RETURN_ERR;
10335 }
developer72fb0bb2023-01-11 09:46:29 +080010336
developere40952c2023-06-15 18:46:43 +080010337 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10338 if (os_snprintf_error(sizeof(config_file), res)) {
10339 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10340 return RETURN_ERR;
10341 }
10342
10343 res = snprintf(buf, sizeof(buf), "%u", threshold);
10344 if (os_snprintf_error(sizeof(buf), res)) {
10345 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10346 return RETURN_ERR;
10347 }
developera3511852023-06-14 14:12:59 +080010348 param.name = "rts_threshold";
10349 param.value = buf;
10350 wifi_hostapdWrite(config_file, &param, 1);
10351 wifi_hostapdProcessUpdate(apIndex, &param, 1);
10352 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010353
developera3511852023-06-14 14:12:59 +080010354 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010355}
10356
10357// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
10358INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
10359{
developere40952c2023-06-15 18:46:43 +080010360 int res;
10361
developera3511852023-06-14 14:12:59 +080010362 if (NULL == output_string)
10363 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010364 res = snprintf(output_string, 32, "TKIPandAESEncryption");
10365 if (os_snprintf_error(32, res)) {
10366 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10367 return RETURN_ERR;
10368 }
developera3511852023-06-14 14:12:59 +080010369 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010370
10371}
10372
10373// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
10374INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
10375{
developera3511852023-06-14 14:12:59 +080010376 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10377 char *param_name = NULL;
10378 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
developerc79e9172023-06-06 19:48:03 +080010379 unsigned int len;
developere40952c2023-06-15 18:46:43 +080010380 int res;
developer72fb0bb2023-01-11 09:46:29 +080010381
developera3511852023-06-14 14:12:59 +080010382 if(NULL == output_string)
10383 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010384
developer75bd10c2023-06-27 11:34:08 +080010385 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10386 if (os_snprintf_error(sizeof(config_file), res)) {
10387 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10388 return RETURN_ERR;
10389 }
10390
developera3511852023-06-14 14:12:59 +080010391 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010392
developera3511852023-06-14 14:12:59 +080010393 if(strcmp(buf,"0")==0)
10394 {
10395 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
developere40952c2023-06-15 18:46:43 +080010396 res = snprintf(output_string, 32, "None");
10397 if (os_snprintf_error(32, res)) {
10398 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10399 return RETURN_ERR;
10400 }
developera3511852023-06-14 14:12:59 +080010401 return RETURN_OK;
10402 }
10403 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
10404 param_name = "rsn_pairwise";
10405 else if((strcmp(buf,"1")==0))
10406 param_name = "wpa_pairwise";
10407 else
10408 return RETURN_ERR;
10409 memset(output_string,'\0',32);
10410 wifi_hostapdRead(config_file,param_name,output_string,32);
10411 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
10412 param_name = "wpa_pairwise";
10413 memset(output_string, '\0', 32);
10414 wifi_hostapdRead(config_file, param_name, output_string, 32);
10415 }
10416 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
developer72fb0bb2023-01-11 09:46:29 +080010417
developera3511852023-06-14 14:12:59 +080010418 if(strcmp(output_string,"TKIP CCMP") == 0) {
developerc79e9172023-06-06 19:48:03 +080010419 len = strlen("TKIPandAESEncryption");
10420 memcpy(output_string,"TKIPandAESEncryption", len);
10421 output_string[len] = '\0';
10422 } else if(strcmp(output_string,"TKIP") == 0) {
10423 len = strlen("TKIPEncryption");
10424 memcpy(output_string,"TKIPEncryption", len);
10425 output_string[len] = '\0';
10426 } else if(strcmp(output_string,"CCMP") == 0) {
10427 len = strlen("AESEncryption");
10428 memcpy(output_string,"AESEncryption", len);
10429 output_string[len] = '\0';
10430 }
developer72fb0bb2023-01-11 09:46:29 +080010431
developera3511852023-06-14 14:12:59 +080010432 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10433 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010434}
10435
10436// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
10437INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
10438{
developera3511852023-06-14 14:12:59 +080010439 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10440 struct params params={'\0'};
10441 char output_string[32];
10442 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080010443 int res;
developer72fb0bb2023-01-11 09:46:29 +080010444
developera3511852023-06-14 14:12:59 +080010445 memset(output_string,'\0',32);
10446 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +080010447
developera3511852023-06-14 14:12:59 +080010448 if(strcmp(encMode, "TKIPEncryption") == 0)
10449 params.value = "TKIP";
10450 else if(strcmp(encMode,"AESEncryption") == 0)
10451 params.value = "CCMP";
10452 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
10453 params.value = "TKIP CCMP";
developer72fb0bb2023-01-11 09:46:29 +080010454
developera3511852023-06-14 14:12:59 +080010455 if((strcmp(output_string,"WPAand11i")==0))
10456 {
10457 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +080010458 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10459 if (os_snprintf_error(sizeof(config_file), res)) {
10460 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10461 return RETURN_ERR;
10462 }
developera3511852023-06-14 14:12:59 +080010463 wifi_hostapdWrite(config_file, &params, 1);
10464 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080010465
developera3511852023-06-14 14:12:59 +080010466 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +080010467 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10468 if (os_snprintf_error(sizeof(config_file), res)) {
10469 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10470 return RETURN_ERR;
10471 }
developera3511852023-06-14 14:12:59 +080010472 wifi_hostapdWrite(config_file, &params, 1);
10473 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080010474
developera3511852023-06-14 14:12:59 +080010475 return RETURN_OK;
10476 }
10477 else if((strcmp(output_string,"11i")==0))
10478 {
10479 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +080010480 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10481 if (os_snprintf_error(sizeof(config_file), res)) {
10482 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10483 return RETURN_ERR;
10484 }
developera3511852023-06-14 14:12:59 +080010485 wifi_hostapdWrite(config_file, &params, 1);
10486 wifi_hostapdProcessUpdate(apIndex, &params, 1);
10487 return RETURN_OK;
10488 }
10489 else if((strcmp(output_string,"WPA")==0))
10490 {
10491 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +080010492 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10493 if (os_snprintf_error(sizeof(config_file), res)) {
10494 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10495 return RETURN_ERR;
10496 }
developera3511852023-06-14 14:12:59 +080010497 wifi_hostapdWrite(config_file, &params, 1);
10498 wifi_hostapdProcessUpdate(apIndex, &params, 1);
10499 return RETURN_OK;
10500 }
developer72fb0bb2023-01-11 09:46:29 +080010501
developera3511852023-06-14 14:12:59 +080010502 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10503 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010504}
10505
10506// deletes internal security varable settings for this ap
10507INT wifi_removeApSecVaribles(INT apIndex)
10508{
developer0155a502023-06-19 20:33:57 +080010509 char config_file[MAX_BUF_SIZE] = {0};
10510 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010511 int res;
developer0155a502023-06-19 20:33:57 +080010512
10513 list.name = "wpa";
10514 list.value = "0";
10515
developer75bd10c2023-06-27 11:34:08 +080010516 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10517 if (os_snprintf_error(sizeof(config_file), res)) {
10518 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10519 return RETURN_ERR;
10520 }
developer0155a502023-06-19 20:33:57 +080010521 wifi_hostapdWrite(config_file, &list, 1);
10522
10523 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010524}
10525
10526// changes the hardware settings to disable encryption on this ap
10527INT wifi_disableApEncryption(INT apIndex)
10528{
developer0155a502023-06-19 20:33:57 +080010529 char config_file[MAX_BUF_SIZE] = {0};
10530 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010531 int res;
developer0155a502023-06-19 20:33:57 +080010532
10533 list.name = "wpa";
10534 list.value = "0";
10535
developer75bd10c2023-06-27 11:34:08 +080010536 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10537 if (os_snprintf_error(sizeof(config_file), res)) {
10538 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10539 return RETURN_ERR;
10540 }
developer0155a502023-06-19 20:33:57 +080010541 wifi_hostapdWrite(config_file, &list, 1);
10542 wifi_hostapdProcessUpdate(apIndex, &list, 1);
10543 wifi_reloadAp(apIndex);
10544
10545 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010546}
10547
10548// set the authorization mode on this ap
10549// mode mapping as: 1: open, 2: shared, 4:auto
10550INT wifi_setApAuthMode(INT apIndex, INT mode)
10551{
developera3511852023-06-14 14:12:59 +080010552 struct params params={0};
10553 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +080010554 int res;
developer72fb0bb2023-01-11 09:46:29 +080010555
developera3511852023-06-14 14:12:59 +080010556 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010557
developera3511852023-06-14 14:12:59 +080010558 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
10559 params.name = "auth_algs";
developer72fb0bb2023-01-11 09:46:29 +080010560
developere5750452023-05-15 16:46:42 +080010561 if ((mode & 1 && mode & 2) || mode & 4)
developera3511852023-06-14 14:12:59 +080010562 params.value = "3";
10563 else if (mode & 2)
10564 params.value = "2";
10565 else if (mode & 1)
10566 params.value = "1";
10567 else
10568 params.value = "0";
developer72fb0bb2023-01-11 09:46:29 +080010569
developer75bd10c2023-06-27 11:34:08 +080010570 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10571 if (os_snprintf_error(sizeof(config_file), res)) {
10572 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10573 return RETURN_ERR;
10574 }
developera3511852023-06-14 14:12:59 +080010575 wifi_hostapdWrite(config_file, &params, 1);
10576 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +080010577 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +080010578 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010579
developera3511852023-06-14 14:12:59 +080010580 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010581}
10582
10583// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
10584INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
10585{
developera3511852023-06-14 14:12:59 +080010586 //save to wifi config, and wait for wifi restart to apply
10587 struct params params={'\0'};
10588 char config_file[MAX_BUF_SIZE] = {0};
10589 int ret;
developer72fb0bb2023-01-11 09:46:29 +080010590
developera3511852023-06-14 14:12:59 +080010591 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10592 if(authMode == NULL)
10593 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010594
developera3511852023-06-14 14:12:59 +080010595 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
10596 params.name = "wpa_key_mgmt";
developer72fb0bb2023-01-11 09:46:29 +080010597
developera3511852023-06-14 14:12:59 +080010598 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
10599 params.value = "WPA-PSK";
10600 else if(strcmp(authMode,"EAPAuthentication") == 0)
10601 params.value = "WPA-EAP";
10602 else if (strcmp(authMode, "SAEAuthentication") == 0)
10603 params.value = "SAE";
10604 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
10605 params.value = "WPA-EAP-SUITE-B-192";
10606 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
10607 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
10608 else if (strcmp(authMode, "Enhanced_Open") == 0)
10609 params.value = "OWE";
10610 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
10611 return RETURN_OK; //This is taken careof in beaconType
developer72fb0bb2023-01-11 09:46:29 +080010612
developer32f2a182023-06-27 19:50:41 +080010613 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10614 if (os_snprintf_error(sizeof(config_file), ret)) {
10615 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10616 return RETURN_ERR;
10617 }
developera3511852023-06-14 14:12:59 +080010618 ret=wifi_hostapdWrite(config_file,&params,1);
10619 if(!ret)
10620 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
10621 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010622
developera3511852023-06-14 14:12:59 +080010623 return ret;
developer72fb0bb2023-01-11 09:46:29 +080010624}
10625
10626// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
10627INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
10628{
developera3511852023-06-14 14:12:59 +080010629 //save to wifi config, and wait for wifi restart to apply
10630 char BeaconType[50] = {0};
10631 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080010632 int res;
developer32f2a182023-06-27 19:50:41 +080010633 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080010634
developera3511852023-06-14 14:12:59 +080010635 *authMode = 0;
10636 wifi_getApBeaconType(apIndex,BeaconType);
10637 printf("%s____%s \n",__FUNCTION__,BeaconType);
developer72fb0bb2023-01-11 09:46:29 +080010638
developer32f2a182023-06-27 19:50:41 +080010639 if(strcmp(BeaconType,"None") == 0) {
10640 memcpy(authMode, "None", 4);
10641 authMode[4] = '\0';
10642 } else {
10643 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
developer75bd10c2023-06-27 11:34:08 +080010644 if (os_snprintf_error(sizeof(config_file), res)) {
10645 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10646 return RETURN_ERR;
10647 }
developera3511852023-06-14 14:12:59 +080010648 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
10649 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
developer32f2a182023-06-27 19:50:41 +080010650 if(strcmp(authMode,"WPA-PSK") == 0) {
10651 len = strlen("SharedAuthentication");
10652 memcpy(authMode, "SharedAuthentication", len);
10653 authMode[len] = '\0';
10654 } else if(strcmp(authMode,"WPA-EAP") == 0) {
10655 len = strlen("EAPAuthentication");
10656 memcpy(authMode, "EAPAuthentication", len);
10657 authMode[len] = '\0';
10658 }
developera3511852023-06-14 14:12:59 +080010659 }
developer72fb0bb2023-01-11 09:46:29 +080010660
developera3511852023-06-14 14:12:59 +080010661 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010662}
10663
10664// Outputs the number of stations associated per AP
10665INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
10666{
developera3511852023-06-14 14:12:59 +080010667 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080010668 char buf[128]={0};
10669 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +080010670 int res;
developer72fb0bb2023-01-11 09:46:29 +080010671
developera3511852023-06-14 14:12:59 +080010672 if(apIndex > MAX_APS)
10673 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010674
developera3511852023-06-14 14:12:59 +080010675 wifi_getApEnable(apIndex,&status);
10676 if (!status)
10677 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010678
developera3511852023-06-14 14:12:59 +080010679 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
10680 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10681 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080010682
10683 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s list_sta | wc -l", interface_name);
10684 if (res) {
10685 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080010686 }
developer8078acf2023-08-04 18:52:48 +080010687
10688
developerd14dff12023-06-28 22:47:44 +080010689 if (sscanf(buf,"%lu", output_ulong) != 1) {
10690 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
10691 return RETURN_ERR;
10692 }
developer72fb0bb2023-01-11 09:46:29 +080010693
developera3511852023-06-14 14:12:59 +080010694 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010695}
10696
10697// manually removes any active wi-fi association with the device specified on this ap
10698INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
10699{
developera3511852023-06-14 14:12:59 +080010700 char inf_name[16] = {0};
developera3511852023-06-14 14:12:59 +080010701 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080010702 int res;
developer72fb0bb2023-01-11 09:46:29 +080010703
developera3511852023-06-14 14:12:59 +080010704 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
10705 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010706
developer8078acf2023-08-04 18:52:48 +080010707 res = _syscmd_secure(buf, sizeof(buf),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
10708 if (res) {
10709 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080010710 }
developer7e4a2a62023-04-06 19:56:03 +080010711
developera3511852023-06-14 14:12:59 +080010712 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010713}
10714
10715// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
10716INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
10717{
developerc3556192023-12-06 17:59:09 +080010718 int radioIndex, bss_idx;
developer7e4a2a62023-04-06 19:56:03 +080010719
10720 if(NULL == output_int)
10721 return RETURN_ERR;
10722
developerc3556192023-12-06 17:59:09 +080010723 if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
10724 wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
developer9ce44382023-06-28 11:09:37 +080010725 return RETURN_ERR;
10726 }
developerc3556192023-12-06 17:59:09 +080010727
10728 *output_int = radioIndex;
developer7e4a2a62023-04-06 19:56:03 +080010729
10730 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010731}
10732
10733// sets the radio index for the specific ap
10734INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
10735{
developera3511852023-06-14 14:12:59 +080010736 //set to config only and wait for wifi reset to apply settings
10737 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010738}
10739
developer0155a502023-06-19 20:33:57 +080010740int mtk_get_ap_metrics(struct nl_msg *msg, void *cb)
10741{
10742 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10743 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX + 1];
developerc14d83a2023-06-29 20:09:42 +080010744 struct genlmsghdr *gnlh;
developer0155a502023-06-19 20:33:57 +080010745 wdev_ap_metric ap_metric;
10746 wdev_ap_metric *p_ap_metric = &ap_metric;
10747 int err = 0;
10748 struct mtk_nl80211_cb_data *cb_data = cb;
10749
10750 if (!msg || !cb_data) {
developerc14d83a2023-06-29 20:09:42 +080010751 wifi_debug(DEBUG_ERROR, "msgor cb_data is null,error.\n");
developer0155a502023-06-19 20:33:57 +080010752 return NL_SKIP;
10753 }
developerc14d83a2023-06-29 20:09:42 +080010754 gnlh = nlmsg_data(nlmsg_hdr(msg));
developer0155a502023-06-19 20:33:57 +080010755
10756 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10757 genlmsg_attrlen(gnlh, 0), NULL);
10758 if (err < 0) {
10759 wifi_debug(DEBUG_ERROR, "nla_parse ap_metrics nl80211 msg fails,error.\n");
10760 return err;
10761 }
10762
10763 if (tb[NL80211_ATTR_VENDOR_DATA]) {
10764 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX,
10765 tb[NL80211_ATTR_VENDOR_DATA], NULL);
10766 if (err < 0) {
10767 wifi_debug(DEBUG_ERROR, "GET_STATISTIC_MAX fails,error.\n");
10768 return err;
10769 }
10770
10771 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]) {
10772 p_ap_metric = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]);
10773 if (p_ap_metric) {
10774 memcpy(cb_data->out_buf , &p_ap_metric->cu, sizeof(unsigned char));
10775 }
10776 }
10777 }
10778
10779 return NL_OK;
10780}
10781
developer121a8e72023-05-22 09:19:39 +080010782
10783#define MAX_ACL_DUMP_LEN 4096
10784int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
10785{
10786 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10787 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
developerc14d83a2023-06-29 20:09:42 +080010788 struct genlmsghdr *gnlh;
developer121a8e72023-05-22 09:19:39 +080010789 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +080010790 int err = 0;
developer121a8e72023-05-22 09:19:39 +080010791 unsigned short acl_result_len = 0;
10792 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +080010793 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +080010794 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +080010795 return NL_SKIP;
10796 }
developerc14d83a2023-06-29 20:09:42 +080010797
10798 gnlh = nlmsg_data(nlmsg_hdr(msg));
developer121a8e72023-05-22 09:19:39 +080010799 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10800 genlmsg_attrlen(gnlh, 0), NULL);
10801 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +080010802 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +080010803 return NL_SKIP;
10804 }
developer121a8e72023-05-22 09:19:39 +080010805 if (tb[NL80211_ATTR_VENDOR_DATA]) {
10806 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
10807 tb[NL80211_ATTR_VENDOR_DATA], NULL);
10808 if (err < 0)
10809 return NL_SKIP;
10810 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
10811 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
10812 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
10813 if (acl_result_len > MAX_ACL_DUMP_LEN) {
10814 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
10815 return NL_SKIP;
10816 } else if (*(show_str + acl_result_len - 1) != '\0') {
10817 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
10818 *(show_str + acl_result_len - 1) = '\0';
10819 }
10820 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +080010821
10822 if (cb_data->out_len >= acl_result_len) {
10823 memset(cb_data->out_buf, 0, cb_data->out_len);
10824 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
10825 memmove(cb_data->out_buf, show_str, acl_result_len);
10826 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
10827 } else {
10828 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +080010829 }
developer121a8e72023-05-22 09:19:39 +080010830 } else
10831 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
10832 } else
10833 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
10834 return NL_OK;
10835}
developer72fb0bb2023-01-11 09:46:29 +080010836// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +080010837INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +080010838{
developer7e4a2a62023-04-06 19:56:03 +080010839 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +080010840 unsigned int if_idx = 0;
10841 int ret = -1;
10842 struct unl unl_ins;
10843 struct nl_msg *msg = NULL;
10844 struct nlattr * msg_data = NULL;
10845 struct mtk_nl80211_param param;
10846 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +080010847 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
10848 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +080010849 if_idx = if_nametoindex(inf_name);
10850 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +080010851 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +080010852 return RETURN_ERR;
10853 }
10854 /*init mtk nl80211 vendor cmd*/
10855 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
10856 param.if_type = NL80211_ATTR_IFINDEX;
10857 param.if_idx = if_idx;
10858
10859 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10860 if (ret) {
10861 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10862 return RETURN_ERR;
10863 }
developer121a8e72023-05-22 09:19:39 +080010864 /*add mtk vendor cmd data*/
10865 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +080010866 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +080010867 nlmsg_free(msg);
10868 goto err;
10869 }
developer72fb0bb2023-01-11 09:46:29 +080010870
developer121a8e72023-05-22 09:19:39 +080010871 /*send mtk nl80211 vendor msg*/
10872 cb_data.out_buf = macArray;
10873 cb_data.out_len = buf_size;
10874
10875 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
10876 if (ret) {
10877 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
10878 goto err;
10879 }
10880 /*deinit mtk nl80211 vendor msg*/
10881 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +080010882 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developera3511852023-06-14 14:12:59 +080010883 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +080010884err:
10885 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +080010886 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +080010887 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010888}
10889
developer2edaf012023-05-24 14:24:53 +080010890INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
10891{
10892 char *mac_arry_buf = NULL;
10893
10894 mac_arry_buf = malloc(buf_size);
10895 if (!mac_arry_buf) {
10896 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
10897 return RETURN_ERR;
10898 }
10899 memset(mac_arry_buf, 0, buf_size);
10900 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
10901 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
10902 free(mac_arry_buf);
10903 mac_arry_buf = NULL;
10904 return RETURN_ERR;
10905 }
10906 /*
10907 mtk format to wifi hal format:
10908 "policy=1
10909 00:11:22:33:44:55
10910 00:11:22:33:44:66
10911 "
10912 -->
10913 "00:11:22:33:44:55
10914 00:11:22:33:44:66
10915 "
10916 */
10917 memset(macArray, 0, buf_size);
10918 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
10919 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
10920 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
10921 }
10922 free(mac_arry_buf);
10923 mac_arry_buf = NULL;
10924 return RETURN_OK;
10925}
10926
developer72fb0bb2023-01-11 09:46:29 +080010927INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
10928{
developer72fb0bb2023-01-11 09:46:29 +080010929
developer7e4a2a62023-04-06 19:56:03 +080010930 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +080010931
developera3511852023-06-14 14:12:59 +080010932 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010933}
10934
10935
10936// Get the list of stations associated per AP
10937INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
10938{
developer7e4a2a62023-04-06 19:56:03 +080010939 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080010940 int res;
developer72fb0bb2023-01-11 09:46:29 +080010941
developer7e4a2a62023-04-06 19:56:03 +080010942 if(apIndex > 3) //Currently supporting apIndex upto 3
developera3511852023-06-14 14:12:59 +080010943 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010944
developer7e4a2a62023-04-06 19:56:03 +080010945 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080010946 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080010947
developer8078acf2023-08-04 18:52:48 +080010948 res = _syscmd_secure(macArray, buf_size, "hostapd_cli -i %s list_sta", interface_name);
10949 if (res) {
10950 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
10951 }
10952
developer7e4a2a62023-04-06 19:56:03 +080010953 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010954}
10955
developer8dd72532023-05-17 19:58:35 +080010956int hex2num(char c)
10957{
10958 if (c >= '0' && c <= '9')
10959 return c - '0';
10960 if (c >= 'a' && c <= 'f')
10961 return c - 'a' + 10;
10962 if (c >= 'A' && c <= 'F')
10963 return c - 'A' + 10;
10964 return -1;
10965}
10966
10967/**
10968 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
10969 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
10970 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
10971 * Returns: Characters used (> 0) on success, -1 on failure
10972 */
10973int hwaddr_aton2(const char *txt, unsigned char *addr)
10974{
10975 int i;
10976 const char *pos = txt;
10977
10978 for (i = 0; i < 6; i++) {
10979 int a, b;
10980
10981 while (*pos == ':' || *pos == '.' || *pos == '-')
10982 pos++;
10983
10984 a = hex2num(*pos++);
10985 if (a < 0)
10986 return -1;
10987 b = hex2num(*pos++);
10988 if (b < 0)
10989 return -1;
10990 *addr++ = (a << 4) | b;
10991 }
10992
10993 return pos - txt;
10994}
10995
developer72fb0bb2023-01-11 09:46:29 +080010996// adds the mac address to the filter list
10997//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
10998INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
10999{
developer7e4a2a62023-04-06 19:56:03 +080011000 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +080011001 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +080011002 struct nl_msg *msg = NULL;
11003 struct nlattr * msg_data = NULL;
11004 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +080011005 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
11006 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +080011007 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
11008 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080011009 if (!DeviceMacAddress)
11010 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +080011011 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +080011012 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +080011013 return RETURN_ERR;
11014 }
developer8dd72532023-05-17 19:58:35 +080011015 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +080011016 if (!if_idx) {
11017 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
11018 return RETURN_ERR;
11019 }
developer49b17232023-05-19 16:35:19 +080011020 /*init mtk nl80211 vendor cmd*/
11021 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
11022 param.if_type = NL80211_ATTR_IFINDEX;
11023 param.if_idx = if_idx;
11024 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11025 if (ret) {
11026 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +080011027 return RETURN_ERR;
11028 }
developer49b17232023-05-19 16:35:19 +080011029 /*add mtk vendor cmd data*/
11030 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +080011031 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +080011032 nlmsg_free(msg);
11033 goto err;
11034 }
developer49b17232023-05-19 16:35:19 +080011035 /*send mtk nl80211 vendor msg*/
11036 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11037 if (ret) {
11038 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +080011039 goto err;
11040 }
developer49b17232023-05-19 16:35:19 +080011041 /*deinit mtk nl80211 vendor msg*/
11042 mtk_nl80211_deint(&unl_ins);
11043 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +080011044 return RETURN_OK;
11045err:
developer49b17232023-05-19 16:35:19 +080011046 mtk_nl80211_deint(&unl_ins);
11047 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +080011048 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011049}
11050
11051// deletes the mac address from the filter list
11052//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
11053INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
11054{
developer2edaf012023-05-24 14:24:53 +080011055 struct unl unl_ins;
11056 int if_idx = 0, ret = 0;
11057 struct nl_msg *msg = NULL;
11058 struct nlattr * msg_data = NULL;
11059 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +080011060 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080011061 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011062
developer7e4a2a62023-04-06 19:56:03 +080011063 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
11064 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011065
developer7e4a2a62023-04-06 19:56:03 +080011066 if (!DeviceMacAddress)
11067 return RETURN_ERR;
11068
developer2edaf012023-05-24 14:24:53 +080011069 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
11070 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
11071 return RETURN_ERR;
11072 }
developer72fb0bb2023-01-11 09:46:29 +080011073
developer2edaf012023-05-24 14:24:53 +080011074 if_idx = if_nametoindex(inf_name);
11075 if (!if_idx) {
11076 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
11077 return RETURN_ERR;
11078 }
11079 /*init mtk nl80211 vendor cmd*/
11080 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
11081 param.if_type = NL80211_ATTR_IFINDEX;
11082 param.if_idx = if_idx;
11083 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11084 if (ret) {
11085 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11086 return RETURN_ERR;
11087 }
11088 /*add mtk vendor cmd data*/
11089 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
11090 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11091 nlmsg_free(msg);
11092 goto err;
11093 }
11094 /*send mtk nl80211 vendor msg*/
11095 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11096 if (ret) {
11097 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
11098 goto err;
11099 }
11100 /*deinit mtk nl80211 vendor msg*/
11101 mtk_nl80211_deint(&unl_ins);
11102 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
11103 return RETURN_OK;
11104err:
11105 mtk_nl80211_deint(&unl_ins);
11106 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11107 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011108}
11109
11110// outputs the number of devices in the filter list
11111INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
11112{
developer2edaf012023-05-24 14:24:53 +080011113 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
11114 UINT buf_size = 1024;
11115 UINT sta_num = 0;
11116 unsigned char mac[ETH_ALEN] = {0};
developera3511852023-06-14 14:12:59 +080011117 if(output_uint == NULL)
developerdaf24792023-06-06 11:40:04 +080011118 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011119
developer2edaf012023-05-24 14:24:53 +080011120 mac_arry = (char *)malloc(buf_size);
11121 if (mac_arry == NULL) {
11122 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +080011123 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011124 }
developerdaf24792023-06-06 11:40:04 +080011125 memset(mac_arry, 0, buf_size);
developer2edaf012023-05-24 14:24:53 +080011126 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
11127 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
11128 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
developer9ce44382023-06-28 11:09:37 +080011129 free(mac_arry);
developer2edaf012023-05-24 14:24:53 +080011130 return RETURN_ERR;
11131 }
11132 /*count the acl str nums:*/
11133 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +080011134
developer2edaf012023-05-24 14:24:53 +080011135 /*mac addr string format:
11136 exp1: 00:11:22:33:44:55\0
11137 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
11138 */
11139 ptr = mac_arry;
11140 while (sscanf(ptr, "%17s", mac_str) == 1) {
11141 if (hwaddr_aton2(mac_str, mac) >= 0)
11142 sta_num++;
11143 ptr = strstr(ptr, mac_str) + strlen(mac_str);
11144 }
11145 *output_uint = sta_num;
11146 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
11147 free(mac_arry);
11148 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +080011149 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011150}
11151
11152INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
11153{
developer75bd10c2023-06-27 11:34:08 +080011154 int res;
developer72fb0bb2023-01-11 09:46:29 +080011155
developera3511852023-06-14 14:12:59 +080011156 if(strcmp(action,"DENY")==0)
11157 {
developer33f13ba2023-07-12 16:19:06 +080011158 res = v_secure_system("iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",
developer32f2a182023-06-27 19:50:41 +080011159 apIndex, interface, client_mac);
developer33f13ba2023-07-12 16:19:06 +080011160 if (res) {
11161 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developer75bd10c2023-06-27 11:34:08 +080011162 return RETURN_ERR;
11163 }
developera3511852023-06-14 14:12:59 +080011164 return RETURN_OK;
11165 }
developer72fb0bb2023-01-11 09:46:29 +080011166
developera3511852023-06-14 14:12:59 +080011167 if(strcmp(action,"ALLOW")==0)
11168 {
developer33f13ba2023-07-12 16:19:06 +080011169 res = v_secure_system("iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",
developer32f2a182023-06-27 19:50:41 +080011170 apIndex, interface, client_mac);
developer33f13ba2023-07-12 16:19:06 +080011171 if (res) {
11172 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developer75bd10c2023-06-27 11:34:08 +080011173 return RETURN_ERR;
11174 }
developera3511852023-06-14 14:12:59 +080011175 return RETURN_OK;
11176 }
developer72fb0bb2023-01-11 09:46:29 +080011177
developera3511852023-06-14 14:12:59 +080011178 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011179
11180}
11181
11182// enable kick for devices on acl black list
11183INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
11184{
developera3511852023-06-14 14:12:59 +080011185 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
11186 char assocArray[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011187
developera3511852023-06-14 14:12:59 +080011188 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
11189 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
developer72fb0bb2023-01-11 09:46:29 +080011190
developera3511852023-06-14 14:12:59 +080011191 /* if there are no devices connected there is nothing to do */
11192 if (strlen(assocArray) < 17)
11193 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011194
developera3511852023-06-14 14:12:59 +080011195 if (enable == TRUE) {
11196 /* kick off the MAC which is in ACL array (deny list) */
11197 acl = strtok(aclArray, "\n");
11198 while (acl != NULL) {
11199 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
11200 wifi_kickApAssociatedDevice(apIndex, acl);
developer72fb0bb2023-01-11 09:46:29 +080011201
developera3511852023-06-14 14:12:59 +080011202 acl = strtok(NULL, "\n");
11203 }
developer72fb0bb2023-01-11 09:46:29 +080011204 wifi_setApMacAddressControlMode(apIndex, 2);
developera3511852023-06-14 14:12:59 +080011205 } else
developer72fb0bb2023-01-11 09:46:29 +080011206 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +080011207
developera3511852023-06-14 14:12:59 +080011208 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011209}
11210
11211INT wifi_setPreferPrivateConnection(BOOL enable)
11212{
developera3511852023-06-14 14:12:59 +080011213 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011214}
11215
11216// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
11217INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
11218{
developer2edaf012023-05-24 14:24:53 +080011219 int if_idx = 0, ret = 0;
11220 struct unl unl_ins;
11221 struct nl_msg *msg = NULL;
11222 struct nlattr * msg_data = NULL;
11223 struct mtk_nl80211_param param;
11224 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +080011225 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011226
developer7e4a2a62023-04-06 19:56:03 +080011227 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
11228 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011229 if_idx = if_nametoindex(inf_name);
11230 if (!if_idx) {
11231 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
11232 return RETURN_ERR;
11233 }
11234 /*init mtk nl80211 vendor cmd*/
11235 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
11236 param.if_type = NL80211_ATTR_IFINDEX;
11237 param.if_idx = if_idx;
11238 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11239 if (ret) {
11240 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11241 return RETURN_ERR;
11242 }
11243 /*add mtk vendor cmd data*/
11244 if (filterMode == 0) {
11245 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
11246 } else if (filterMode == 1) {
11247 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
11248 } else if (filterMode == 2) {
11249 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
11250 } else {
11251 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
11252 nlmsg_free(msg);
11253 goto err;
11254 }
11255 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
11256 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11257 nlmsg_free(msg);
11258 goto err;
11259 }
11260 /*send mtk nl80211 vendor msg*/
11261 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11262 if (ret) {
11263 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
11264 goto err;
11265 }
11266 /*deinit mtk nl80211 vendor msg*/
11267 mtk_nl80211_deint(&unl_ins);
11268 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +080011269 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +080011270err:
11271 mtk_nl80211_deint(&unl_ins);
11272 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11273 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011274}
11275
11276// 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.
11277INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
11278{
developera3511852023-06-14 14:12:59 +080011279 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011280}
11281
11282// gets the vlan ID for this ap from an internal enviornment variable
11283INT wifi_getApVlanID(INT apIndex, INT *output_int)
11284{
developera3511852023-06-14 14:12:59 +080011285 if(apIndex==0)
11286 {
11287 *output_int=100;
11288 return RETURN_OK;
11289 }
developer72fb0bb2023-01-11 09:46:29 +080011290
developera3511852023-06-14 14:12:59 +080011291 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011292}
11293
11294// sets the vlan ID for this ap to an internal enviornment variable
11295INT wifi_setApVlanID(INT apIndex, INT vlanId)
11296{
developera3511852023-06-14 14:12:59 +080011297 //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 +080011298 char interface_name[16] = {0};
11299 int if_idx, ret = 0;
11300 struct nl_msg *msg = NULL;
11301 struct nlattr * msg_data = NULL;
11302 struct mtk_nl80211_param param;
11303 struct unl unl_ins;
11304
11305 if (apIndex > MAX_APS) {
11306 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
11307 return RETURN_ERR;
11308 }
11309 if (vlanId > 4095 || vlanId < 1) {
11310 wifi_debug(DEBUG_ERROR, "Invalid vlanId %d\n", vlanId);
11311 return RETURN_ERR;
11312 }
11313 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11314 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11315 return RETURN_ERR;
11316 /*step 1. mwctl dev %s set vlan_tag 0*/
11317 if_idx = if_nametoindex(interface_name);
11318 /*init mtk nl80211 vendor cmd*/
11319 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
11320 param.if_type = NL80211_ATTR_IFINDEX;
11321 param.if_idx = if_idx;
11322 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11323 if (ret) {
11324 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11325 return RETURN_ERR;
11326 }
11327 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, vlanId)) {
11328 printf("Nla put attribute error\n");
11329 nlmsg_free(msg);
11330 goto err;
11331 }
11332 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11333 if (ret) {
11334 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11335 goto err;
11336 }
11337 mtk_nl80211_deint(&unl_ins);
11338 //wifi_debug(DEBUG_NOTICE, "set vlanId cmd success.\n", vlanId);
11339 printf("set vlanId=%d cmd success.\n", vlanId);
11340 return RETURN_OK;
11341err:
11342 mtk_nl80211_deint(&unl_ins);
11343 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +080011344 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011345}
11346
developercc5cbfb2023-06-13 18:29:52 +080011347char br_name[IFNAMSIZ] = "brlan0";
11348
developer72fb0bb2023-01-11 09:46:29 +080011349// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
11350INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
11351{
developercc5cbfb2023-06-13 18:29:52 +080011352 int sock = socket(AF_INET, SOCK_DGRAM, 0);
11353 struct ifreq ifr;
11354 struct sockaddr_in *sin;
11355
11356 memcpy(bridgeName, br_name, strlen(br_name));
11357
11358 if (sock == -1) {
11359 wifi_debug(DEBUG_ERROR, "socket failed");
11360 return RETURN_ERR;
11361 }
11362
developerd14dff12023-06-28 22:47:44 +080011363 strncpy(ifr.ifr_name, br_name, strlen(br_name));
developercc5cbfb2023-06-13 18:29:52 +080011364 ifr.ifr_addr.sa_family = AF_INET;
11365 if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
11366 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFADDR) failed, %s, bridge_name=%s\n",
11367 strerror(errno), br_name);
developer9ce44382023-06-28 11:09:37 +080011368 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011369 return RETURN_ERR;
11370 }
11371
11372 sin = (struct sockaddr_in *)&ifr.ifr_addr;
11373 wifi_debug(DEBUG_ERROR, "Bridge device %s has IP address: %s\n", br_name, inet_ntoa(sin->sin_addr));
11374 memcpy(IP, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
11375
11376 if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0) {
11377 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFNETMASK) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011378 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011379 return RETURN_ERR;
11380 }
11381
11382 wifi_debug(DEBUG_ERROR, "Bridge device %s has subnet mask: %s\n", br_name, inet_ntoa(sin->sin_addr));
11383 memcpy(subnet, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
11384 close(sock);
developer72fb0bb2023-01-11 09:46:29 +080011385
developera3511852023-06-14 14:12:59 +080011386 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011387}
11388
11389//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
11390INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
11391{
developera3511852023-06-14 14:12:59 +080011392 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
developercc5cbfb2023-06-13 18:29:52 +080011393 struct ifreq ifr;
11394 struct sockaddr_in sin;
11395 int sock = socket(AF_INET, SOCK_DGRAM, 0);
11396
developerc14d83a2023-06-29 20:09:42 +080011397 if(sock < 0) {
11398 wifi_debug(DEBUG_ERROR, "sock init fail\n");
11399 return RETURN_ERR;
11400 }
developer5b23cd02023-07-19 20:26:03 +080011401
developercc5cbfb2023-06-13 18:29:52 +080011402 if (strlen(bridgeName) >= IFNAMSIZ) {
11403 wifi_debug(DEBUG_ERROR, "invalide bridgeName length=%ld\n", strlen(bridgeName));
developer9ce44382023-06-28 11:09:37 +080011404 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011405 return RETURN_ERR;
11406 }
11407
11408 if (strlen(br_name) >= IFNAMSIZ) {
11409 wifi_debug(DEBUG_ERROR, "invalide br_name length=%ld in strorage\n", strlen(br_name));
developer9ce44382023-06-28 11:09:37 +080011410 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011411 return RETURN_ERR;
11412 }
11413
11414 if (sock == -1) {
developera3511852023-06-14 14:12:59 +080011415 wifi_debug(DEBUG_ERROR, "socket failed");
developercc5cbfb2023-06-13 18:29:52 +080011416 return RETURN_ERR;
11417 }
11418
11419 memset(&ifr, 0, sizeof(ifr));
11420 strncpy(ifr.ifr_name, br_name, strlen(br_name));
11421 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
11422 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011423 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011424 return RETURN_ERR;
11425 }
11426
11427 ifr.ifr_flags = (short)(ifr.ifr_flags & ~IFF_UP);
11428 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
11429 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011430 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011431 return RETURN_ERR;
11432 }
11433
11434 memset(&ifr, 0, sizeof(ifr));
11435 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
developerd14dff12023-06-28 22:47:44 +080011436 strncpy(ifr.ifr_newname, bridgeName, strlen(bridgeName));
developercc5cbfb2023-06-13 18:29:52 +080011437 if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
11438 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNAME) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011439 close(sock);
developera3511852023-06-14 14:12:59 +080011440 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +080011441 }
11442
11443 memset(br_name, 0, sizeof(br_name));
11444 memcpy(br_name, bridgeName, strlen(bridgeName));
11445
11446 memset(&ifr, 0, sizeof(ifr));
11447 strncpy(ifr.ifr_name, bridgeName, IFNAMSIZ);
11448 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
11449 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011450 close(sock);
developera3511852023-06-14 14:12:59 +080011451 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +080011452 }
11453 ifr.ifr_flags = (short)(ifr.ifr_flags | IFF_UP);
11454 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
11455 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011456 close(sock);
developera3511852023-06-14 14:12:59 +080011457 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +080011458 }
11459
11460 memset(&ifr, 0, sizeof(ifr));
11461 memcpy(ifr.ifr_name, bridgeName, strlen(bridgeName));
11462
11463 memset(&sin, 0, sizeof(struct sockaddr_in));
11464 sin.sin_family = AF_INET;
11465 if (inet_aton(IP, &(sin.sin_addr)) == 0) {
11466 wifi_debug(DEBUG_ERROR, "inet_aton failed");
developer9ce44382023-06-28 11:09:37 +080011467 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011468 return RETURN_ERR;
11469 }
11470 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in));
11471 if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
11472 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFADDR) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +080011473 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011474 return RETURN_ERR;
11475 }
11476
11477 if (inet_aton(subnet, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr) == 0) {
11478 wifi_debug(DEBUG_ERROR, "inet_aton failed");
developerc14d83a2023-06-29 20:09:42 +080011479 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011480 return RETURN_ERR;
11481 }
11482 if (ioctl(sock, SIOCSIFNETMASK, &ifr) < -1) {
11483 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNETMASK) failed, %s", strerror(errno));
developerc14d83a2023-06-29 20:09:42 +080011484 close(sock);
developercc5cbfb2023-06-13 18:29:52 +080011485 return RETURN_ERR;
11486 }
11487
11488 close(sock);
developera3511852023-06-14 14:12:59 +080011489 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011490}
11491
11492// reset the vlan configuration for this ap
11493INT wifi_resetApVlanCfg(INT apIndex)
11494{
developera1255e42023-05-13 17:45:02 +080011495 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +080011496 int if_idx, ret = 0;
11497 struct nl_msg *msg = NULL;
11498 struct nlattr * msg_data = NULL;
11499 struct mtk_nl80211_param param;
11500 struct unl unl_ins;
11501 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +080011502
developer2202b332023-05-24 16:23:22 +080011503 if (apIndex > MAX_APS) {
11504 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
11505 return RETURN_ERR;
11506 }
developer72fb0bb2023-01-11 09:46:29 +080011507
developer2202b332023-05-24 16:23:22 +080011508 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11509 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11510 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011511
developer2202b332023-05-24 16:23:22 +080011512 /*step 1. mwctl dev %s set vlan_tag 0*/
11513 if_idx = if_nametoindex(interface_name);
11514 /*init mtk nl80211 vendor cmd*/
11515 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
11516 param.if_type = NL80211_ATTR_IFINDEX;
11517 param.if_idx = if_idx;
11518 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +080011519
developer2202b332023-05-24 16:23:22 +080011520 if (ret) {
11521 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11522 return RETURN_ERR;
11523 }
developer72fb0bb2023-01-11 09:46:29 +080011524
developer2202b332023-05-24 16:23:22 +080011525 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
11526 printf("Nla put attribute error\n");
11527 nlmsg_free(msg);
11528 goto err;
11529 }
developer72fb0bb2023-01-11 09:46:29 +080011530
developer2202b332023-05-24 16:23:22 +080011531 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11532 if (ret) {
11533 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11534 goto err;
11535 }
11536 mtk_nl80211_deint(&unl_ins);
11537 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +080011538
developer2202b332023-05-24 16:23:22 +080011539 /*step 2. mwctl dev %s set vlan_priority 0*/
11540 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11541 if (ret) {
11542 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11543 return RETURN_ERR;
11544 }
developer72fb0bb2023-01-11 09:46:29 +080011545
developer2202b332023-05-24 16:23:22 +080011546 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
11547 printf("Nla put attribute error\n");
11548 nlmsg_free(msg);
11549 goto err;
11550 }
developer72fb0bb2023-01-11 09:46:29 +080011551
developer2202b332023-05-24 16:23:22 +080011552 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11553 if (ret) {
11554 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11555 goto err;
11556 }
11557 mtk_nl80211_deint(&unl_ins);
11558 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
11559
11560 /*step 3. mwctl dev %s set vlan_id 0*/
11561 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11562 if (ret) {
11563 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +080011564 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +080011565 }
developer72fb0bb2023-01-11 09:46:29 +080011566
developer2202b332023-05-24 16:23:22 +080011567 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
11568 printf("Nla put attribute error\n");
11569 nlmsg_free(msg);
11570 goto err;
11571 }
11572
11573 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11574 if (ret) {
11575 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11576 goto err;
11577 }
11578 mtk_nl80211_deint(&unl_ins);
11579 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
11580
11581 /*step 4. mwctl dev %s set vlan_en 0*/
11582 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11583 if (ret) {
11584 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11585 return RETURN_ERR;
11586 }
11587
11588 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
11589 printf("Nla put attribute error\n");
11590 nlmsg_free(msg);
11591 goto err;
11592 }
11593
11594 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11595 if (ret) {
11596 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11597 goto err;
11598 }
11599 mtk_nl80211_deint(&unl_ins);
11600 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
11601
11602 /*step 5. mwctl dev %s set vlan_policy 0:4*/
11603 vlan_param.direction = 0;
11604 vlan_param.policy = 4;
11605 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11606 if (ret) {
11607 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11608 return RETURN_ERR;
11609 }
11610 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
11611 printf("Nla put attribute error\n");
11612 nlmsg_free(msg);
11613 goto err;
11614 }
11615
11616 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11617 if (ret) {
11618 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11619 goto err;
11620 }
11621 mtk_nl80211_deint(&unl_ins);
11622 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
11623
11624 /*step 6. mwctl dev %s set vlan_policy 1:0*/
11625 vlan_param.direction = 1;
11626 vlan_param.policy = 0;
11627 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11628 if (ret) {
11629 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11630 return RETURN_ERR;
11631 }
11632
11633 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
11634 printf("Nla put attribute error\n");
11635 nlmsg_free(msg);
11636 goto err;
11637 }
11638
11639 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11640 if (ret) {
11641 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11642 goto err;
11643 }
11644 /*deinit mtk nl80211 vendor msg*/
11645 mtk_nl80211_deint(&unl_ins);
11646 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
11647
11648 /*TODO need to modify VLAN config in dat file*/
11649 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11650
11651 return RETURN_OK;
11652err:
11653 mtk_nl80211_deint(&unl_ins);
11654 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11655 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011656}
11657
11658// 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.
11659INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
11660{
developera3511852023-06-14 14:12:59 +080011661 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011662}
11663
11664// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
11665INT wifi_startHostApd()
11666{
developera3511852023-06-14 14:12:59 +080011667 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer33f13ba2023-07-12 16:19:06 +080011668 v_secure_system("systemctl start hostapd.service");
developera3511852023-06-14 14:12:59 +080011669 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11670 return RETURN_OK;
11671 //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 +080011672}
11673
11674// stops hostapd
developer69b61b02023-03-07 17:17:44 +080011675INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +080011676{
developera3511852023-06-14 14:12:59 +080011677 char buf[128] = {0};
developer75bd10c2023-06-27 11:34:08 +080011678 int res;
developer72fb0bb2023-01-11 09:46:29 +080011679
developer8078acf2023-08-04 18:52:48 +080011680 res = _syscmd_secure(buf, sizeof(buf), "systemctl stop hostapd");
11681 if (res) {
11682 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080011683 }
developer72fb0bb2023-01-11 09:46:29 +080011684
developera3511852023-06-14 14:12:59 +080011685 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011686}
11687
11688// restart hostapd dummy function
11689INT wifi_restartHostApd()
11690{
developera3511852023-06-14 14:12:59 +080011691 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer33f13ba2023-07-12 16:19:06 +080011692 v_secure_system("systemctl restart hostapd-global");
developera3511852023-06-14 14:12:59 +080011693 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011694
developera3511852023-06-14 14:12:59 +080011695 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011696}
11697
11698// sets the AP enable status variable for the specified ap.
11699INT wifi_setApEnable(INT apIndex, BOOL enable)
11700{
developer7e4a2a62023-04-06 19:56:03 +080011701 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080011702 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer8078acf2023-08-04 18:52:48 +080011703
developer7e4a2a62023-04-06 19:56:03 +080011704 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +080011705 BOOL status = FALSE;
developerc3556192023-12-06 17:59:09 +080011706 int radioIndex, bss_idx;
developer7e4a2a62023-04-06 19:56:03 +080011707 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080011708 int res;
developer72fb0bb2023-01-11 09:46:29 +080011709
developer7e4a2a62023-04-06 19:56:03 +080011710 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +080011711
developer7e4a2a62023-04-06 19:56:03 +080011712 if (enable == status)
11713 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011714
developer7e4a2a62023-04-06 19:56:03 +080011715 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11716 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011717
developer7e4a2a62023-04-06 19:56:03 +080011718 if (enable == TRUE) {
developerc3556192023-12-06 17:59:09 +080011719 if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
11720 wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
11721 return RETURN_ERR;
11722 }
developer7e4a2a62023-04-06 19:56:03 +080011723 phyId = radio_index_to_phy(radioIndex);
developer8078acf2023-08-04 18:52:48 +080011724
11725 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up", interface_name);
11726 if (res) {
11727 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080011728 }
developer8a3bbbf2023-03-15 17:47:23 +080011729
developere40952c2023-06-15 18:46:43 +080011730 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
11731 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
11732 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11733 return RETURN_ERR;
11734 }
developer8078acf2023-08-04 18:52:48 +080011735 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
11736 if (res) {
11737 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080011738 }
developer7e4a2a62023-04-06 19:56:03 +080011739 } else {
developer9635f402023-12-25 19:48:21 +080011740 /*Do not REMOVE main interfaces in hostapd*/
11741 if (!is_main_vap_index(apIndex)) {
developer136e4642023-11-29 10:41:32 +080011742 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
11743 if (res) {
11744 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
11745 }
11746 } else {
11747 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
11748 if (res) {
11749 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
11750 }
developere40952c2023-06-15 18:46:43 +080011751 }
developer7e4a2a62023-04-06 19:56:03 +080011752 }
developer8078acf2023-08-04 18:52:48 +080011753 res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer7e4a2a62023-04-06 19:56:03 +080011754 interface_name, interface_name, enable, VAP_STATUS_FILE);
developer8078acf2023-08-04 18:52:48 +080011755 if (res) {
11756 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080011757 }
developer7e4a2a62023-04-06 19:56:03 +080011758 //Wait for wifi up/down to apply
11759 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011760}
11761
11762// Outputs the setting of the internal variable that is set by wifi_setApEnable().
11763INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
11764{
developer7e4a2a62023-04-06 19:56:03 +080011765 char interface_name[IF_NAME_SIZE] = {0};
developerc1aa6532023-06-09 09:37:01 +080011766 char buf[MAX_BUF_SIZE] = {0};
developerc338aba2023-08-09 13:56:42 +080011767 int res, len;
11768 char ctrl_interface[64] = {0};
11769 char config_file[128] = {0};
developer136e4642023-11-29 10:41:32 +080011770 BOOL is_ap_enable, hostapd_state;
developer72fb0bb2023-01-11 09:46:29 +080011771
developer7e4a2a62023-04-06 19:56:03 +080011772 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
11773 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011774
developer7e4a2a62023-04-06 19:56:03 +080011775 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +080011776
developer7e4a2a62023-04-06 19:56:03 +080011777 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
11778 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
11779 *output_bool = FALSE;
11780 return RETURN_OK;
11781 }
developerc338aba2023-08-09 13:56:42 +080011782 if (strlen(interface_name) == 0)
11783 return RETURN_ERR;
11784
11785 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11786 if (os_snprintf_error(sizeof(config_file), res)) {
11787 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11788 return RETURN_ERR;
11789 }
11790 if (wifi_hostapdRead(config_file, "ctrl_interface", ctrl_interface, sizeof(ctrl_interface))) {
11791 wifi_debug(DEBUG_ERROR, "ctrl_interface for %s not exist\n", interface_name);
11792 }
11793
11794 _syscmd_secure(buf, sizeof(buf), "ls %s | grep %s",
11795 strlen(ctrl_interface) == 0 ? "/var/run/hostapd/" : ctrl_interface, interface_name);
11796 len = strlen(buf) >= strlen(interface_name) ? strlen(interface_name) : strlen(buf);
11797
11798 if (len == 0 || strncmp(buf, interface_name, len)) {
11799 return RETURN_OK;
11800 }
11801 memset(buf, 0, sizeof(buf));
developerc1aa6532023-06-09 09:37:01 +080011802
developer8078acf2023-08-04 18:52:48 +080011803 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
11804 if (res) {
11805 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080011806 }
developerc1aa6532023-06-09 09:37:01 +080011807
developer136e4642023-11-29 10:41:32 +080011808 if (strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 ||
11809 strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) {
11810 hostapd_state = TRUE;
developerc1aa6532023-06-09 09:37:01 +080011811 }
developer136e4642023-11-29 10:41:32 +080011812
11813 is_ap_enable = _syscmd_secure(buf, sizeof(buf), "ifconfig %s | grep UP", interface_name) ? FALSE : TRUE;
11814
11815 if (hostapd_state && is_ap_enable)
11816 *output_bool = TRUE;
developer7e4a2a62023-04-06 19:56:03 +080011817 }
developer72fb0bb2023-01-11 09:46:29 +080011818
developer7e4a2a62023-04-06 19:56:03 +080011819 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011820}
11821
developer69b61b02023-03-07 17:17:44 +080011822// Outputs the AP "Enabled" "Disabled" status from driver
11823INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +080011824{
developer9ce44382023-06-28 11:09:37 +080011825 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +080011826 int res;
developer72fb0bb2023-01-11 09:46:29 +080011827
developer7e4a2a62023-04-06 19:56:03 +080011828 if (!output_string) {
11829 printf("%s: null pointer!", __func__);
11830 return RETURN_ERR;
11831 }
developer72fb0bb2023-01-11 09:46:29 +080011832
developer7e4a2a62023-04-06 19:56:03 +080011833 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +080011834
developer7e4a2a62023-04-06 19:56:03 +080011835 if(output_bool == 1)
developere40952c2023-06-15 18:46:43 +080011836 res = snprintf(output_string, 32, "Up");
developer7e4a2a62023-04-06 19:56:03 +080011837 else
developere40952c2023-06-15 18:46:43 +080011838 res = snprintf(output_string, 32, "Disable");
11839 if (os_snprintf_error(32, res)) {
11840 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11841 return RETURN_ERR;
11842 }
developer7e4a2a62023-04-06 19:56:03 +080011843
11844 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011845}
11846
11847//Indicates whether or not beacons include the SSID name.
11848// outputs a 1 if SSID on the AP is enabled, else outputs 0
11849INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
11850{
developera3511852023-06-14 14:12:59 +080011851 //get the running status
11852 char config_file[MAX_BUF_SIZE] = {0};
11853 char buf[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080011854 int res;
developer72fb0bb2023-01-11 09:46:29 +080011855
developera3511852023-06-14 14:12:59 +080011856 if (!output)
11857 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011858
developer32f2a182023-06-27 19:50:41 +080011859 res = snprintf(config_file, sizeof(config_file),
11860 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080011861 if (os_snprintf_error(sizeof(config_file), res)) {
11862 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11863 return RETURN_ERR;
11864 }
developera3511852023-06-14 14:12:59 +080011865 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
11866 // default is enable
11867 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
11868 *output = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080011869
developera3511852023-06-14 14:12:59 +080011870 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011871}
11872
11873// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
11874INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
11875{
developera3511852023-06-14 14:12:59 +080011876 //store the config, apply instantly
11877 char config_file[MAX_BUF_SIZE] = {0};
11878 struct params list;
developer75bd10c2023-06-27 11:34:08 +080011879 int res;
developer72fb0bb2023-01-11 09:46:29 +080011880
developera3511852023-06-14 14:12:59 +080011881 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11882 list.name = "ignore_broadcast_ssid";
11883 list.value = enable?"0":"1";
developer72fb0bb2023-01-11 09:46:29 +080011884
developer32f2a182023-06-27 19:50:41 +080011885 res = snprintf(config_file, sizeof(config_file),
11886 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080011887 if (os_snprintf_error(sizeof(config_file), res)) {
11888 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11889 return RETURN_ERR;
11890 }
developera3511852023-06-14 14:12:59 +080011891 wifi_hostapdWrite(config_file, &list, 1);
11892 wifi_hostapdProcessUpdate(apIndex, &list, 1);
11893 //TODO: call hostapd_cli for dynamic_config_control
11894 wifi_reloadAp(apIndex);
11895 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011896
developera3511852023-06-14 14:12:59 +080011897 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011898}
11899
11900//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
11901INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
11902{
developer47cc27a2023-05-17 23:09:58 +080011903 /* get the running status */
11904 if(!output_uint)
developera3511852023-06-14 14:12:59 +080011905 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +080011906
11907 *output_uint = 15;
11908 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011909}
11910
developer47cc27a2023-05-17 23:09:58 +080011911/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +080011912INT wifi_setApRetryLimit(INT apIndex, UINT number)
11913{
developer47cc27a2023-05-17 23:09:58 +080011914 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011915}
11916
developer95c045d2023-05-24 19:26:28 +080011917int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
11918{
11919 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11920 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
11921 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developer2f79c922023-06-02 17:33:42 +080011922 unsigned char *status = (unsigned char *)data;
developer95c045d2023-05-24 19:26:28 +080011923 int err = 0;
developer95c045d2023-05-24 19:26:28 +080011924
11925 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11926 genlmsg_attrlen(gnlh, 0), NULL);
11927 if (err < 0)
11928 return err;
11929
11930 if (tb[NL80211_ATTR_VENDOR_DATA]) {
11931 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
11932 tb[NL80211_ATTR_VENDOR_DATA], NULL);
11933 if (err < 0)
11934 return err;
11935
11936 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
developer95c045d2023-05-24 19:26:28 +080011937 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
11938 }
11939 }
11940
11941 return 0;
11942}
11943
developer72fb0bb2023-01-11 09:46:29 +080011944//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
11945INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
11946{
developer95c045d2023-05-24 19:26:28 +080011947 int if_idx, ret = 0;
developera3511852023-06-14 14:12:59 +080011948 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080011949 unsigned char status = 0;
11950 struct nl_msg *msg = NULL;
11951 struct nlattr * msg_data = NULL;
11952 struct mtk_nl80211_param param;
11953 struct unl unl_ins;
developer8e6583c2023-05-23 13:36:06 +080011954
developera3511852023-06-14 14:12:59 +080011955 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11956 if(!output)
developerdaf24792023-06-06 11:40:04 +080011957 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080011958
developer95c045d2023-05-24 19:26:28 +080011959 if (apIndex > MAX_APS) {
11960 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
11961 return RETURN_ERR;
11962 }
11963
developera3511852023-06-14 14:12:59 +080011964 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developerdaf24792023-06-06 11:40:04 +080011965 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +080011966
11967 if_idx = if_nametoindex(interface_name);
11968 /*init mtk nl80211 vendor cmd*/
11969 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
11970 param.if_type = NL80211_ATTR_IFINDEX;
11971 param.if_idx = if_idx;
11972 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11973
11974 if (ret) {
11975 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11976 return RETURN_ERR;
11977 }
11978
11979 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
11980 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11981 nlmsg_free(msg);
11982 goto err;
11983 }
11984
11985 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
11986 (void *)&status);
11987 if (ret) {
11988 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
11989 goto err;
11990 }
11991 mtk_nl80211_deint(&unl_ins);
11992
11993 *output = status == 0 ? FALSE : TRUE;
11994 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +080011995
developera3511852023-06-14 14:12:59 +080011996 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11997 return RETURN_OK;
11998err:
developer95c045d2023-05-24 19:26:28 +080011999 mtk_nl80211_deint(&unl_ins);
12000 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12001 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012002}
12003
12004//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
12005INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
12006{
developera3511852023-06-14 14:12:59 +080012007 //get the running status from driver
developera3511852023-06-14 14:12:59 +080012008 char buf[128] = {0};
developerc3556192023-12-06 17:59:09 +080012009 int radioIndex = 0, bss_idx;
developera3511852023-06-14 14:12:59 +080012010 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080012011 int res;
developer72fb0bb2023-01-11 09:46:29 +080012012
developera3511852023-06-14 14:12:59 +080012013 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012014
developerc3556192023-12-06 17:59:09 +080012015 if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
12016 wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
developer9ce44382023-06-28 11:09:37 +080012017 return RETURN_ERR;
12018 }
developera3511852023-06-14 14:12:59 +080012019 phyId = radio_index_to_phy(radioIndex);
developer8078acf2023-08-04 18:52:48 +080012020
12021 res = _syscmd_secure(buf, sizeof(buf), "iw phy phy%d info | grep u-APSD", phyId);
12022 if (res) {
12023 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080012024 }
developer72fb0bb2023-01-11 09:46:29 +080012025
developera3511852023-06-14 14:12:59 +080012026 if (strlen(buf) > 0)
12027 *output = true;
developer72fb0bb2023-01-11 09:46:29 +080012028
developera3511852023-06-14 14:12:59 +080012029 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012030
developera3511852023-06-14 14:12:59 +080012031 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012032}
12033
12034//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
12035INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
12036{
developera3511852023-06-14 14:12:59 +080012037 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +080012038}
12039
12040// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
12041INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
12042{
developer95c045d2023-05-24 19:26:28 +080012043 int if_idx, ret = 0;
12044 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080012045 struct nl_msg *msg = NULL;
12046 struct nlattr * msg_data = NULL;
12047 struct mtk_nl80211_param param;
12048 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +080012049
developer95c045d2023-05-24 19:26:28 +080012050 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012051
developer95c045d2023-05-24 19:26:28 +080012052 if (apIndex > MAX_APS) {
12053 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
12054 return RETURN_ERR;
12055 }
developer72fb0bb2023-01-11 09:46:29 +080012056
developer95c045d2023-05-24 19:26:28 +080012057 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12058 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080012059
developer95c045d2023-05-24 19:26:28 +080012060 if_idx = if_nametoindex(interface_name);
12061 /*init mtk nl80211 vendor cmd*/
12062 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
12063 param.if_type = NL80211_ATTR_IFINDEX;
12064 param.if_idx = if_idx;
12065 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
12066
12067 if (ret) {
12068 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
12069 return RETURN_ERR;
12070 }
12071
12072 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
12073 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
12074 nlmsg_free(msg);
12075 goto err;
12076 }
12077
12078 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
12079 if (ret) {
12080 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
12081 goto err;
12082 }
12083 mtk_nl80211_deint(&unl_ins);
12084
12085 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12086 return RETURN_OK;
12087err:
12088 mtk_nl80211_deint(&unl_ins);
12089 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12090 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012091}
12092
developer95c045d2023-05-24 19:26:28 +080012093
developer72fb0bb2023-01-11 09:46:29 +080012094//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.
12095INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
12096{
developer75bd10c2023-06-27 11:34:08 +080012097 int res;
12098
developera3511852023-06-14 14:12:59 +080012099 //get the running status from driver
12100 if(!output)
12101 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012102
developera3511852023-06-14 14:12:59 +080012103 char config_file[128] = {0};
12104 char buf[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012105
developer75bd10c2023-06-27 11:34:08 +080012106 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12107 if (os_snprintf_error(sizeof(config_file), res)) {
12108 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12109 return RETURN_ERR;
12110 }
developera3511852023-06-14 14:12:59 +080012111 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
12112 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
12113 *output = TRUE;
12114 else
12115 *output = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080012116
developera3511852023-06-14 14:12:59 +080012117 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012118}
12119
12120// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
12121INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
12122{
developera3511852023-06-14 14:12:59 +080012123 //save config and apply instantly.
12124 char config_file[MAX_BUF_SIZE] = {0};
12125 struct params list;
developer75bd10c2023-06-27 11:34:08 +080012126 int res;
developer72fb0bb2023-01-11 09:46:29 +080012127
developera3511852023-06-14 14:12:59 +080012128 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12129 list.name = "uapsd_advertisement_enabled";
12130 list.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080012131
developer75bd10c2023-06-27 11:34:08 +080012132 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12133 if (os_snprintf_error(sizeof(config_file), res)) {
12134 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12135 return RETURN_ERR;
12136 }
developera3511852023-06-14 14:12:59 +080012137 wifi_hostapdWrite(config_file, &list, 1);
12138 wifi_hostapdProcessUpdate(apIndex, &list, 1);
12139 wifi_quick_reload_ap(apIndex);
12140 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012141
developera3511852023-06-14 14:12:59 +080012142 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012143}
12144
12145// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
12146INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
12147{
developera3511852023-06-14 14:12:59 +080012148 char interface_name[16] = {0};
12149 // assume class 0->BE, 1->BK, 2->VI, 3->VO
developer8078acf2023-08-04 18:52:48 +080012150
developera3511852023-06-14 14:12:59 +080012151 char buf[128] = {0};
12152 char ack_filepath[128] = {0};
12153 uint16_t bitmap = 0;
12154 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
12155 FILE *f = NULL;
developere40952c2023-06-15 18:46:43 +080012156 int res;
developerc14d83a2023-06-29 20:09:42 +080012157 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080012158
developera3511852023-06-14 14:12:59 +080012159 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012160
developera3511852023-06-14 14:12:59 +080012161 // Get current setting
developere40952c2023-06-15 18:46:43 +080012162 res = snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
12163 if (os_snprintf_error(sizeof(ack_filepath), res)) {
12164 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12165 return RETURN_ERR;
12166 }
developer8078acf2023-08-04 18:52:48 +080012167 res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null", ack_filepath);
12168 if (res) {
12169 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080012170 }
developer8078acf2023-08-04 18:52:48 +080012171
developerd14dff12023-06-28 22:47:44 +080012172 if (strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +080012173 if (hal_strtoul(buf, 10, &tmp) < 0) {
12174 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080012175 }
developerc14d83a2023-06-29 20:09:42 +080012176 bitmap = tmp;
developerd14dff12023-06-28 22:47:44 +080012177 }
developer72fb0bb2023-01-11 09:46:29 +080012178
developera3511852023-06-14 14:12:59 +080012179 if (ackPolicy == TRUE) { // True, unset this class
12180 bitmap &= ~class_map[class];
12181 } else { // False, set this class
12182 bitmap |= class_map[class];
12183 }
developer72fb0bb2023-01-11 09:46:29 +080012184
developera3511852023-06-14 14:12:59 +080012185 f = fopen(ack_filepath, "w");
12186 if (f == NULL) {
developer37646972023-06-29 10:58:43 +080012187 if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
12188 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +080012189 return RETURN_ERR;
12190 }
developer37646972023-06-29 10:58:43 +080012191 if (fprintf(f, "%hu", bitmap) < 0)
12192 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
12193
12194 if (fclose(f) == EOF) {
12195 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
12196 return RETURN_ERR;
12197 }
developer72fb0bb2023-01-11 09:46:29 +080012198
developera3511852023-06-14 14:12:59 +080012199 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12200 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080012201
12202 res = _syscmd_secure(buf, sizeof(buf), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
12203 if (res) {
12204 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080012205 }
developer72fb0bb2023-01-11 09:46:29 +080012206
developera3511852023-06-14 14:12:59 +080012207 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
12208 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012209}
12210
12211//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.
12212INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
12213{
developer75bd10c2023-06-27 11:34:08 +080012214 int res;
12215
developera3511852023-06-14 14:12:59 +080012216 //get the running status from driver
12217 if(!output_uint)
12218 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012219
developera3511852023-06-14 14:12:59 +080012220 char output[16]={'\0'};
12221 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012222
developer75bd10c2023-06-27 11:34:08 +080012223 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12224 if (os_snprintf_error(sizeof(config_file), res)) {
12225 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12226 return RETURN_ERR;
12227 }
developera3511852023-06-14 14:12:59 +080012228 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
12229 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
12230 else {
12231 int device_num = atoi(output);
12232 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
12233 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
12234 return RETURN_ERR;
12235 }
12236 else {
12237 *output_uint = device_num;
12238 }
12239 }
developer72fb0bb2023-01-11 09:46:29 +080012240
developera3511852023-06-14 14:12:59 +080012241 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012242}
12243
12244INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
12245{
developera3511852023-06-14 14:12:59 +080012246 //store to wifi config, apply instantly
12247 char str[MAX_BUF_SIZE]={'\0'};
12248 struct params params;
12249 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080012250 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080012251
developera3511852023-06-14 14:12:59 +080012252 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12253 if (number > MAX_ASSOCIATED_STA_NUM) {
12254 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
12255 return RETURN_ERR;
12256 }
developer75bd10c2023-06-27 11:34:08 +080012257 res = snprintf(str, sizeof(str), "%d", number);
12258 if (os_snprintf_error(sizeof(str), res)) {
12259 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12260 return RETURN_ERR;
12261 }
developera3511852023-06-14 14:12:59 +080012262 params.name = "max_num_sta";
12263 params.value = str;
developer72fb0bb2023-01-11 09:46:29 +080012264
developer32f2a182023-06-27 19:50:41 +080012265 res = snprintf(config_file,
12266 sizeof(config_file), "%s%d.conf",CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080012267 if (os_snprintf_error(sizeof(config_file), res)) {
12268 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12269 return RETURN_ERR;
12270 }
developer32f2a182023-06-27 19:50:41 +080012271 ret = wifi_hostapdWrite(config_file, &params, 1);
developera3511852023-06-14 14:12:59 +080012272 if (ret) {
12273 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
12274 ,__func__, ret);
12275 }
developer72fb0bb2023-01-11 09:46:29 +080012276
developera3511852023-06-14 14:12:59 +080012277 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
12278 if (ret) {
12279 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
12280 ,__func__, ret);
12281 }
12282 wifi_reloadAp(apIndex);
12283 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012284
developera3511852023-06-14 14:12:59 +080012285 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012286}
12287
12288//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.
12289INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
12290{
developera3511852023-06-14 14:12:59 +080012291 //get the current threshold
12292 if(!output_uint)
12293 return RETURN_ERR;
12294 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
12295 if (*output_uint == 0)
12296 *output_uint = 50;
12297 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012298}
12299
12300INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
12301{
developera3511852023-06-14 14:12:59 +080012302 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
12303 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
12304 return RETURN_OK;
12305 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012306}
12307
12308//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.
12309INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
12310{
developera3511852023-06-14 14:12:59 +080012311 if(!output_uint)
12312 return RETURN_ERR;
12313 *output_uint = 3;
12314 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012315}
12316
12317//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
12318INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
12319{
developera3511852023-06-14 14:12:59 +080012320 if(!output_uint)
12321 return RETURN_ERR;
12322 *output_uint = 3;
12323 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012324}
12325
12326//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.
12327INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
12328{
developera3511852023-06-14 14:12:59 +080012329 if(!output_in_seconds)
12330 return RETURN_ERR;
12331 *output_in_seconds = 0;
12332 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012333}
12334
12335//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
12336INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
12337{
developere40952c2023-06-15 18:46:43 +080012338 int res;
12339
developera3511852023-06-14 14:12:59 +080012340 if(!output || apIndex>=MAX_APS)
12341 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012342 //res = snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
developer3d899672023-11-15 15:57:01 +080012343 res = snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise,WPA3-Personal-Transition");
developere40952c2023-06-15 18:46:43 +080012344 if (os_snprintf_error(128, res)) {
12345 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12346 return RETURN_ERR;
12347 }
developera3511852023-06-14 14:12:59 +080012348 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080012349}
developer72fb0bb2023-01-11 09:46:29 +080012350
12351//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
12352INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
12353{
developera3511852023-06-14 14:12:59 +080012354 char config_file[128] = {0};
12355 char wpa[16] = {0};
12356 char key_mgmt[64] = {0};
developer9ce44382023-06-28 11:09:37 +080012357 int res = -1;
developere40952c2023-06-15 18:46:43 +080012358
developera3511852023-06-14 14:12:59 +080012359 if (!output)
12360 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012361
developer75bd10c2023-06-27 11:34:08 +080012362 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12363 if (os_snprintf_error(sizeof(config_file), res)) {
12364 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12365 return RETURN_ERR;
12366 }
developera3511852023-06-14 14:12:59 +080012367 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
developer72fb0bb2023-01-11 09:46:29 +080012368
developer32f2a182023-06-27 19:50:41 +080012369 memcpy(output, "None", 4);//Copying "None" to output string for default case
12370 output[4] = '\0';
developera3511852023-06-14 14:12:59 +080012371 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
12372 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
12373 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080012374 res = snprintf(output, 32, "WPA-Personal");
developera3511852023-06-14 14:12:59 +080012375 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080012376 res = snprintf(output, 32, "WPA2-Personal");
developera3511852023-06-14 14:12:59 +080012377 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080012378 res = snprintf(output, 32, "WPA-WPA2-Personal");
developer72fb0bb2023-01-11 09:46:29 +080012379
developera3511852023-06-14 14:12:59 +080012380 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
developere40952c2023-06-15 18:46:43 +080012381 res = snprintf(output, 32, "WPA3-Enterprise");
developera3511852023-06-14 14:12:59 +080012382 } else if (strstr(key_mgmt, "WPA-EAP")) {
12383 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080012384 res = snprintf(output, 32, "WPA-Enterprise");
developera3511852023-06-14 14:12:59 +080012385 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080012386 res = snprintf(output, 32, "WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080012387 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080012388 res = snprintf(output, 32, "WPA-WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080012389 } else if (strstr(key_mgmt, "SAE")) {
12390 if (strstr(key_mgmt, "WPA-PSK") == NULL)
developere40952c2023-06-15 18:46:43 +080012391 res = snprintf(output, 32, "WPA3-Personal");
developera3511852023-06-14 14:12:59 +080012392 else
developere40952c2023-06-15 18:46:43 +080012393 res = snprintf(output, 32, "WPA3-Personal-Transition");
12394 }
12395 if (os_snprintf_error(32, res)) {
12396 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12397 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080012398 }
developer72fb0bb2023-01-11 09:46:29 +080012399
developera3511852023-06-14 14:12:59 +080012400 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
12401 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012402}
developer69b61b02023-03-07 17:17:44 +080012403
developer72fb0bb2023-01-11 09:46:29 +080012404INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
12405{
developer32f2a182023-06-27 19:50:41 +080012406 char securityType[32] = {0};
12407 char authMode[32] = {0};
12408 unsigned long len_sec, len_auth;
developera3511852023-06-14 14:12:59 +080012409 //store settings and wait for wifi up to apply
12410 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12411 if(!encMode)
12412 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012413
developera3511852023-06-14 14:12:59 +080012414 if (strcmp(encMode, "None")==0)
12415 {
developer32f2a182023-06-27 19:50:41 +080012416 len_sec = strlen("None");
12417 len_auth = strlen("None");
12418 memcpy(securityType, "None", len_sec);
12419 memcpy(authMode, "None", len_auth);
12420 } else if (strcmp(encMode, "WPA-WPA2-Personal")==0) {
12421 len_sec = strlen("WPAand11i");
12422 memcpy(securityType, "WPAand11i", len_sec);
12423 len_auth = strlen("PSKAuthentication");
12424 memcpy(authMode, "PSKAuthentication", len_auth);
12425 } else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) {
12426 len_sec = strlen("WPAand11i");
12427 memcpy(securityType, "WPAand11i", len_sec);
12428 len_auth = strlen("EAPAuthentication");
12429 memcpy(authMode, "EAPAuthentication", len_auth);
12430 } else if (strcmp(encMode, "WPA-Personal")==0) {
12431 len_sec = strlen("WPA");
12432 memcpy(securityType, "WPA", len_sec);
12433 len_auth = strlen("PSKAuthentication");
12434 memcpy(authMode, "PSKAuthentication", len_auth);
12435 } else if (strcmp(encMode, "WPA-Enterprise")==0) {
12436 len_sec = strlen("WPA");
12437 memcpy(securityType, "WPA", len_sec);
12438 len_auth = strlen("EAPAuthentication");
12439 memcpy(authMode, "EAPAuthentication", len_auth);
12440 } else if (strcmp(encMode, "WPA2-Personal")==0) {
12441 len_sec = strlen("11i");
12442 memcpy(securityType, "11i", len_sec);
12443 len_auth = strlen("PSKAuthentication");
12444 memcpy(authMode, "PSKAuthentication", len_auth);
12445 } else if (strcmp(encMode, "WPA2-Enterprise")==0) {
12446 len_sec = strlen("11i");
12447 memcpy(securityType, "11i", len_sec);
12448 len_auth = strlen("EAPAuthentication");
12449 memcpy(authMode, "EAPAuthentication", len_auth);
12450 } else if (strcmp(encMode, "WPA3-Personal") == 0) {
12451 len_sec = strlen("11i");
12452 memcpy(securityType, "11i", len_sec);
12453 len_auth = strlen("SAEAuthentication");
12454 memcpy(authMode, "SAEAuthentication", len_auth);
12455 } else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) {
12456 len_sec = strlen("11i");
12457 memcpy(securityType, "11i", len_sec);
12458 len_auth = strlen("PSK-SAEAuthentication");
12459 memcpy(authMode, "PSK-SAEAuthentication", len_auth);
12460 } else if (strcmp(encMode, "WPA3-Enterprise") == 0) {
12461 len_sec = strlen("11i");
12462 memcpy(securityType, "11i", len_sec);
12463 len_auth = strlen("EAP_192-bit_Authentication");
12464 memcpy(authMode, "EAP_192-bit_Authentication", len_auth);
12465 } else if (strcmp(encMode, "OWE") == 0) {
12466 len_sec = strlen("11i");
12467 memcpy(securityType, "11i", len_sec);
12468 len_auth = strlen("Enhanced_Open");
12469 memcpy(authMode, "Enhanced_Open", len_auth);
12470 } else {
12471 len_sec = strlen("None");
12472 memcpy(securityType, "None", len_sec);
12473 len_auth = strlen("None");
12474 memcpy(authMode, "None", len_auth);
developera3511852023-06-14 14:12:59 +080012475 }
developer32f2a182023-06-27 19:50:41 +080012476 securityType[len_sec] = '\0';
12477 authMode[len_auth] = '\0';
developera3511852023-06-14 14:12:59 +080012478 wifi_setApBeaconType(apIndex, securityType);
12479 wifi_setApBasicAuthenticationMode(apIndex, authMode);
12480 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012481
developera3511852023-06-14 14:12:59 +080012482 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080012483}
developer72fb0bb2023-01-11 09:46:29 +080012484
12485
12486//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
12487// output_string must be pre-allocated as 64 character string by caller
12488// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
12489INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
12490{
developera3511852023-06-14 14:12:59 +080012491 char buf[16] = {0};
12492 char config_file[MAX_BUF_SIZE] = {0};
12493 int res;
developer72fb0bb2023-01-11 09:46:29 +080012494
developera3511852023-06-14 14:12:59 +080012495 if(output_string==NULL)
12496 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012497
developera3511852023-06-14 14:12:59 +080012498 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
12499 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012500 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12501 return RETURN_ERR;
12502 }
developera3511852023-06-14 14:12:59 +080012503 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012504
developera3511852023-06-14 14:12:59 +080012505 if(strcmp(buf,"0")==0)
12506 {
12507 printf("wpa_mode is %s ......... \n",buf);
12508 return RETURN_ERR;
12509 }
developer72fb0bb2023-01-11 09:46:29 +080012510
developera3511852023-06-14 14:12:59 +080012511 wifi_dbg_printf("\nFunc=%s\n",__func__);
12512 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
12513 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012514 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12515 return RETURN_ERR;
12516 }
developere5750452023-05-15 16:46:42 +080012517 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developera3511852023-06-14 14:12:59 +080012518 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080012519
developera3511852023-06-14 14:12:59 +080012520 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012521}
12522
12523// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
12524// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
12525INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
12526{
developera3511852023-06-14 14:12:59 +080012527 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
12528 struct params params={'\0'};
developer32f2a182023-06-27 19:50:41 +080012529 int ret;
developera3511852023-06-14 14:12:59 +080012530 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012531
developera3511852023-06-14 14:12:59 +080012532 if(NULL == preSharedKey)
12533 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012534
developera3511852023-06-14 14:12:59 +080012535 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +080012536
developera3511852023-06-14 14:12:59 +080012537 if(strlen(preSharedKey) != 64)
12538 {
12539 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
12540 return RETURN_ERR;
12541 }
12542 params.value = preSharedKey;
developer32f2a182023-06-27 19:50:41 +080012543 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12544 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080012545 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12546 return RETURN_ERR;
12547 }
developera3511852023-06-14 14:12:59 +080012548 ret = wifi_hostapdWrite(config_file, &params, 1);
12549 if(!ret) {
12550 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
12551 wifi_reloadAp(apIndex);
12552 }
12553 return ret;
12554 //TODO: call hostapd_cli for dynamic_config_control
developer72fb0bb2023-01-11 09:46:29 +080012555}
12556
12557//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
12558// outputs the passphrase, maximum 63 characters
12559INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
12560{
developera3511852023-06-14 14:12:59 +080012561 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
developer75bd10c2023-06-27 11:34:08 +080012562 int res;
developer72fb0bb2023-01-11 09:46:29 +080012563
developera3511852023-06-14 14:12:59 +080012564 wifi_dbg_printf("\nFunc=%s\n",__func__);
12565 if (NULL == output_string)
12566 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012567
developer75bd10c2023-06-27 11:34:08 +080012568 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12569 if (os_snprintf_error(sizeof(config_file), res)) {
12570 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12571 return RETURN_ERR;
12572 }
12573
developera3511852023-06-14 14:12:59 +080012574 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
12575 if(strcmp(buf,"0")==0)
12576 {
12577 printf("wpa_mode is %s ......... \n",buf);
12578 return RETURN_ERR;
12579 }
developer72fb0bb2023-01-11 09:46:29 +080012580
developera3511852023-06-14 14:12:59 +080012581 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
12582 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080012583
developera3511852023-06-14 14:12:59 +080012584 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012585}
12586
12587// sets the passphrase enviornment variable, max 63 characters
12588INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
12589{
developera3511852023-06-14 14:12:59 +080012590 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
12591 struct params params={'\0'};
12592 char config_file[MAX_BUF_SIZE] = {0};
12593 int ret;
developer72fb0bb2023-01-11 09:46:29 +080012594
developera3511852023-06-14 14:12:59 +080012595 if(NULL == passPhrase)
12596 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012597
developera3511852023-06-14 14:12:59 +080012598 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
12599 {
12600 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
12601 return RETURN_ERR;
12602 }
12603 params.name = "wpa_passphrase";
12604 params.value = passPhrase;
developer32f2a182023-06-27 19:50:41 +080012605 ret = snprintf(config_file, sizeof(config_file),
12606 "%s%d.conf", CONFIG_PREFIX, apIndex);
12607 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080012608 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12609 return RETURN_ERR;
12610 }
developera3511852023-06-14 14:12:59 +080012611 ret=wifi_hostapdWrite(config_file,&params,1);
12612 if(!ret) {
12613 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +080012614 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +080012615 }
developer72fb0bb2023-01-11 09:46:29 +080012616
developera3511852023-06-14 14:12:59 +080012617 return ret;
developer72fb0bb2023-01-11 09:46:29 +080012618}
12619
12620//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.
12621INT wifi_setApSecurityReset(INT apIndex)
12622{
developera3511852023-06-14 14:12:59 +080012623 char original_config_file[64] = {0};
12624 char current_config_file[64] = {0};
12625 char buf[64] = {0};
developer8078acf2023-08-04 18:52:48 +080012626
developera3511852023-06-14 14:12:59 +080012627 char wpa[4] = {0};
12628 char wpa_psk[64] = {0};
12629 char wpa_passphrase[64] = {0};
12630 char wpa_psk_file[128] = {0};
12631 char wpa_key_mgmt[64] = {0};
12632 char wpa_pairwise[32] = {0};
12633 wifi_band band;
12634 struct params list[6];
developere40952c2023-06-15 18:46:43 +080012635 int res;
developer72fb0bb2023-01-11 09:46:29 +080012636
developera3511852023-06-14 14:12:59 +080012637 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012638
developera3511852023-06-14 14:12:59 +080012639 band = wifi_index_to_band(apIndex);
developer37646972023-06-29 10:58:43 +080012640 if (band == band_2_4) {
12641 res = snprintf(original_config_file, sizeof(original_config_file),
12642 "/etc/hostapd-2G.conf");
12643 if (os_snprintf_error(sizeof(original_config_file), res)) {
12644 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12645 return RETURN_ERR;
12646 }
developer8078acf2023-08-04 18:52:48 +080012647
developer37646972023-06-29 10:58:43 +080012648 } else if (band == band_5) {
12649 res = snprintf(original_config_file, sizeof(original_config_file),
12650 "/etc/hostapd-5G.conf");
12651 if (os_snprintf_error(sizeof(original_config_file), res)) {
12652 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12653 return RETURN_ERR;
12654 }
12655 } else if (band == band_6) {
12656 res = snprintf(original_config_file, sizeof(original_config_file),
12657 "/etc/hostapd-6G.conf");
12658 if (os_snprintf_error(sizeof(original_config_file), res)) {
12659 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12660 return RETURN_ERR;
12661 }
12662 } else
developera3511852023-06-14 14:12:59 +080012663 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012664
developera3511852023-06-14 14:12:59 +080012665 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
12666 list[0].name = "wpa";
12667 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +080012668
developera3511852023-06-14 14:12:59 +080012669 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
12670 list[1].name = "wpa_psk";
12671 list[1].value = wpa_psk;
developer72fb0bb2023-01-11 09:46:29 +080012672
developera3511852023-06-14 14:12:59 +080012673 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
12674 list[2].name = "wpa_passphrase";
12675 list[2].value = wpa_passphrase;
developer72fb0bb2023-01-11 09:46:29 +080012676
developera3511852023-06-14 14:12:59 +080012677 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
developer72fb0bb2023-01-11 09:46:29 +080012678
developera3511852023-06-14 14:12:59 +080012679 if (strlen(wpa_psk_file) == 0)
developer32f2a182023-06-27 19:50:41 +080012680 memcpy(wpa_psk_file, PSK_FILE, strlen(PSK_FILE));
developer72fb0bb2023-01-11 09:46:29 +080012681
developera3511852023-06-14 14:12:59 +080012682 if (access(wpa_psk_file, F_OK) != 0) {
developer8078acf2023-08-04 18:52:48 +080012683 res = _syscmd_secure(buf, sizeof(buf),"touch %s", wpa_psk_file);
12684 if (res) {
12685 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080012686 }
developera3511852023-06-14 14:12:59 +080012687 }
12688 list[3].name = "wpa_psk_file";
12689 list[3].value = wpa_psk_file;
developer72fb0bb2023-01-11 09:46:29 +080012690
developera3511852023-06-14 14:12:59 +080012691 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
12692 list[4].name = "wpa_key_mgmt";
12693 list[4].value = wpa_key_mgmt;
developer72fb0bb2023-01-11 09:46:29 +080012694
developera3511852023-06-14 14:12:59 +080012695 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
12696 list[5].name = "wpa_pairwise";
12697 list[5].value = wpa_pairwise;
developer72fb0bb2023-01-11 09:46:29 +080012698
developer32f2a182023-06-27 19:50:41 +080012699 res = snprintf(current_config_file, sizeof(current_config_file),
12700 "%s%d.conf", CONFIG_PREFIX, apIndex);
12701 if (os_snprintf_error(sizeof(current_config_file), res)) {
12702 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12703 return RETURN_ERR;
12704 }
developera3511852023-06-14 14:12:59 +080012705 wifi_hostapdWrite(current_config_file, list, 6);
developer72fb0bb2023-01-11 09:46:29 +080012706
developera3511852023-06-14 14:12:59 +080012707 wifi_setApEnable(apIndex, FALSE);
12708 wifi_setApEnable(apIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +080012709
developera3511852023-06-14 14:12:59 +080012710 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12711 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012712}
12713
12714//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).
12715INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
12716{
developera3511852023-06-14 14:12:59 +080012717 char config_file[64] = {0};
12718 char buf[64] = {0};
developer8078acf2023-08-04 18:52:48 +080012719
developere40952c2023-06-15 18:46:43 +080012720 int res;
developer72fb0bb2023-01-11 09:46:29 +080012721
developera3511852023-06-14 14:12:59 +080012722 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012723
developera3511852023-06-14 14:12:59 +080012724 if(!IP_output || !Port_output || !RadiusSecret_output)
12725 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012726
developera3511852023-06-14 14:12:59 +080012727 // Read the first matched config
developere40952c2023-06-15 18:46:43 +080012728 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12729 if (os_snprintf_error(sizeof(config_file), res)) {
12730 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12731 return RETURN_ERR;
12732 }
developer8078acf2023-08-04 18:52:48 +080012733 res = _syscmd_secure(buf, sizeof(buf),
developer32f2a182023-06-27 19:50:41 +080012734 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
developer8078acf2023-08-04 18:52:48 +080012735 if (res) {
12736 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080012737 }
developera3511852023-06-14 14:12:59 +080012738 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080012739
developera3511852023-06-14 14:12:59 +080012740 memset(buf, 0, sizeof(buf));
developer8078acf2023-08-04 18:52:48 +080012741 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
12742 if (res) {
12743 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080012744 }
developera3511852023-06-14 14:12:59 +080012745 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080012746
developera3511852023-06-14 14:12:59 +080012747 memset(buf, 0, sizeof(buf));
developer8078acf2023-08-04 18:52:48 +080012748 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
12749 if (res) {
12750 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080012751 }
developera3511852023-06-14 14:12:59 +080012752 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080012753
developera3511852023-06-14 14:12:59 +080012754 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12755 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012756}
12757
12758INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
12759{
developera3511852023-06-14 14:12:59 +080012760 char config_file[64] = {0};
12761 char port_str[8] = {0};
12762 char cmd[256] = {0};
12763 char buf[128] = {0};
12764 int res;
developer72fb0bb2023-01-11 09:46:29 +080012765
developera3511852023-06-14 14:12:59 +080012766 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012767
developere5750452023-05-15 16:46:42 +080012768 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080012769 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080012770
developera3511852023-06-14 14:12:59 +080012771 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
12772 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080012773
developera3511852023-06-14 14:12:59 +080012774 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12775 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012776 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12777 return RETURN_ERR;
12778 }
developer72fb0bb2023-01-11 09:46:29 +080012779
developer8078acf2023-08-04 18:52:48 +080012780 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '# radius 1'", config_file);
12781 if (res) {
12782 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer46506162023-06-12 10:09:39 +080012783 }
developer8078acf2023-08-04 18:52:48 +080012784
developera3511852023-06-14 14:12:59 +080012785 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080012786
developere40952c2023-06-15 18:46:43 +080012787 res = snprintf(port_str, sizeof(port_str), "%d", port);
developer37646972023-06-29 10:58:43 +080012788 if (os_snprintf_error(sizeof(port_str), res)) {
12789 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12790 return RETURN_ERR;
12791 }
developera3511852023-06-14 14:12:59 +080012792 if (strlen(buf) == 0) {
12793 // Append
12794 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
12795 "auth_server_addr=%s\\n"
12796 "auth_server_port=%s\\n"
12797 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
12798 if (os_snprintf_error(sizeof(cmd), res)) {
12799 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12800 return RETURN_ERR;
12801 }
developer8078acf2023-08-04 18:52:48 +080012802
12803 if(_syscmd_secure(buf, sizeof(buf), "echo -e '# radius 1\\n"
12804 "auth_server_addr=%s\\n"
12805 "auth_server_port=%s\\n"
12806 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file)) {
12807 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
12808 return RETURN_ERR;
12809 }
developera3511852023-06-14 14:12:59 +080012810 } else {
12811 // Delete the three lines setting after the "# radius 1" comment
developer8078acf2023-08-04 18:52:48 +080012812 res = _syscmd_secure(buf, sizeof(buf), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
12813 if (res) {
12814 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developera3511852023-06-14 14:12:59 +080012815 }
developera3511852023-06-14 14:12:59 +080012816 memset(cmd, 0, sizeof(cmd));
12817 // Use "# radius 1" comment to find the location to insert the radius setting
12818 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
12819 "# radius 1\\n"
12820 "auth_server_addr=%s\\n"
12821 "auth_server_port=%s\\n"
12822 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
12823 if (os_snprintf_error(sizeof(cmd), res)) {
12824 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12825 return RETURN_ERR;
12826 }
developer8078acf2023-08-04 18:52:48 +080012827
12828 if(_syscmd_secure(buf, sizeof(buf), "sed -i 's/# radius 1/"
12829 "# radius 1\\n"
12830 "auth_server_addr=%s\\n"
12831 "auth_server_port=%s\\n"
12832 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file)) {
12833 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
12834 return RETURN_ERR;
12835 }
developera3511852023-06-14 14:12:59 +080012836 }
developer72fb0bb2023-01-11 09:46:29 +080012837
developera3511852023-06-14 14:12:59 +080012838 wifi_reloadAp(apIndex);
12839 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12840 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012841}
12842
12843INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
12844{
developera3511852023-06-14 14:12:59 +080012845 char config_file[64] = {0};
12846 char buf[64] = {0};
developer8078acf2023-08-04 18:52:48 +080012847
developere40952c2023-06-15 18:46:43 +080012848 int res;
developer72fb0bb2023-01-11 09:46:29 +080012849
developera3511852023-06-14 14:12:59 +080012850 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012851
developera3511852023-06-14 14:12:59 +080012852 if(!IP_output || !Port_output || !RadiusSecret_output)
12853 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012854
developera3511852023-06-14 14:12:59 +080012855 // Read the second matched config
developere40952c2023-06-15 18:46:43 +080012856 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12857 if (os_snprintf_error(sizeof(config_file), res)) {
12858 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12859 return RETURN_ERR;
12860 }
12861
developer8078acf2023-08-04 18:52:48 +080012862 res = _syscmd_secure(buf, sizeof(buf),
developer32f2a182023-06-27 19:50:41 +080012863 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
12864 config_file);
developer8078acf2023-08-04 18:52:48 +080012865 if (res) {
12866 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080012867 }
developer8078acf2023-08-04 18:52:48 +080012868
developera3511852023-06-14 14:12:59 +080012869 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080012870
developera3511852023-06-14 14:12:59 +080012871 memset(buf, 0, sizeof(buf));
developer8078acf2023-08-04 18:52:48 +080012872 res = _syscmd_secure(buf, sizeof(buf),
developer32f2a182023-06-27 19:50:41 +080012873 "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
12874 config_file);
developer8078acf2023-08-04 18:52:48 +080012875 if (res) {
12876 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080012877 }
developer8078acf2023-08-04 18:52:48 +080012878
developera3511852023-06-14 14:12:59 +080012879 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080012880
developera3511852023-06-14 14:12:59 +080012881 memset(buf, 0, sizeof(buf));
developer8078acf2023-08-04 18:52:48 +080012882 res = _syscmd_secure(buf, sizeof(buf),
developer32f2a182023-06-27 19:50:41 +080012883 "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
12884 config_file);
developer8078acf2023-08-04 18:52:48 +080012885 if (res) {
12886 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080012887 }
12888
developera3511852023-06-14 14:12:59 +080012889 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080012890
developera3511852023-06-14 14:12:59 +080012891 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12892 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012893}
12894
12895INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
12896{
developera3511852023-06-14 14:12:59 +080012897 char config_file[64] = {0};
12898 char port_str[8] = {0};
12899 char cmd[256] = {0};
12900 char buf[128] = {0};
12901 int res;
developer72fb0bb2023-01-11 09:46:29 +080012902
developera3511852023-06-14 14:12:59 +080012903 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012904
developere5750452023-05-15 16:46:42 +080012905 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080012906 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080012907
developera3511852023-06-14 14:12:59 +080012908 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
12909 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080012910
developera3511852023-06-14 14:12:59 +080012911 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12912 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012913 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12914 return RETURN_ERR;
12915 }
developer72fb0bb2023-01-11 09:46:29 +080012916
developer8078acf2023-08-04 18:52:48 +080012917 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '# radius 2'", config_file);
12918 if (res) {
12919 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer46506162023-06-12 10:09:39 +080012920 }
developer8078acf2023-08-04 18:52:48 +080012921
developera3511852023-06-14 14:12:59 +080012922 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080012923
developera3511852023-06-14 14:12:59 +080012924 res = snprintf(port_str, sizeof(port_str), "%d", port);
12925 if (os_snprintf_error(sizeof(port_str), res)) {
developer46506162023-06-12 10:09:39 +080012926 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12927 return RETURN_ERR;
12928 }
developera3511852023-06-14 14:12:59 +080012929 if (strlen(buf) == 0) {
12930 // Append
12931 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
12932 "auth_server_addr=%s\\n"
12933 "auth_server_port=%s\\n"
12934 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
12935 if (os_snprintf_error(sizeof(cmd), res)) {
12936 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12937 return RETURN_ERR;
12938 }
developer8078acf2023-08-04 18:52:48 +080012939
12940 if(_syscmd_secure(buf, sizeof(buf), "echo -e '# radius 2\\n"
12941 "auth_server_addr=%s\\n"
12942 "auth_server_port=%s\\n"
12943 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file)){
12944 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
12945 return RETURN_ERR;
12946 }
developera3511852023-06-14 14:12:59 +080012947 } else {
12948 // Delete the three lines setting after the "# radius 2" comment
developer8078acf2023-08-04 18:52:48 +080012949 res = _syscmd_secure(buf, sizeof(buf), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
12950 if (res) {
12951 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developera3511852023-06-14 14:12:59 +080012952 }
developer8078acf2023-08-04 18:52:48 +080012953
developera3511852023-06-14 14:12:59 +080012954 memset(cmd, 0, sizeof(cmd));
12955 // Use "# radius 2" comment to find the location to insert the radius setting
12956 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
12957 "# radius 2\\n"
12958 "auth_server_addr=%s\\n"
12959 "auth_server_port=%s\\n"
12960 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
12961 if (os_snprintf_error(sizeof(cmd), res)) {
12962 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12963 return RETURN_ERR;
12964 }
developer8078acf2023-08-04 18:52:48 +080012965
12966 if(_syscmd_secure(buf, sizeof(buf), "sed -i 's/# radius 2/"
12967 "# radius 2\\n"
12968 "auth_server_addr=%s\\n"
12969 "auth_server_port=%s\\n"
12970 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file)){
12971 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
12972 return RETURN_ERR;
12973 }
developera3511852023-06-14 14:12:59 +080012974 }
developer72fb0bb2023-01-11 09:46:29 +080012975
developera3511852023-06-14 14:12:59 +080012976 wifi_reloadAp(apIndex);
12977 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12978 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012979}
12980
12981//RadiusSettings
12982INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
12983{
developera3511852023-06-14 14:12:59 +080012984 if(!output)
12985 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012986
developera3511852023-06-14 14:12:59 +080012987 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
12988 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
12989 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
12990 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
12991 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
12992 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.
12993 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
12994 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
12995 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 +080012996 //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 +080012997
developera3511852023-06-14 14:12:59 +080012998 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012999}
13000
13001INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
13002{
developera3511852023-06-14 14:12:59 +080013003 //store the paramters, and apply instantly
13004 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013005}
13006
13007//Device.WiFi.AccessPoint.{i}.WPS.Enable
13008//Enables or disables WPS functionality for this access point.
13009// outputs the WPS enable state of this ap in output_bool
13010INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
13011{
developera3511852023-06-14 14:12:59 +080013012 char interface_name[16] = {0};
developer8078acf2023-08-04 18:52:48 +080013013 char buf[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080013014 int res;
13015
developera3511852023-06-14 14:12:59 +080013016 if(!output_bool)
13017 return RETURN_ERR;
13018 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13019 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080013020 res = _syscmd_secure(buf, sizeof(buf),
developer32f2a182023-06-27 19:50:41 +080013021 "hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2",
13022 interface_name);
developer8078acf2023-08-04 18:52:48 +080013023 if (res) {
13024 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080013025 }
developera3511852023-06-14 14:12:59 +080013026 if(strstr(buf, "configured"))
13027 *output_bool=TRUE;
13028 else
13029 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +080013030
developera3511852023-06-14 14:12:59 +080013031 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080013032}
developer72fb0bb2023-01-11 09:46:29 +080013033
13034//Device.WiFi.AccessPoint.{i}.WPS.Enable
13035// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
13036INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
13037{
developera3511852023-06-14 14:12:59 +080013038 char config_file[MAX_BUF_SIZE] = {0};
13039 char buf[128] = {0};
13040 struct params params;
developere40952c2023-06-15 18:46:43 +080013041 int res;
developer72fb0bb2023-01-11 09:46:29 +080013042
developera3511852023-06-14 14:12:59 +080013043 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13044 //store the paramters, and wait for wifi up to apply
13045 params.name = "wps_state";
13046 if (enable == TRUE) {
13047 wifi_getApBeaconType(apIndex, buf);
13048 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
13049 params.value = "1";
13050 else // If ap set encryption
13051 params.value = "2";
13052 } else {
13053 params.value = "0";
13054 }
developer72fb0bb2023-01-11 09:46:29 +080013055
developere40952c2023-06-15 18:46:43 +080013056 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
13057 if (os_snprintf_error(sizeof(config_file), res)) {
13058 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13059 return RETURN_ERR;
13060 }
developera3511852023-06-14 14:12:59 +080013061 wifi_hostapdWrite(config_file, &params, 1);
13062 wifi_hostapdProcessUpdate(apIndex, &params, 1);
13063 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080013064
developera3511852023-06-14 14:12:59 +080013065 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13066 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013067}
13068
13069//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
13070INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
13071{
developere40952c2023-06-15 18:46:43 +080013072 int res;
developera3511852023-06-14 14:12:59 +080013073 if(!output)
13074 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080013075 res = snprintf(output, 128, "PushButton,PIN");
13076 if (os_snprintf_error(128, res)) {
13077 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13078 return RETURN_ERR;
13079 }
13080
developera3511852023-06-14 14:12:59 +080013081 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013082}
13083
13084//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
13085//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.
13086// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
13087INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
13088{
developere40952c2023-06-15 18:46:43 +080013089 int res;
developera3511852023-06-14 14:12:59 +080013090 if(!output)
13091 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080013092 res = snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
13093 if (os_snprintf_error(64, res)) {
13094 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13095 return RETURN_ERR;
13096 }
developer72fb0bb2023-01-11 09:46:29 +080013097
developera3511852023-06-14 14:12:59 +080013098 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013099}
13100
13101//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
13102// 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
13103INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
13104{
developera3511852023-06-14 14:12:59 +080013105 //apply instantly. No setting need to be stored.
13106 char methods[MAX_BUF_SIZE], *token, *next_token;
13107 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
13108 struct params params;
developere40952c2023-06-15 18:46:43 +080013109 int res;
developer72fb0bb2023-01-11 09:46:29 +080013110
developera3511852023-06-14 14:12:59 +080013111 if(!methodString)
13112 return RETURN_ERR;
13113 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13114 //store the paramters, and wait for wifi up to apply
developer72fb0bb2023-01-11 09:46:29 +080013115
developere40952c2023-06-15 18:46:43 +080013116 res = snprintf(methods, sizeof(methods), "%s", methodString);
13117 if (os_snprintf_error(sizeof(methods), res)) {
13118 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13119 return RETURN_ERR;
13120 }
developera3511852023-06-14 14:12:59 +080013121 for(token=methods; *token; token=next_token) {
13122 strtok_r(token, ",", &next_token);
13123 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
developere40952c2023-06-15 18:46:43 +080013124 res = snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
developera3511852023-06-14 14:12:59 +080013125 else if(*token=='E')
13126 {
13127 if(!strcmp(methods, "Ethernet"))
developere40952c2023-06-15 18:46:43 +080013128 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
developera3511852023-06-14 14:12:59 +080013129 else if(!strcmp(methods, "ExternalNFCToken"))
developere40952c2023-06-15 18:46:43 +080013130 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
developera3511852023-06-14 14:12:59 +080013131 else
13132 printf("%s: Unknown WpsConfigMethod\n", __func__);
13133 }
13134 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
developere40952c2023-06-15 18:46:43 +080013135 res = snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
developera3511852023-06-14 14:12:59 +080013136 else if(*token=='N' && !strcmp(token, "NFCInterface"))
developere40952c2023-06-15 18:46:43 +080013137 res = snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
developera3511852023-06-14 14:12:59 +080013138 else if(*token=='P' )
13139 {
13140 if(!strcmp(token, "PushButton"))
developere40952c2023-06-15 18:46:43 +080013141 res = snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developera3511852023-06-14 14:12:59 +080013142 else if(!strcmp(token, "PIN"))
developere40952c2023-06-15 18:46:43 +080013143 res = snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
developera3511852023-06-14 14:12:59 +080013144 else
13145 printf("%s: Unknown WpsConfigMethod\n", __func__);
13146 }
13147 else
13148 printf("%s: Unknown WpsConfigMethod\n", __func__);
developere40952c2023-06-15 18:46:43 +080013149
developer37646972023-06-29 10:58:43 +080013150 if (os_snprintf_error(sizeof(config_methods), res)) {
13151 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13152 return RETURN_ERR;
13153 }
13154 }
developera3511852023-06-14 14:12:59 +080013155 params.name = "config_methods";
13156 params.value = config_methods;
developere40952c2023-06-15 18:46:43 +080013157 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
13158 if (os_snprintf_error(sizeof(config_file), res)) {
13159 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13160 return RETURN_ERR;
13161 }
developera3511852023-06-14 14:12:59 +080013162 wifi_hostapdWrite(config_file, &params, 1);
13163 wifi_hostapdProcessUpdate(apIndex, &params, 1);
13164 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013165
developera3511852023-06-14 14:12:59 +080013166 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013167}
13168
13169// outputs the pin value, ulong_pin must be allocated by the caller
13170INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
13171{
developera3511852023-06-14 14:12:59 +080013172 char buf[MAX_BUF_SIZE] = {0};
developer8078acf2023-08-04 18:52:48 +080013173
developere40952c2023-06-15 18:46:43 +080013174 int res;
developer72fb0bb2023-01-11 09:46:29 +080013175
developera3511852023-06-14 14:12:59 +080013176 if(!output_ulong)
13177 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080013178 res = _syscmd_secure(buf, sizeof(buf), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
13179 if (res) {
13180 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080013181 }
developerd14dff12023-06-28 22:47:44 +080013182 if(strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +080013183 if (hal_strtoul(buf, 10, output_ulong) < 0) {
13184 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080013185 }
13186 }
developer72fb0bb2023-01-11 09:46:29 +080013187
developera3511852023-06-14 14:12:59 +080013188 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013189}
13190
13191// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
13192INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
13193{
developera3511852023-06-14 14:12:59 +080013194 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
13195 char ap_pin[16] = {0};
13196 char config_file[MAX_BUF_SIZE] = {0};
13197 struct params params;
developere40952c2023-06-15 18:46:43 +080013198 int res;
developer72fb0bb2023-01-11 09:46:29 +080013199
developera3511852023-06-14 14:12:59 +080013200 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080013201 res = snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
13202 if (os_snprintf_error(sizeof(ap_pin), res)) {
13203 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13204 return RETURN_ERR;
13205 }
developera3511852023-06-14 14:12:59 +080013206 params.name = "ap_pin";
13207 params.value = ap_pin;
developere40952c2023-06-15 18:46:43 +080013208 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
13209 if (os_snprintf_error(sizeof(config_file), res)) {
13210 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13211 return RETURN_ERR;
13212 }
developera3511852023-06-14 14:12:59 +080013213 wifi_hostapdWrite(config_file, &params, 1);
13214 wifi_hostapdProcessUpdate(apIndex, &params, 1);
13215 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013216
developera3511852023-06-14 14:12:59 +080013217 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013218}
13219
13220// Output string is either Not configured or Configured, max 32 characters
13221INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
13222{
developera3511852023-06-14 14:12:59 +080013223 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080013224 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080013225 int res;
developer72fb0bb2023-01-11 09:46:29 +080013226
developera3511852023-06-14 14:12:59 +080013227 if(!output_string)
13228 return RETURN_ERR;
13229 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080013230 res = snprintf(output_string, 32, "Not configured");
13231 if (os_snprintf_error(32, res)) {
13232 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13233 return RETURN_ERR;
13234 }
developera3511852023-06-14 14:12:59 +080013235 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13236 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080013237 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
13238 if (res) {
13239 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080013240 }
developer72fb0bb2023-01-11 09:46:29 +080013241
developerc14d83a2023-06-29 20:09:42 +080013242 if(!strncmp(buf, "configured", 10)) {
developere40952c2023-06-15 18:46:43 +080013243 res = snprintf(output_string, 32, "Configured");
developerc14d83a2023-06-29 20:09:42 +080013244 if (os_snprintf_error(32, res)) {
13245 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13246 return RETURN_ERR;
13247 }
13248 }
developera3511852023-06-14 14:12:59 +080013249 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013250
developera3511852023-06-14 14:12:59 +080013251 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013252}
13253
13254// sets the WPS pin for this AP
13255INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
13256{
developera3511852023-06-14 14:12:59 +080013257 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080013258 char buf[MAX_BUF_SIZE]={0};
developer9ce44382023-06-28 11:09:37 +080013259 BOOL enable = 0;
developere40952c2023-06-15 18:46:43 +080013260 int res;
developer72fb0bb2023-01-11 09:46:29 +080013261
developera3511852023-06-14 14:12:59 +080013262 wifi_getApEnable(apIndex, &enable);
13263 if (!enable)
13264 return RETURN_ERR;
13265 wifi_getApWpsEnable(apIndex, &enable);
13266 if (!enable)
13267 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013268
developera3511852023-06-14 14:12:59 +080013269 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13270 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080013271 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
13272 if (res) {
13273 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080013274 }
developer8078acf2023-08-04 18:52:48 +080013275
developera3511852023-06-14 14:12:59 +080013276 if((strstr(buf, "OK"))!=NULL)
13277 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013278
developera3511852023-06-14 14:12:59 +080013279 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013280}
13281
13282// This function is called when the WPS push button has been pressed for this AP
13283INT wifi_setApWpsButtonPush(INT apIndex)
13284{
developera3511852023-06-14 14:12:59 +080013285 char buf[MAX_BUF_SIZE]={0};
13286 char interface_name[16] = {0};
13287 BOOL enable=FALSE;
developere40952c2023-06-15 18:46:43 +080013288 int res;
developer72fb0bb2023-01-11 09:46:29 +080013289
developera3511852023-06-14 14:12:59 +080013290 wifi_getApEnable(apIndex, &enable);
13291 if (!enable)
13292 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013293
developera3511852023-06-14 14:12:59 +080013294 wifi_getApWpsEnable(apIndex, &enable);
13295 if (!enable)
13296 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013297
developera3511852023-06-14 14:12:59 +080013298 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13299 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013300
developer8078acf2023-08-04 18:52:48 +080013301 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
13302 if (res) {
13303 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080013304 }
developer72fb0bb2023-01-11 09:46:29 +080013305
developera3511852023-06-14 14:12:59 +080013306 if((strstr(buf, "OK"))!=NULL)
13307 return RETURN_OK;
13308 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013309}
13310
13311// cancels WPS mode for this AP
13312INT wifi_cancelApWPS(INT apIndex)
13313{
developera3511852023-06-14 14:12:59 +080013314 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080013315 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080013316 int res;
developer72fb0bb2023-01-11 09:46:29 +080013317
developera3511852023-06-14 14:12:59 +080013318 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13319 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080013320
13321 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s wps_cancel", interface_name);
13322 if (res) {
13323 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080013324 }
developer72fb0bb2023-01-11 09:46:29 +080013325
developera3511852023-06-14 14:12:59 +080013326 if((strstr(buf, "OK"))!=NULL)
13327 return RETURN_OK;
13328 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013329}
13330
13331//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
13332//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
13333INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
13334{
developera3511852023-06-14 14:12:59 +080013335 char interface_name[16] = {0};
13336 FILE *f = NULL;
13337 int read_flag=0, auth_temp=0, mac_temp=0;
developer8078acf2023-08-04 18:52:48 +080013338 char buf[2048] = {0};
developera3511852023-06-14 14:12:59 +080013339 char *param = NULL, *value = NULL, *line=NULL;
13340 size_t len = 0;
13341 wifi_associated_dev_t *dev=NULL;
13342 int res;
developer72fb0bb2023-01-11 09:46:29 +080013343
developera3511852023-06-14 14:12:59 +080013344 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13345 *associated_dev_array = NULL;
13346 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13347 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080013348 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
13349 if (res) {
13350 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer46506162023-06-12 10:09:39 +080013351 }
developer8078acf2023-08-04 18:52:48 +080013352
developera3511852023-06-14 14:12:59 +080013353 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080013354
developera3511852023-06-14 14:12:59 +080013355 if (*output_array_size <= 0)
13356 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013357
developera3511852023-06-14 14:12:59 +080013358 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
developere75ba632023-06-29 16:03:33 +080013359 if (!dev) {
13360 wifi_debug(DEBUG_ERROR, "Unexpected calloc fail\n");
13361 return RETURN_ERR;
13362 }
developera3511852023-06-14 14:12:59 +080013363 *associated_dev_array = dev;
developer8078acf2023-08-04 18:52:48 +080013364 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
13365 if (res) {
13366 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer46506162023-06-12 10:09:39 +080013367 }
developer8078acf2023-08-04 18:52:48 +080013368
developera3511852023-06-14 14:12:59 +080013369 f = fopen("/tmp/connected_devices.txt", "r");
13370 if (f==NULL)
13371 {
13372 *output_array_size=0;
13373 return RETURN_ERR;
13374 }
13375 while ((getline(&line, &len, f)) != -1)
13376 {
13377 param = strtok(line,"=");
developere75ba632023-06-29 16:03:33 +080013378 if (!param)
13379 continue;
developera3511852023-06-14 14:12:59 +080013380 value = strtok(NULL,"=");
developere75ba632023-06-29 16:03:33 +080013381 if (!value)
13382 continue;
developer72fb0bb2023-01-11 09:46:29 +080013383
developera3511852023-06-14 14:12:59 +080013384 if( strcmp("flags",param) == 0 )
13385 {
13386 value[strlen(value)-1]='\0';
13387 if(strstr (value,"AUTHORIZED") != NULL )
13388 {
13389 dev[auth_temp].cli_AuthenticationState = 1;
13390 dev[auth_temp].cli_Active = 1;
13391 auth_temp++;
13392 read_flag=1;
13393 }
13394 }
13395 if(read_flag==1)
13396 {
13397 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
13398 {
13399 value[strlen(value)-1]='\0';
developere75ba632023-06-29 16:03:33 +080013400 if (sscanf(value, "%x:%x:%x:%x:%x:%x",
developera3511852023-06-14 14:12:59 +080013401 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
13402 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
13403 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
13404 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
13405 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
developere75ba632023-06-29 16:03:33 +080013406 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] ) == EOF)
13407 continue;
developera3511852023-06-14 14:12:59 +080013408 mac_temp++;
13409 read_flag=0;
13410 }
13411 }
13412 }
13413 *output_array_size = auth_temp;
13414 auth_temp=0;
13415 mac_temp=0;
13416 free(line);
developere75ba632023-06-29 16:03:33 +080013417 if (fclose(f) == EOF) {
13418 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
13419 return RETURN_ERR;
13420 }
developera3511852023-06-14 14:12:59 +080013421 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13422 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013423}
13424
13425#define MACADDRESS_SIZE 6
13426
13427INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
13428{
developera3511852023-06-14 14:12:59 +080013429 FILE *fp = NULL;
13430 char str[MAX_BUF_SIZE] = {0};
13431 int wificlientindex = 0 ;
13432 int count = 0;
13433 int signalstrength = 0;
13434 int arr[MACADDRESS_SIZE] = {0};
13435 unsigned char mac[MACADDRESS_SIZE] = {0};
13436 UINT wifi_count = 0;
developere40952c2023-06-15 18:46:43 +080013437 int res;
developerc14d83a2023-06-29 20:09:42 +080013438 wifi_associated_dev3_t* temp = NULL;
developer72fb0bb2023-01-11 09:46:29 +080013439
developera3511852023-06-14 14:12:59 +080013440 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13441 *output_array_size = 0;
13442 *associated_dev_array = NULL;
developer72fb0bb2023-01-11 09:46:29 +080013443
developer33f13ba2023-07-12 16:19:06 +080013444 fp = v_secure_popen("r", "iw dev %s station dump | grep %s | wc -l",
13445 interface_name, interface_name);
developera3511852023-06-14 14:12:59 +080013446 if (fp == NULL)
13447 {
13448 printf("Failed to run command inside function %s\n",__FUNCTION__ );
13449 return RETURN_ERR;
13450 }
developer72fb0bb2023-01-11 09:46:29 +080013451
developera3511852023-06-14 14:12:59 +080013452 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080013453 if (fgets(str, sizeof(str)-1, fp) == NULL) {
13454 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer33f13ba2023-07-12 16:19:06 +080013455 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080013456 return RETURN_ERR;
13457 }
developera3511852023-06-14 14:12:59 +080013458 wifi_count = (unsigned int) atoi ( str );
13459 *output_array_size = wifi_count;
13460 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
developer33f13ba2023-07-12 16:19:06 +080013461 v_secure_pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080013462
developera3511852023-06-14 14:12:59 +080013463 if(wifi_count == 0)
13464 {
13465 return RETURN_OK;
13466 }
13467 else
13468 {
developer9ce44382023-06-28 11:09:37 +080013469 if(wifi_count <= 0 || wifi_count > MAX_ASSOCIATED_STA_NUM){
13470 return RETURN_ERR;
13471 }
developera3511852023-06-14 14:12:59 +080013472 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
13473 if(temp == NULL)
13474 {
13475 printf("Error Statement. Insufficient memory \n");
13476 return RETURN_ERR;
13477 }
developer72fb0bb2023-01-11 09:46:29 +080013478
developer33f13ba2023-07-12 16:19:06 +080013479 res = v_secure_system("iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
13480 if (res) {
13481 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developer9ce44382023-06-28 11:09:37 +080013482 free(temp);
developere40952c2023-06-15 18:46:43 +080013483 return RETURN_ERR;
13484 }
developer33f13ba2023-07-12 16:19:06 +080013485
developera3511852023-06-14 14:12:59 +080013486 if(apIndex == 0)
developer33f13ba2023-07-12 16:19:06 +080013487 res = v_secure_system("iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
developera3511852023-06-14 14:12:59 +080013488 else if(apIndex == 1)
developer33f13ba2023-07-12 16:19:06 +080013489 res = v_secure_system("iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
13490 if (res) {
13491 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developer9ce44382023-06-28 11:09:37 +080013492 free(temp);
developere40952c2023-06-15 18:46:43 +080013493 return RETURN_ERR;
13494 }
developer72fb0bb2023-01-11 09:46:29 +080013495
developera3511852023-06-14 14:12:59 +080013496 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
13497 if(fp == NULL)
13498 {
13499 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
13500 free(temp);
13501 return RETURN_ERR;
13502 }
developere75ba632023-06-29 16:03:33 +080013503 if (fclose(fp) == EOF) {
13504 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developerc14d83a2023-06-29 20:09:42 +080013505 free(temp);
developere75ba632023-06-29 16:03:33 +080013506 return RETURN_ERR;
13507 }
developer72fb0bb2023-01-11 09:46:29 +080013508
developer33f13ba2023-07-12 16:19:06 +080013509 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
developera3511852023-06-14 14:12:59 +080013510 if(fp)
13511 {
13512 for(count =0 ; count < wifi_count; count++)
13513 {
developer86035662023-06-28 19:21:12 +080013514 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13515 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013516 goto err;
developer86035662023-06-28 19:21:12 +080013517 }
developera3511852023-06-14 14:12:59 +080013518 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
13519 {
13520 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
13521 {
13522 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080013523
developera3511852023-06-14 14:12:59 +080013524 }
13525 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
13526 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]);
13527 }
13528 temp[count].cli_AuthenticationState = 1; //TODO
13529 temp[count].cli_Active = 1; //TODO
13530 }
developer33f13ba2023-07-12 16:19:06 +080013531 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080013532 }
13533
developer33f13ba2023-07-12 16:19:06 +080013534 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
developera3511852023-06-14 14:12:59 +080013535 if(fp)
13536 {
developer33f13ba2023-07-12 16:19:06 +080013537 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013538 }
developer33f13ba2023-07-12 16:19:06 +080013539 fp = v_secure_popen("r", "cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013540 if(fp)
13541 {
13542 for(count =0 ; count < wifi_count ;count++)
13543 {
developer86035662023-06-28 19:21:12 +080013544 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13545 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013546 goto err;
developer86035662023-06-28 19:21:12 +080013547 }
developera3511852023-06-14 14:12:59 +080013548 signalstrength = atoi(str);
13549 temp[count].cli_SignalStrength = signalstrength;
13550 temp[count].cli_RSSI = signalstrength;
13551 temp[count].cli_SNR = signalstrength + 95;
13552 }
developer33f13ba2023-07-12 16:19:06 +080013553 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013554 }
developer72fb0bb2023-01-11 09:46:29 +080013555
13556
developera3511852023-06-14 14:12:59 +080013557 if((apIndex == 0) || (apIndex == 4))
13558 {
13559 for(count =0 ; count < wifi_count ;count++)
13560 {
developer32f2a182023-06-27 19:50:41 +080013561 memcpy(temp[count].cli_OperatingStandard,"g", 1);
13562 temp[count].cli_OperatingStandard[1] = '\0';
13563 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
13564 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080013565 }
developer72fb0bb2023-01-11 09:46:29 +080013566
developera3511852023-06-14 14:12:59 +080013567 //BytesSent
developer33f13ba2023-07-12 16:19:06 +080013568 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
developera3511852023-06-14 14:12:59 +080013569 if(fp)
13570 {
developer33f13ba2023-07-12 16:19:06 +080013571 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013572 }
developer33f13ba2023-07-12 16:19:06 +080013573 fp = v_secure_popen("r", "cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013574 if(fp)
13575 {
13576 for (count = 0; count < wifi_count; count++)
13577 {
developer86035662023-06-28 19:21:12 +080013578 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13579 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer33f13ba2023-07-12 16:19:06 +080013580 v_secure_pclose(fp);
developerc14d83a2023-06-29 20:09:42 +080013581 free(temp);
developer86035662023-06-28 19:21:12 +080013582 return RETURN_ERR;
developer5b23cd02023-07-19 20:26:03 +080013583 }
developerc14d83a2023-06-29 20:09:42 +080013584 if (hal_strtoul(str, 10, &(temp[count].cli_BytesSent)) < 0) {
13585 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013586 }
developera3511852023-06-14 14:12:59 +080013587 }
developer33f13ba2023-07-12 16:19:06 +080013588 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013589 }
developer72fb0bb2023-01-11 09:46:29 +080013590
developera3511852023-06-14 14:12:59 +080013591 //BytesReceived
developer86035662023-06-28 19:21:12 +080013592
developer33f13ba2023-07-12 16:19:06 +080013593 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
developera3511852023-06-14 14:12:59 +080013594 if (fp)
13595 {
developer33f13ba2023-07-12 16:19:06 +080013596 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013597 }
developer33f13ba2023-07-12 16:19:06 +080013598 fp = v_secure_popen("r", "cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013599 if (fp)
13600 {
13601 for (count = 0; count < wifi_count; count++)
13602 {
developer86035662023-06-28 19:21:12 +080013603 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13604 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013605 goto err;
13606 }
13607 if (hal_strtoul(str, 10, &(temp[count].cli_BytesReceived)) < 0) {
13608 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013609 }
developera3511852023-06-14 14:12:59 +080013610 }
developer33f13ba2023-07-12 16:19:06 +080013611 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013612 }
developer72fb0bb2023-01-11 09:46:29 +080013613
developera3511852023-06-14 14:12:59 +080013614 //PacketsSent
developer33f13ba2023-07-12 16:19:06 +080013615 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
developera3511852023-06-14 14:12:59 +080013616 if (fp)
13617 {
developer33f13ba2023-07-12 16:19:06 +080013618 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013619 }
developer72fb0bb2023-01-11 09:46:29 +080013620
developer33f13ba2023-07-12 16:19:06 +080013621 fp = v_secure_popen("r", "cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013622 if (fp)
13623 {
13624 for (count = 0; count < wifi_count; count++)
13625 {
developer86035662023-06-28 19:21:12 +080013626 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13627 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013628 goto err;
developer5b23cd02023-07-19 20:26:03 +080013629 }
developerc14d83a2023-06-29 20:09:42 +080013630 if (hal_strtoul(str, 10, &(temp[count].cli_PacketsSent)) < 0) {
13631 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013632 }
developera3511852023-06-14 14:12:59 +080013633 }
developer33f13ba2023-07-12 16:19:06 +080013634 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013635 }
developer72fb0bb2023-01-11 09:46:29 +080013636
developera3511852023-06-14 14:12:59 +080013637 //PacketsReceived
developer33f13ba2023-07-12 16:19:06 +080013638 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
developera3511852023-06-14 14:12:59 +080013639 if (fp)
13640 {
developer33f13ba2023-07-12 16:19:06 +080013641 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013642 }
developer33f13ba2023-07-12 16:19:06 +080013643 fp = v_secure_popen("r", "cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013644 if (fp)
13645 {
13646 for (count = 0; count < wifi_count; count++)
13647 {
developer86035662023-06-28 19:21:12 +080013648 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13649 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013650 goto err;
developer5b23cd02023-07-19 20:26:03 +080013651 }
developerc14d83a2023-06-29 20:09:42 +080013652 if (hal_strtoul(str, 10, &(temp[count].cli_PacketsReceived)) < 0) {
13653 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013654 }
developera3511852023-06-14 14:12:59 +080013655 }
developer33f13ba2023-07-12 16:19:06 +080013656 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013657 }
developer72fb0bb2023-01-11 09:46:29 +080013658
developera3511852023-06-14 14:12:59 +080013659 //ErrorsSent
developer33f13ba2023-07-12 16:19:06 +080013660 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
developera3511852023-06-14 14:12:59 +080013661 if (fp)
13662 {
developer33f13ba2023-07-12 16:19:06 +080013663 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013664 }
developer33f13ba2023-07-12 16:19:06 +080013665 fp = v_secure_popen("r", "cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013666 if (fp)
13667 {
13668 for (count = 0; count < wifi_count; count++)
13669 {
developer86035662023-06-28 19:21:12 +080013670 if (fgets(str, MAX_BUF_SIZE, fp) == NULL){
13671 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013672 goto err;
developer5b23cd02023-07-19 20:26:03 +080013673 }
developerc14d83a2023-06-29 20:09:42 +080013674 if (hal_strtoul(str, 10, &(temp[count].cli_ErrorsSent)) < 0) {
13675 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013676 }
developera3511852023-06-14 14:12:59 +080013677 }
developer33f13ba2023-07-12 16:19:06 +080013678 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013679 }
developer72fb0bb2023-01-11 09:46:29 +080013680
developera3511852023-06-14 14:12:59 +080013681 //ErrorsSent
developer86035662023-06-28 19:21:12 +080013682
developer33f13ba2023-07-12 16:19:06 +080013683 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
developera3511852023-06-14 14:12:59 +080013684 if (fp)
13685 {
developer33f13ba2023-07-12 16:19:06 +080013686 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013687 }
developer33f13ba2023-07-12 16:19:06 +080013688 fp = v_secure_popen("r", "cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013689 if (fp)
13690 {
13691 for (count = 0; count < wifi_count; count++)
13692 {
developer86035662023-06-28 19:21:12 +080013693 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13694 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013695 goto err;
developer5b23cd02023-07-19 20:26:03 +080013696 }
developerc14d83a2023-06-29 20:09:42 +080013697 if (hal_strtoul(str, 10, &(temp[count].cli_ErrorsSent)) < 0) {
13698 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013699 }
developera3511852023-06-14 14:12:59 +080013700 }
developer33f13ba2023-07-12 16:19:06 +080013701 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013702 }
developer72fb0bb2023-01-11 09:46:29 +080013703
developera3511852023-06-14 14:12:59 +080013704 //LastDataDownlinkRate
developer33f13ba2023-07-12 16:19:06 +080013705 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
developera3511852023-06-14 14:12:59 +080013706 if (fp)
13707 {
developer33f13ba2023-07-12 16:19:06 +080013708 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013709 }
developer33f13ba2023-07-12 16:19:06 +080013710 fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013711 if (fp)
developer5b23cd02023-07-19 20:26:03 +080013712 {
developerc14d83a2023-06-29 20:09:42 +080013713 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080013714 for (count = 0; count < wifi_count; count++)
13715 {
developer86035662023-06-28 19:21:12 +080013716 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13717 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013718 goto err;
13719 }
developer5b23cd02023-07-19 20:26:03 +080013720
developerc14d83a2023-06-29 20:09:42 +080013721 if (hal_strtoul(str, 10, &tmp_u) < 0) {
13722 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013723 }
developerc14d83a2023-06-29 20:09:42 +080013724 temp[count].cli_LastDataDownlinkRate = tmp_u;
developera3511852023-06-14 14:12:59 +080013725 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
13726 }
developer33f13ba2023-07-12 16:19:06 +080013727 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013728 }
developer72fb0bb2023-01-11 09:46:29 +080013729
developera3511852023-06-14 14:12:59 +080013730 //LastDataUplinkRate
developer33f13ba2023-07-12 16:19:06 +080013731 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
developera3511852023-06-14 14:12:59 +080013732 if (fp)
13733 {
developer33f13ba2023-07-12 16:19:06 +080013734 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013735 }
developer33f13ba2023-07-12 16:19:06 +080013736 fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080013737 if (fp)
13738 {
developerc14d83a2023-06-29 20:09:42 +080013739 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080013740 for (count = 0; count < wifi_count; count++)
13741 {
developer86035662023-06-28 19:21:12 +080013742 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13743 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080013744 goto err;
13745 }
13746 if (hal_strtoul(str, 10, &tmp_u) < 0) {
13747 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer86035662023-06-28 19:21:12 +080013748 }
developerc14d83a2023-06-29 20:09:42 +080013749 temp[count].cli_LastDataUplinkRate = tmp_u;
13750
developera3511852023-06-14 14:12:59 +080013751 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
13752 }
developer33f13ba2023-07-12 16:19:06 +080013753 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080013754 }
developer72fb0bb2023-01-11 09:46:29 +080013755
developera3511852023-06-14 14:12:59 +080013756 }
13757 else if ((apIndex == 1) || (apIndex == 5))
13758 {
13759 for (count = 0; count < wifi_count; count++)
13760 {
developer32f2a182023-06-27 19:50:41 +080013761 memcpy(temp[count].cli_OperatingStandard, "a", 1);
13762 temp[count].cli_OperatingStandard[1] = '\0';
13763 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
13764 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080013765 temp[count].cli_BytesSent = 0;
13766 temp[count].cli_BytesReceived = 0;
13767 temp[count].cli_LastDataUplinkRate = 0;
13768 temp[count].cli_LastDataDownlinkRate = 0;
13769 temp[count].cli_PacketsSent = 0;
13770 temp[count].cli_PacketsReceived = 0;
13771 temp[count].cli_ErrorsSent = 0;
13772 }
13773 }
developer72fb0bb2023-01-11 09:46:29 +080013774
developera3511852023-06-14 14:12:59 +080013775 for (count = 0; count < wifi_count; count++)
13776 {
13777 temp[count].cli_Retransmissions = 0;
13778 temp[count].cli_DataFramesSentAck = 0;
13779 temp[count].cli_DataFramesSentNoAck = 0;
13780 temp[count].cli_MinRSSI = 0;
13781 temp[count].cli_MaxRSSI = 0;
13782 strncpy(temp[count].cli_InterferenceSources, "", 64);
13783 memset(temp[count].cli_IPAddress, 0, 64);
13784 temp[count].cli_RetransCount = 0;
13785 temp[count].cli_FailedRetransCount = 0;
13786 temp[count].cli_RetryCount = 0;
13787 temp[count].cli_MultipleRetryCount = 0;
13788 }
13789 *associated_dev_array = temp;
13790 }
13791 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13792 return RETURN_OK;
developerc14d83a2023-06-29 20:09:42 +080013793err:
13794 if (temp)
13795 free(temp);
developer8078acf2023-08-04 18:52:48 +080013796 v_secure_pclose(fp);
developerc14d83a2023-06-29 20:09:42 +080013797 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013798}
13799
developer7e4a2a62023-04-06 19:56:03 +080013800int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +080013801{
developer7e4a2a62023-04-06 19:56:03 +080013802 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080013803 int res;
developer32f2a182023-06-27 19:50:41 +080013804 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080013805
developera3511852023-06-14 14:12:59 +080013806 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080013807
developer8078acf2023-08-04 18:52:48 +080013808 res = _syscmd_secure(buf, MAX_BUF_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +080013809 interface_name);
developer8078acf2023-08-04 18:52:48 +080013810 if (res) {
13811 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080013812 }
13813
developer32f2a182023-06-27 19:50:41 +080013814 len = strlen(buf);
13815 if (len >= sizeof(buf)) {
13816 wifi_debug(DEBUG_ERROR, "Unexpected buf size\n");
13817 return RETURN_ERR;
13818 }
13819 strncpy(wifi_status, buf, len); /* TBD: check wifi_status mem lenth and replace with strcpy later */
13820 wifi_status[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080013821
developera3511852023-06-14 14:12:59 +080013822 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
13823 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013824}
13825
developer72fb0bb2023-01-11 09:46:29 +080013826static const char *get_line_from_str_buf(const char *buf, char *line)
13827{
developera3511852023-06-14 14:12:59 +080013828 int i;
13829 int n = strlen(buf);
developer72fb0bb2023-01-11 09:46:29 +080013830
developera3511852023-06-14 14:12:59 +080013831 for (i = 0; i < n; i++) {
13832 line[i] = buf[i];
13833 if (buf[i] == '\n') {
13834 line[i] = '\0';
13835 return &buf[i + 1];
13836 }
13837 }
developer72fb0bb2023-01-11 09:46:29 +080013838
developera3511852023-06-14 14:12:59 +080013839 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080013840}
13841
developer6f35aa12023-11-13 14:52:39 +080013842int mtk_get_station_callback(struct nl_msg *msg, void *cb)
13843{
13844 struct nlattr *tb[NL80211_ATTR_MAX + 1];
13845 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_ATTR_MAX + 1];
13846 struct genlmsghdr *gnlh;
13847 int err = 0;
13848 unsigned short len = 0;
13849 struct station_information *sta;
13850 struct mtk_nl80211_cb_data *cb_data = cb;
13851 if (!msg || !cb_data) {
13852 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
13853 return NL_SKIP;
13854 }
13855
13856 gnlh = nlmsg_data(nlmsg_hdr(msg));
13857 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
13858 genlmsg_attrlen(gnlh, 0), NULL);
13859 if (err < 0) {
13860 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
13861 return NL_SKIP;
13862 }
13863 if (tb[NL80211_ATTR_VENDOR_DATA]) {
13864 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_STA_ATTR_MAX,
13865 tb[NL80211_ATTR_VENDOR_DATA], NULL);
13866 if (err < 0)
13867 return NL_SKIP;
13868 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_INFO]) {
13869 len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_INFO]);
13870 sta = (struct station_information*)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_INFO]);
13871 if (len != sizeof(*sta)){
13872 wifi_debug(DEBUG_ERROR,"result len(%u) is invalid, expected len(%lu)!!!\n", len, sizeof(*sta));
13873 return NL_SKIP;
13874 }
13875 memcpy(cb_data->out_buf, sta, len);
13876 } else
13877 wifi_debug(DEBUG_ERROR, "no MTK_NL80211_VENDOR_ATTR_STA_INFO attr\n");
13878 } else
13879 wifi_debug(DEBUG_ERROR, "no any station result from driver\n");
13880 return NL_OK;
13881}
13882INT station_info_2_dev3(struct station_information *sta, wifi_associated_dev3_t *dev3)
13883{
13884 int i = 0, n = 0;
13885
13886 dev3->cli_LastDataDownlinkRate = sta->rx_rate;
13887 dev3->cli_LastDataUplinkRate = sta->tx_rate;
13888 dev3->cli_SNR = sta->snr[0];
13889 dev3->cli_BytesReceived = sta->rx_bytes;
13890 dev3->cli_BytesSent = sta->tx_bytes;
13891 for (i = 0; i < 4; i++) {
13892 if (sta->rssi[0] == -127)
13893 continue;
13894 dev3->cli_RSSI += sta->rssi[i];
13895 n++;
13896 }
13897 dev3->cli_RSSI = dev3->cli_RSSI/n;
13898 dev3->cli_PacketsReceived = sta->rx_packets;
13899 dev3->cli_PacketsSent = sta->tx_packets;
13900 dev3->mld_enable = sta->mlo_enable;
13901 memcpy(dev3->mld_addr, sta->mld_mac, 6);
13902 for (i = 0; i < 3; i++) {
13903 dev3->mld_link_info[i].valid = sta->mlo_link[i].valid;
13904 if (!dev3->mld_link_info[i].valid)
13905 continue;
13906 memcpy(dev3->mld_link_info[i].link_addr, sta->mlo_link[i].link_address, 6);
13907 dev3->mld_link_info[i].rssi = sta->mlo_link[i].rssi[0];
13908 dev3->mld_link_info[i].rx_bytes = sta->mlo_link[i].rx_bytes;
13909 dev3->mld_link_info[i].tx_bytes = sta->mlo_link[i].tx_bytes;
13910 dev3->mld_link_info[i].rx_rate = sta->mlo_link[i].rx_rate;
13911 dev3->mld_link_info[i].tx_rate = sta->mlo_link[i].tx_rate;
13912 }
13913
13914 return RETURN_OK;
13915}
13916
13917INT fill_dev3_statistics_by_mac(INT apIndex, wifi_associated_dev3_t *dev3, unsigned char *mac)
13918{
13919 char inf_name[IF_NAME_SIZE] = {0};
13920 unsigned int if_idx = 0;
13921 int ret = -1;
13922 struct unl unl_ins;
13923 struct nl_msg *msg = NULL;
13924 struct nlattr * msg_data = NULL;
13925 struct mtk_nl80211_param nl_param;
13926 struct mtk_nl80211_cb_data cb_data;
13927 struct station_information station;
13928
13929 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
13930 return RETURN_ERR;
13931
13932 if_idx = if_nametoindex(inf_name);
13933 if (!if_idx) {
13934 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
13935 return RETURN_ERR;
13936 }
13937 /*init mtk nl80211 vendor cmd*/
13938 nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STA;
13939 nl_param.if_type = NL80211_ATTR_IFINDEX;
13940 nl_param.if_idx = if_idx;
13941
13942 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_param);
13943 if (ret) {
13944 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
13945 return RETURN_ERR;
13946 }
13947 /*add mtk vendor cmd data*/
13948 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_STA_MAC, ETH_ALEN, mac)) {
13949 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
13950 nlmsg_free(msg);
13951 mtk_nl80211_deint(&unl_ins);
13952 return RETURN_ERR;
13953 }
13954 cb_data.out_buf = (void*)&station;
13955
13956 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_station_callback, &cb_data);
13957 if (ret) {
13958 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
13959 mtk_nl80211_deint(&unl_ins);
13960 return RETURN_ERR;
13961 }
13962 station_info_2_dev3(&station, dev3);
13963 /*deinit mtk nl80211 vendor msg*/
13964 mtk_nl80211_deint(&unl_ins);
13965
13966 return RETURN_OK;
13967}
13968
developer72fb0bb2023-01-11 09:46:29 +080013969INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
13970{
developera3511852023-06-14 14:12:59 +080013971 char interface_name[16] = {0};
13972 FILE *f = NULL;
13973 int auth_temp= -1;
developer8078acf2023-08-04 18:52:48 +080013974 char buf[2048] = {0};
developera3511852023-06-14 14:12:59 +080013975 char *param = NULL, *value = NULL, *line=NULL;
13976 size_t len = 0;
13977 wifi_associated_dev3_t *dev=NULL;
developer6f35aa12023-11-13 14:52:39 +080013978 int res, i;
developer72fb0bb2023-01-11 09:46:29 +080013979
developera3511852023-06-14 14:12:59 +080013980 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13981 *associated_dev_array = NULL;
13982 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13983 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080013984
developer8078acf2023-08-04 18:52:48 +080013985 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
13986 if (res) {
13987 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080013988 }
13989
developera3511852023-06-14 14:12:59 +080013990 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080013991
developera3511852023-06-14 14:12:59 +080013992 if (*output_array_size <= 0)
13993 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013994
developera3511852023-06-14 14:12:59 +080013995 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
developer86035662023-06-28 19:21:12 +080013996
13997 if (dev == NULL) {
13998 wifi_debug(DEBUG_ERROR, "calloc fail\n");
13999 return RETURN_ERR;
14000 }
developera3511852023-06-14 14:12:59 +080014001 *associated_dev_array = dev;
developer8078acf2023-08-04 18:52:48 +080014002 res = _syscmd_secure(buf, sizeof(buf),
developer32f2a182023-06-27 19:50:41 +080014003 "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
developer8078acf2023-08-04 18:52:48 +080014004 if (res) {
14005 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developer75bd10c2023-06-27 11:34:08 +080014006 }
14007
developera3511852023-06-14 14:12:59 +080014008 f = fopen("/tmp/diagnostic3_devices.txt", "r");
14009 if (f == NULL)
14010 {
14011 *output_array_size=0;
14012 return RETURN_ERR;
14013 }
14014 while ((getline(&line, &len, f)) != -1)
14015 {
14016 param = strtok(line, "=");
developere75ba632023-06-29 16:03:33 +080014017 if (!param)
14018 continue;
developera3511852023-06-14 14:12:59 +080014019 value = strtok(NULL, "=");
developere75ba632023-06-29 16:03:33 +080014020 if (!value)
14021 continue;
developer72fb0bb2023-01-11 09:46:29 +080014022
developera3511852023-06-14 14:12:59 +080014023 if( strcmp("flags",param) == 0 )
14024 {
14025 value[strlen(value)-1]='\0';
14026 if(strstr (value,"AUTHORIZED") != NULL )
14027 {
14028 auth_temp++;
14029 dev[auth_temp].cli_AuthenticationState = 1;
14030 dev[auth_temp].cli_Active = 1;
14031 }
14032 } else if (auth_temp < 0) {
14033 continue;
14034 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
14035 {
14036 value[strlen(value)-1]='\0';
developere75ba632023-06-29 16:03:33 +080014037 if (sscanf(value, "%x:%x:%x:%x:%x:%x",
14038 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
14039 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
14040 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
14041 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
14042 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
14043 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]) == EOF)
14044 continue;
developera3511852023-06-14 14:12:59 +080014045 } else if (strcmp("signal", param) == 0) {
14046 value[strlen(value)-1]='\0';
developere75ba632023-06-29 16:03:33 +080014047 if (sscanf(value, "%d", &dev[auth_temp].cli_RSSI) == EOF)
14048 continue;
developera3511852023-06-14 14:12:59 +080014049 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
14050 }
14051 }
developer0d26f2c2023-05-25 19:46:36 +080014052 if (line)
developera3511852023-06-14 14:12:59 +080014053 free(line);
developerc14d83a2023-06-29 20:09:42 +080014054
14055 if (fclose(f) != 0) {
14056 wifi_debug(DEBUG_ERROR, "fclose fail\n");
14057 }
14058
developer6f35aa12023-11-13 14:52:39 +080014059 for (i = 0; i < *output_array_size; i++) {
14060 if (fill_dev3_statistics_by_mac(apIndex, &dev[i], dev[i].cli_MACAddress)) {
14061 wifi_debug(DEBUG_ERROR, "fail to get dev3(%02x:%02x:%02x:%02x:%02x:%02x)"
14062 " statistic information from logan driver\n", dev[i].cli_MACAddress[0],
14063 dev[i].cli_MACAddress[1], dev[i].cli_MACAddress[2], dev[i].cli_MACAddress[3],
14064 dev[i].cli_MACAddress[4], dev[i].cli_MACAddress[5]);
14065 continue;
14066 }
14067 }
14068
developera3511852023-06-14 14:12:59 +080014069 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14070 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014071}
developer72fb0bb2023-01-11 09:46:29 +080014072
14073/* getIPAddress function */
14074/**
14075* @description Returning IpAddress of the Matched String
14076*
developer69b61b02023-03-07 17:17:44 +080014077* @param
developer72fb0bb2023-01-11 09:46:29 +080014078* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080014079* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080014080* @return The status of the operation
14081* @retval RETURN_OK if successful
14082* @retval RETURN_ERR if any error is detected
14083*
14084*/
14085
14086INT getIPAddress(char *str,char *ipaddr)
14087{
developera3511852023-06-14 14:12:59 +080014088 FILE *fp = NULL;
14089 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
14090 int LeaseTime = 0,ret = 0;
developer32f2a182023-06-27 19:50:41 +080014091 unsigned long len;
14092
developera3511852023-06-14 14:12:59 +080014093 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
14094 {
14095 return RETURN_ERR;
14096 }
developer72fb0bb2023-01-11 09:46:29 +080014097
developera3511852023-06-14 14:12:59 +080014098 while ( fgets(buf, sizeof(buf), fp)!= NULL )
14099 {
14100 /*
14101 Sample:sss
14102 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
14103 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
14104 */
14105 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
14106 &(LeaseTime),
14107 phyAddr,
14108 ipAddr,
14109 hostName
14110 );
14111 if(ret != 4)
14112 continue;
developer32f2a182023-06-27 19:50:41 +080014113 if (strcmp(str,phyAddr) == 0) {
14114 len = strlen(ipAddr);
14115 strncpy(ipaddr, ipAddr, len);
14116 ipaddr[len] = '\0';
14117 }
developera3511852023-06-14 14:12:59 +080014118 }
developer37646972023-06-29 10:58:43 +080014119 if (fclose(fp) == EOF) {
14120 wifi_debug(DEBUG_ERROR, "fclose fail\n");
14121 return RETURN_ERR;
14122 }
developera3511852023-06-14 14:12:59 +080014123 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014124}
14125
14126/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
14127/**
14128* @description Returning Inactive wireless connected clients informations
14129*
developer69b61b02023-03-07 17:17:44 +080014130* @param
developer72fb0bb2023-01-11 09:46:29 +080014131* @filename Holding private_wifi 2g/5g content files
14132* @associated_dev_array Having inactiv wireless clients informations
14133* @output_array_size Returning Inactive wireless counts
14134* @return The status of the operation
14135* @retval RETURN_OK if successful
14136* @retval RETURN_ERR if any error is detected
14137*
14138*/
14139
14140INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
14141{
developera3511852023-06-14 14:12:59 +080014142 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14143 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
14144 FILE *fp = NULL;
14145 int arr[MACADDRESS_SIZE] = {0};
14146 unsigned char mac[MACADDRESS_SIZE] = {0};
14147 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
developer86035662023-06-28 19:21:12 +080014148 int res;
14149
developer8078acf2023-08-04 18:52:48 +080014150 fp = v_secure_popen("r","cat %s | grep Station | sort | uniq | wc -l",filename);
developera3511852023-06-14 14:12:59 +080014151 if(fp == NULL)
14152 return RETURN_ERR;
14153 else
14154 {
developerd14dff12023-06-28 22:47:44 +080014155 if (fgets(path,sizeof(path),fp) == NULL) {
14156 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080014157 v_secure_pclose(fp);
developerd14dff12023-06-28 22:47:44 +080014158 return RETURN_ERR;
14159 }
developera3511852023-06-14 14:12:59 +080014160 maccount = atoi(path);
14161 }
developer8078acf2023-08-04 18:52:48 +080014162 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080014163 *output_array_size = maccount;
14164 wifi_associated_dev3_t* temp = NULL;
developer9ce44382023-06-28 11:09:37 +080014165 if(*output_array_size > 0 && *output_array_size < MAX_ASSOCIATED_STA_NUM){
14166 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
14167 } else {
14168 return RETURN_ERR;
14169 }
developer37646972023-06-29 10:58:43 +080014170
developera3511852023-06-14 14:12:59 +080014171 *associated_dev_array = temp;
14172 if(temp == NULL)
14173 {
14174 printf("Error Statement. Insufficient memory \n");
14175 return RETURN_ERR;
14176 }
14177 memset(buf,0,sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080014178 res = snprintf(buf, sizeof(buf),
14179 "cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
14180 if (os_snprintf_error(sizeof(buf), res)) {
14181 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14182 return RETURN_ERR;
14183 }
developer8078acf2023-08-04 18:52:48 +080014184 fp = v_secure_popen("r", "cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
developera3511852023-06-14 14:12:59 +080014185 if (fp == NULL) {
developer37646972023-06-29 10:58:43 +080014186 res = fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
14187 if (res < 0) {
14188 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
14189 }
developera3511852023-06-14 14:12:59 +080014190 return RETURN_ERR;
14191 }
14192 for(count = 0; count < maccount ; count++)
14193 {
developer37646972023-06-29 10:58:43 +080014194 if (fgets(path,sizeof(path),fp) == NULL)
14195 continue;
developera3511852023-06-14 14:12:59 +080014196 for(i = 0; path[i]!='\n';i++)
14197 str[i]=path[i];
14198 str[i]='\0';
14199 getIPAddress(str,ipaddr);
developera3511852023-06-14 14:12:59 +080014200 if(strlen(ipaddr) > 0)
14201 {
developer33f13ba2023-07-12 16:19:06 +080014202 if (v_secure_system("ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1", ipaddr)) //InActive wireless clients info
developera3511852023-06-14 14:12:59 +080014203 {
14204 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
14205 {
14206 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
14207 {
14208 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080014209
developera3511852023-06-14 14:12:59 +080014210 }
14211 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
developer37646972023-06-29 10:58:43 +080014212 if (fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],
14213 temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2],
14214 temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4],
14215 temp[count].cli_MACAddress[5]) < 0) {
14216 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
14217 break;
14218 }
developera3511852023-06-14 14:12:59 +080014219 }
14220 temp[count].cli_AuthenticationState = 0; //TODO
14221 temp[count].cli_Active = 0; //TODO
14222 temp[count].cli_SignalStrength = 0;
14223 }
14224 else //Active wireless clients info
14225 {
14226 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
14227 {
14228 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
14229 {
14230 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080014231
developera3511852023-06-14 14:12:59 +080014232 }
14233 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
developer12fb9f62023-06-30 15:26:27 +080014234 wifi_debug(DEBUG_ERROR, "%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]);
developera3511852023-06-14 14:12:59 +080014235 }
14236 temp[count].cli_Active = 1;
14237 }
14238 }
14239 memset(ipaddr,0,sizeof(ipaddr));
14240 }
developer8078acf2023-08-04 18:52:48 +080014241 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080014242 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14243 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014244}
14245//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
14246//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
14247//To get Band Steering Capability
14248INT wifi_getBandSteeringCapability(BOOL *support)
14249{
developera3511852023-06-14 14:12:59 +080014250 *support = FALSE;
14251 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014252}
14253
14254
14255//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
14256//To get Band Steering enable status
14257INT wifi_getBandSteeringEnable(BOOL *enable)
14258{
developera3511852023-06-14 14:12:59 +080014259 *enable = FALSE;
14260 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014261}
14262
14263//To turn on/off Band steering
14264INT wifi_setBandSteeringEnable(BOOL enable)
14265{
developera3511852023-06-14 14:12:59 +080014266 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014267}
14268
14269//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
14270//To get Band Steering AP group
14271INT wifi_getBandSteeringApGroup(char *output_ApGroup)
14272{
developera3511852023-06-14 14:12:59 +080014273 if (NULL == output_ApGroup)
14274 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014275
developer32f2a182023-06-27 19:50:41 +080014276 memcpy(output_ApGroup, "1,2", 3);
14277 output_ApGroup[3] = '\0';
developera3511852023-06-14 14:12:59 +080014278 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014279}
14280
14281//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
14282//to set and read the band steering BandUtilizationThreshold parameters
14283INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
14284{
developera3511852023-06-14 14:12:59 +080014285 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014286}
14287
14288INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
14289{
developera3511852023-06-14 14:12:59 +080014290 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014291}
14292
14293//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
14294//to set and read the band steering RSSIThreshold parameters
14295INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
14296{
developera3511852023-06-14 14:12:59 +080014297 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014298}
14299
14300INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
14301{
developera3511852023-06-14 14:12:59 +080014302 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014303}
14304
14305
14306//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
14307//to set and read the band steering physical modulation rate threshold parameters
14308INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
14309{
developera3511852023-06-14 14:12:59 +080014310 //If chip is not support, return -1
14311 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014312}
14313
14314INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
14315{
developera3511852023-06-14 14:12:59 +080014316 //If chip is not support, return -1
14317 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014318}
14319
14320//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
14321//to set and read the inactivity time (in seconds) for steering under overload condition
14322INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
14323{
developera3511852023-06-14 14:12:59 +080014324 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014325}
14326
14327INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
14328{
developera3511852023-06-14 14:12:59 +080014329 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014330}
14331
14332//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
14333//to set and read the inactivity time (in seconds) for steering under Idle condition
14334INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
14335{
developera3511852023-06-14 14:12:59 +080014336 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014337}
14338
14339INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
14340{
developera3511852023-06-14 14:12:59 +080014341 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014342}
14343
14344//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
14345//pClientMAC[64]
14346//pSourceSSIDIndex[64]
14347//pDestSSIDIndex[64]
14348//pSteeringReason[256]
14349INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
14350{
developera3511852023-06-14 14:12:59 +080014351 //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
developer12fb9f62023-06-30 15:26:27 +080014352 long int tim_tmp = time(NULL);
14353 if (tim_tmp < 0)
14354 return RETURN_ERR;
14355 *pSteeringTime = tim_tmp;
developera3511852023-06-14 14:12:59 +080014356 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
14357 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014358}
14359
14360INT wifi_ifConfigDown(INT apIndex)
14361{
developera3511852023-06-14 14:12:59 +080014362 INT status = RETURN_OK;
14363 char cmd[64];
developere40952c2023-06-15 18:46:43 +080014364 int res;
developer72fb0bb2023-01-11 09:46:29 +080014365
developer33f13ba2023-07-12 16:19:06 +080014366 res = v_secure_system("ifconfig ath%d down", apIndex);
14367 if (res) {
14368 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developere40952c2023-06-15 18:46:43 +080014369 return RETURN_ERR;
14370 }
developera3511852023-06-14 14:12:59 +080014371 printf("%s: %s\n", __func__, cmd);
developer72fb0bb2023-01-11 09:46:29 +080014372
developera3511852023-06-14 14:12:59 +080014373 return status;
developer72fb0bb2023-01-11 09:46:29 +080014374}
14375
14376INT wifi_ifConfigUp(INT apIndex)
14377{
developera3511852023-06-14 14:12:59 +080014378 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080014379 char buf[1024];
developere40952c2023-06-15 18:46:43 +080014380 int res;
developer72fb0bb2023-01-11 09:46:29 +080014381
developera3511852023-06-14 14:12:59 +080014382 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14383 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080014384 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up 2>/dev/null", interface_name);
14385 if (res) {
14386 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080014387 }
developera3511852023-06-14 14:12:59 +080014388 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014389}
14390
14391//>> Deprecated. Replace with wifi_applyRadioSettings
14392INT wifi_pushBridgeInfo(INT apIndex)
14393{
developerb2977562023-05-24 17:54:12 +080014394 char ip[32] = {0};
14395 char subnet[32] = {0};
14396 char bridge[32] = {0};
developerb2977562023-05-24 17:54:12 +080014397 char buf[1024] = {0};
developere40952c2023-06-15 18:46:43 +080014398 int res;
developer72fb0bb2023-01-11 09:46:29 +080014399
developerb2977562023-05-24 17:54:12 +080014400 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080014401
developer8078acf2023-08-04 18:52:48 +080014402 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
14403 if (res) {
14404 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080014405 }
developer72fb0bb2023-01-11 09:46:29 +080014406
developerb2977562023-05-24 17:54:12 +080014407 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014408}
14409
14410INT wifi_pushChannel(INT radioIndex, UINT channel)
14411{
developera3511852023-06-14 14:12:59 +080014412 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080014413 char buf[1024];
developere40952c2023-06-15 18:46:43 +080014414 int res;
developerc3556192023-12-06 17:59:09 +080014415 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080014416
developerc3556192023-12-06 17:59:09 +080014417 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
14418 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
14419 return RETURN_ERR;
14420 }
14421
14422 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080014423 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080014424 res = _syscmd_secure(buf, sizeof(buf), "iwconfig %s freq %d",interface_name,channel);
14425 if (res) {
14426 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080014427 }
developer72fb0bb2023-01-11 09:46:29 +080014428
developera3511852023-06-14 14:12:59 +080014429 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014430}
14431
14432INT wifi_pushChannelMode(INT radioIndex)
14433{
developera3511852023-06-14 14:12:59 +080014434 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
14435 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014436}
14437
14438INT wifi_pushDefaultValues(INT radioIndex)
14439{
developera3511852023-06-14 14:12:59 +080014440 //Apply Comcast specified default radio settings instantly
14441 //AMPDU=1
14442 //AMPDUFrames=32
14443 //AMPDULim=50000
14444 //txqueuelen=1000
developer72fb0bb2023-01-11 09:46:29 +080014445
developera3511852023-06-14 14:12:59 +080014446 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014447}
14448
14449INT wifi_pushTxChainMask(INT radioIndex)
14450{
developera3511852023-06-14 14:12:59 +080014451 //Apply default TxChainMask instantly
14452 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014453}
14454
14455INT wifi_pushRxChainMask(INT radioIndex)
14456{
developera3511852023-06-14 14:12:59 +080014457 //Apply default RxChainMask instantly
14458 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014459}
14460
14461INT wifi_pushSSID(INT apIndex, CHAR *ssid)
14462{
developer7e4a2a62023-04-06 19:56:03 +080014463 INT status;
developer72fb0bb2023-01-11 09:46:29 +080014464
developer7e4a2a62023-04-06 19:56:03 +080014465 status = wifi_setSSIDName(apIndex, ssid);
14466 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080014467
developer7e4a2a62023-04-06 19:56:03 +080014468 return status;
developer72fb0bb2023-01-11 09:46:29 +080014469}
14470
14471INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
14472{
developera3511852023-06-14 14:12:59 +080014473 int ret;
developerc1aa6532023-06-09 09:37:01 +080014474 ret = wifi_setApSsidAdvertisementEnable(apIndex, enable);
14475
14476 return ret;
developer72fb0bb2023-01-11 09:46:29 +080014477}
14478
14479INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
14480{
developerd52547a2023-12-26 20:01:42 +080014481 ULONG currentTime;
14482 struct timeval tv_now;
developere82c0ca2023-05-10 16:25:35 +080014483
developerd52547a2023-12-26 20:01:42 +080014484 gettimeofday(&tv_now, NULL);
14485 currentTime = tv_now.tv_sec;
14486
14487 if (currentTime >= radio_up_time[radioIndex]) {
14488 *output = currentTime - radio_up_time[radioIndex];
developere82c0ca2023-05-10 16:25:35 +080014489 }
developerd52547a2023-12-26 20:01:42 +080014490 else {
14491 *output = 0xFFFFFFFFUL - radio_up_time[radioIndex] + currentTime;
14492 }
developere82c0ca2023-05-10 16:25:35 +080014493
developera3511852023-06-14 14:12:59 +080014494 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014495}
14496
14497INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
14498{
developera3511852023-06-14 14:12:59 +080014499 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014500}
14501
14502INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
14503{
developera3511852023-06-14 14:12:59 +080014504 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014505}
14506
14507//To-do
14508INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
14509{
developera3511852023-06-14 14:12:59 +080014510 char output[16]={'\0'};
14511 char config_file[MAX_BUF_SIZE] = {0};
14512 int res;
developer72fb0bb2023-01-11 09:46:29 +080014513
developera3511852023-06-14 14:12:59 +080014514 if (!output_string)
14515 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014516
developera3511852023-06-14 14:12:59 +080014517 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14518 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080014519 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14520 return RETURN_ERR;
14521 }
developera3511852023-06-14 14:12:59 +080014522 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080014523
developera3511852023-06-14 14:12:59 +080014524 if (strlen(output) == 0)
developere40952c2023-06-15 18:46:43 +080014525 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080014526 else if (strncmp(output, "0", 1) == 0)
developere40952c2023-06-15 18:46:43 +080014527 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080014528 else if (strncmp(output, "1", 1) == 0)
developere40952c2023-06-15 18:46:43 +080014529 res = snprintf(output_string, 64, "Optional");
developera3511852023-06-14 14:12:59 +080014530 else if (strncmp(output, "2", 1) == 0)
developere40952c2023-06-15 18:46:43 +080014531 res = snprintf(output_string, 64, "Required");
developera3511852023-06-14 14:12:59 +080014532 else {
14533 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
14534 return RETURN_ERR;
14535 }
developere40952c2023-06-15 18:46:43 +080014536 if (os_snprintf_error(64, res)) {
14537 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14538 return RETURN_ERR;
14539 }
developer72fb0bb2023-01-11 09:46:29 +080014540
developera3511852023-06-14 14:12:59 +080014541 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
14542 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014543}
developerc154deb2023-11-14 13:36:44 +080014544INT wifi_setApMBOConfig(INT apIndex)
14545{
14546 struct params params;
14547 char config_file[MAX_BUF_SIZE] = {0};
14548 int res;
14549
14550 params.name = "mbo";
14551 params.value = "0";
14552
14553 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14554 if (os_snprintf_error(sizeof(config_file), res)) {
14555 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14556 return RETURN_ERR;
14557 }
14558
14559 wifi_hostapdWrite(config_file, &params, 1);
14560 wifi_hostapdProcessUpdate(apIndex, &params, 1);
14561 return RETURN_OK;
14562}
14563
developer72fb0bb2023-01-11 09:46:29 +080014564INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
14565{
developera3511852023-06-14 14:12:59 +080014566 struct params params;
14567 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080014568 int res;
developer72fb0bb2023-01-11 09:46:29 +080014569
developera3511852023-06-14 14:12:59 +080014570 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14571 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
14572 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014573
developera3511852023-06-14 14:12:59 +080014574 params.name = "ieee80211w";
developerc154deb2023-11-14 13:36:44 +080014575 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0) {
developera3511852023-06-14 14:12:59 +080014576 params.value = "0";
developerc154deb2023-11-14 13:36:44 +080014577 /* mbo should disable when pmf = 0*/
14578 wifi_setApMBOConfig(apIndex);
14579 }
developera3511852023-06-14 14:12:59 +080014580 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
14581 params.value = "1";
14582 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
14583 params.value = "2";
14584 else{
14585 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
14586 return RETURN_ERR;
14587 }
developer75bd10c2023-06-27 11:34:08 +080014588
14589 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14590 if (os_snprintf_error(sizeof(config_file), res)) {
14591 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14592 return RETURN_ERR;
14593 }
14594
developera3511852023-06-14 14:12:59 +080014595 wifi_hostapdWrite(config_file, &params, 1);
developer9f2358c2023-09-22 18:42:12 +080014596 wifi_hostapdProcessUpdate(apIndex, &params, 1);
14597 wifi_quick_reload_ap(apIndex);
developer9f2358c2023-09-22 18:42:12 +080014598
developera3511852023-06-14 14:12:59 +080014599 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
14600 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014601}
14602INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
14603{
developera3511852023-06-14 14:12:59 +080014604 char output[16]={'\0'};
14605 char config_file[MAX_BUF_SIZE] = {0};
14606 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080014607 int res;
developer72fb0bb2023-01-11 09:46:29 +080014608
developera3511852023-06-14 14:12:59 +080014609 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerdfd270b2023-12-12 10:24:30 +080014610 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080014611 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
14612 if (os_snprintf_error(sizeof(config_file), res)) {
14613 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14614 return RETURN_ERR;
14615 }
developera3511852023-06-14 14:12:59 +080014616 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080014617
developera3511852023-06-14 14:12:59 +080014618 if (strncmp(output, "0", 1) == 0)
14619 *output_bool = FALSE;
14620 else if (strncmp(output, "1", 1) == 0)
14621 *output_bool = TRUE;
14622 else if (strncmp(output, "2", 1) == 0)
14623 *output_bool = TRUE;
14624 else if (strncmp(output, "3", 1) == 0)
14625 *output_bool = TRUE;
14626 else
14627 *output_bool = FALSE;
14628 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014629
developera3511852023-06-14 14:12:59 +080014630 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014631}
14632
14633INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
14634{
developera3511852023-06-14 14:12:59 +080014635 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014636}
14637
14638INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
14639{
developera3511852023-06-14 14:12:59 +080014640 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014641}
14642
14643INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
14644{
developera3511852023-06-14 14:12:59 +080014645 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014646}
14647
14648INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
14649{
developera3511852023-06-14 14:12:59 +080014650 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14651 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080014652 char tmp_output[MAX_BUF_SIZE] = {0};
developera3511852023-06-14 14:12:59 +080014653 int res;
developer72fb0bb2023-01-11 09:46:29 +080014654
developera3511852023-06-14 14:12:59 +080014655 if (NULL == output)
14656 return RETURN_ERR;
14657 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
14658 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080014659 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14660 return RETURN_ERR;
14661 }
developera3511852023-06-14 14:12:59 +080014662 wifi_hostapdRead(config_file,"hw_mode",output,64);
developer72fb0bb2023-01-11 09:46:29 +080014663
developer32f2a182023-06-27 19:50:41 +080014664 if(strcmp(output,"b")==0) {
14665 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,11");
14666 if (os_snprintf_error(sizeof(tmp_output), res)) {
14667 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14668 return RETURN_ERR;
14669 }
14670 } else if (strcmp(output,"a")==0) {
14671 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "6,9,11,12,18,24,36,48,54");
14672 if (os_snprintf_error(sizeof(tmp_output), res)) {
14673 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14674 return RETURN_ERR;
developer5b23cd02023-07-19 20:26:03 +080014675 }
developer32f2a182023-06-27 19:50:41 +080014676 } else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) {
14677 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
14678 if (os_snprintf_error(sizeof(tmp_output), res)) {
14679 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14680 return RETURN_ERR;
14681 }
developer75bd10c2023-06-27 11:34:08 +080014682 }
developer32f2a182023-06-27 19:50:41 +080014683 memcpy(output, tmp_output, strlen(tmp_output));
14684 output[strlen(tmp_output)] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080014685
developera3511852023-06-14 14:12:59 +080014686 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14687 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014688}
14689
14690INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
14691{
developera3511852023-06-14 14:12:59 +080014692 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14693 char *temp;
developer32f2a182023-06-27 19:50:41 +080014694 char temp_output[128] = {0};
14695 char temp_TransmitRates[128] = {0};
developera3511852023-06-14 14:12:59 +080014696 char config_file[MAX_BUF_SIZE] = {0};
14697 int res;
developer32f2a182023-06-27 19:50:41 +080014698 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080014699
developera3511852023-06-14 14:12:59 +080014700 if (NULL == output)
14701 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014702
developera3511852023-06-14 14:12:59 +080014703 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
14704 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080014705 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14706 return RETURN_ERR;
14707 }
developera3511852023-06-14 14:12:59 +080014708 wifi_hostapdRead(config_file,"supported_rates",output,64);
developer72fb0bb2023-01-11 09:46:29 +080014709
developera3511852023-06-14 14:12:59 +080014710 if (strlen(output) == 0) {
14711 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
14712 return RETURN_OK;
14713 }
developer32f2a182023-06-27 19:50:41 +080014714 len = strlen(output);
14715 if (len >= sizeof(temp_TransmitRates)) {
14716 wifi_debug(DEBUG_ERROR, "Unexpected strlen(output)\n");
14717 return RETURN_ERR;
14718 }
14719 strncpy(temp_TransmitRates, output, len);
developera3511852023-06-14 14:12:59 +080014720 temp = strtok(temp_TransmitRates," ");
14721 while(temp!=NULL)
14722 {
14723 temp[strlen(temp)-1]=0;
14724 if((temp[0]=='5') && (temp[1]=='\0'))
14725 {
14726 temp="5.5";
14727 }
developer32f2a182023-06-27 19:50:41 +080014728 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp)) {
14729 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
14730 return RETURN_ERR;
14731 }
14732 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080014733 temp = strtok(NULL," ");
14734 if(temp!=NULL)
14735 {
developer32f2a182023-06-27 19:50:41 +080014736 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
14737 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
14738 return RETURN_ERR;
14739 }
14740 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080014741 }
14742 }
developer32f2a182023-06-27 19:50:41 +080014743 len = strlen(temp_output);
14744 strncpy(output, temp_output, len);
14745 output[len] = '\0';
developera3511852023-06-14 14:12:59 +080014746 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014747
developera3511852023-06-14 14:12:59 +080014748 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014749}
14750
14751INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
14752{
developera3511852023-06-14 14:12:59 +080014753 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014754}
14755
14756
14757INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
14758{
developera3511852023-06-14 14:12:59 +080014759 int i=0;
14760 char *temp;
14761 char temp1[128] = {0};
14762 char temp_output[128] = {0};
14763 char temp_TransmitRates[128] = {0};
14764 struct params params={'\0'};
14765 char config_file[MAX_BUF_SIZE] = {0};
14766 wifi_band band = wifi_index_to_band(wlanIndex);
developer32f2a182023-06-27 19:50:41 +080014767 unsigned long len;
14768 int res;
developer72fb0bb2023-01-11 09:46:29 +080014769
developera3511852023-06-14 14:12:59 +080014770 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14771 if(NULL == output)
14772 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080014773
14774 len = strlen(output);
14775 if (len >= sizeof(temp_TransmitRates)) {
14776 wifi_debug(DEBUG_ERROR, "not enough room in temp_TransmitRates\n");
14777 return RETURN_ERR;
14778 }
14779 strncpy(temp_TransmitRates, output, len);
14780 temp_TransmitRates[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080014781
developera3511852023-06-14 14:12:59 +080014782 for(i=0;i<strlen(temp_TransmitRates);i++)
14783 {
14784 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
14785 {
14786 continue;
14787 }
14788 else
14789 {
14790 return RETURN_ERR;
14791 }
14792 }
developera3511852023-06-14 14:12:59 +080014793 temp = strtok(temp_TransmitRates,",");
14794 while(temp!=NULL)
14795 {
developer32f2a182023-06-27 19:50:41 +080014796 len = strlen(temp);
14797 if (len >= sizeof(temp1)) {
14798 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
14799 return RETURN_ERR;
14800 }
14801 strncpy(temp1, temp, len);
14802 temp1[len] = '\0';
developera3511852023-06-14 14:12:59 +080014803 if(band == band_5)
14804 {
14805 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
14806 {
14807 return RETURN_ERR;
14808 }
14809 }
developer72fb0bb2023-01-11 09:46:29 +080014810
developer32f2a182023-06-27 19:50:41 +080014811 if(strcmp(temp,"5.5")==0) {
14812 strncpy(temp1, "55", 2);
14813 temp1[2] = '\0';
14814 } else {
14815 if ((sizeof(temp1) - strlen(temp1)) <= 1) {
14816 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
14817 return RETURN_ERR;
14818 }
14819 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +080014820 }
developer5b23cd02023-07-19 20:26:03 +080014821
developer32f2a182023-06-27 19:50:41 +080014822 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp1)) {
14823 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
14824 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080014825 }
developer32f2a182023-06-27 19:50:41 +080014826 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080014827 temp = strtok(NULL,",");
14828 if(temp!=NULL)
14829 {
developer32f2a182023-06-27 19:50:41 +080014830 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
14831 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
14832 return RETURN_ERR;
14833 }
14834 strncat(temp_output, " ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080014835 }
14836 }
developer32f2a182023-06-27 19:50:41 +080014837 len = strlen(temp_output);
14838 strncpy(output, temp_output, len);
14839 output[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080014840
developera3511852023-06-14 14:12:59 +080014841 params.name = "supported_rates";
14842 params.value = output;
developer72fb0bb2023-01-11 09:46:29 +080014843
developera3511852023-06-14 14:12:59 +080014844 wifi_dbg_printf("\n%s:",__func__);
14845 wifi_dbg_printf("params.value=%s\n",params.value);
developer32f2a182023-06-27 19:50:41 +080014846 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
14847 if (os_snprintf_error(sizeof(config_file), res)) {
14848 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14849 return RETURN_ERR;
developer5b23cd02023-07-19 20:26:03 +080014850 }
developer9f2358c2023-09-22 18:42:12 +080014851
developera3511852023-06-14 14:12:59 +080014852 wifi_hostapdWrite(config_file,&params,1);
developer9f2358c2023-09-22 18:42:12 +080014853 wifi_hostapdProcessUpdate(wlanIndex, &params, 1);
14854 wifi_quick_reload_ap(wlanIndex);
developer9f2358c2023-09-22 18:42:12 +080014855
developera3511852023-06-14 14:12:59 +080014856 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014857
developera3511852023-06-14 14:12:59 +080014858 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014859}
14860
14861
14862static char *sncopy(char *dst, int dst_sz, const char *src)
14863{
developera3511852023-06-14 14:12:59 +080014864 if (src && dst && dst_sz > 0) {
14865 strncpy(dst, src, dst_sz);
14866 dst[dst_sz - 1] = '\0';
14867 }
14868 return dst;
developer72fb0bb2023-01-11 09:46:29 +080014869}
14870
14871static int util_get_sec_chan_offset(int channel, const char* ht_mode)
14872{
developera3511852023-06-14 14:12:59 +080014873 if (0 == strcmp(ht_mode, "HT40") ||
14874 0 == strcmp(ht_mode, "HT80") ||
14875 0 == strcmp(ht_mode, "HT160")) {
14876 switch (channel) {
14877 case 1 ... 7:
14878 case 36:
14879 case 44:
14880 case 52:
14881 case 60:
14882 case 100:
14883 case 108:
14884 case 116:
14885 case 124:
14886 case 132:
14887 case 140:
14888 case 149:
14889 case 157:
14890 return 1;
14891 case 8 ... 13:
14892 case 40:
14893 case 48:
14894 case 56:
14895 case 64:
14896 case 104:
14897 case 112:
14898 case 120:
14899 case 128:
14900 case 136:
14901 case 144:
14902 case 153:
14903 case 161:
14904 return -1;
14905 default:
14906 return -EINVAL;
14907 }
14908 }
developer72fb0bb2023-01-11 09:46:29 +080014909
developera3511852023-06-14 14:12:59 +080014910 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080014911}
14912
14913static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
14914{
developera3511852023-06-14 14:12:59 +080014915 int idx = channel%8;
14916 if (0 == strcmp(ht_mode, "HT40") ||
14917 0 == strcmp(ht_mode, "HT80") ||
14918 0 == strcmp(ht_mode, "HT160")) {
14919 switch (idx) {
14920 case 1:
14921 return 1;
14922 case 5:
14923 return -1;
14924 default:
14925 return -EINVAL;
14926 }
14927 }
developer72fb0bb2023-01-11 09:46:29 +080014928
developera3511852023-06-14 14:12:59 +080014929 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080014930}
14931static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
14932{
developera3511852023-06-14 14:12:59 +080014933 if (NULL == hw_mode) return;
developer72fb0bb2023-01-11 09:46:29 +080014934
developera3511852023-06-14 14:12:59 +080014935 if (0 == strcmp(hw_mode, "ac"))
14936 sncopy(bw_mode, bw_mode_len, "ht vht");
developer72fb0bb2023-01-11 09:46:29 +080014937
developera3511852023-06-14 14:12:59 +080014938 if (0 == strcmp(hw_mode, "n"))
14939 sncopy(bw_mode, bw_mode_len, "ht");
developer72fb0bb2023-01-11 09:46:29 +080014940
developera3511852023-06-14 14:12:59 +080014941 return;
developer72fb0bb2023-01-11 09:46:29 +080014942}
14943
14944static int util_chan_to_freq(int chan)
14945{
developera3511852023-06-14 14:12:59 +080014946 if (chan == 14)
14947 return 2484;
14948 else if (chan < 14)
14949 return 2407 + chan * 5;
14950 else if (chan >= 182 && chan <= 196)
14951 return 4000 + chan * 5;
14952 else
14953 return 5000 + chan * 5;
14954 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014955}
14956
14957static int util_6G_chan_to_freq(int chan)
14958{
developera3511852023-06-14 14:12:59 +080014959 if (chan)
14960 return 5950 + chan * 5;
14961 else
14962 return 0;
developer69b61b02023-03-07 17:17:44 +080014963
developer72fb0bb2023-01-11 09:46:29 +080014964}
14965const int *util_unii_5g_chan2list(int chan, int width)
14966{
developera3511852023-06-14 14:12:59 +080014967 static const int lists[] = {
14968 // <width>, <chan1>, <chan2>..., 0,
14969 20, 36, 0,
14970 20, 40, 0,
14971 20, 44, 0,
14972 20, 48, 0,
14973 20, 52, 0,
14974 20, 56, 0,
14975 20, 60, 0,
14976 20, 64, 0,
14977 20, 100, 0,
14978 20, 104, 0,
14979 20, 108, 0,
14980 20, 112, 0,
14981 20, 116, 0,
14982 20, 120, 0,
14983 20, 124, 0,
14984 20, 128, 0,
14985 20, 132, 0,
14986 20, 136, 0,
14987 20, 140, 0,
14988 20, 144, 0,
14989 20, 149, 0,
14990 20, 153, 0,
14991 20, 157, 0,
14992 20, 161, 0,
14993 20, 165, 0,
14994 40, 36, 40, 0,
14995 40, 44, 48, 0,
14996 40, 52, 56, 0,
14997 40, 60, 64, 0,
14998 40, 100, 104, 0,
14999 40, 108, 112, 0,
15000 40, 116, 120, 0,
15001 40, 124, 128, 0,
15002 40, 132, 136, 0,
15003 40, 140, 144, 0,
15004 40, 149, 153, 0,
15005 40, 157, 161, 0,
15006 80, 36, 40, 44, 48, 0,
15007 80, 52, 56, 60, 64, 0,
15008 80, 100, 104, 108, 112, 0,
15009 80, 116, 120, 124, 128, 0,
15010 80, 132, 136, 140, 144, 0,
15011 80, 149, 153, 157, 161, 0,
15012 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
15013 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
15014 -1 // final delimiter
15015 };
15016 const int *start;
15017 const int *p;
developer72fb0bb2023-01-11 09:46:29 +080015018
developera3511852023-06-14 14:12:59 +080015019 for (p = lists; *p != -1; p++) {
15020 if (*p == width) {
15021 for (start = ++p; *p != 0; p++) {
15022 if (*p == chan)
15023 return start;
15024 }
15025 }
15026 // move to the end of channel list of given width
15027 while (*p != 0) {
15028 p++;
15029 }
15030 }
developer72fb0bb2023-01-11 09:46:29 +080015031
developera3511852023-06-14 14:12:59 +080015032 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080015033}
15034
15035static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
15036{
developera3511852023-06-14 14:12:59 +080015037 if (NULL == ht_mode)
15038 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015039
developera3511852023-06-14 14:12:59 +080015040 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
15041 const int *chans = util_unii_5g_chan2list(channel, width);
15042 int sum = 0;
15043 int cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080015044
developera3511852023-06-14 14:12:59 +080015045 if (NULL == chans)
15046 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015047
developera3511852023-06-14 14:12:59 +080015048 while (*chans) {
15049 sum += *chans;
15050 cnt++;
15051 chans++;
15052 }
15053 if (cnt == 0)
15054 return 0;
15055 return sum / cnt;
developer72fb0bb2023-01-11 09:46:29 +080015056}
15057
15058static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
15059{
developerc14d83a2023-06-29 20:09:42 +080015060 long int width;
developera3511852023-06-14 14:12:59 +080015061 int idx = 0 ;
15062 int centerchan = 0;
15063 int chan_ofs = 1;
developer72fb0bb2023-01-11 09:46:29 +080015064
developerc14d83a2023-06-29 20:09:42 +080015065 if (NULL == ht_mode)
15066 return 0;
15067
15068 if (hal_strtol((char *)(ht_mode + 2), 10, &width) < 0) {
15069 wifi_debug(DEBUG_ERROR, "strtol fail\n");
15070 }
15071
developera3511852023-06-14 14:12:59 +080015072 if (width == 40){
15073 idx = ((channel/4) + chan_ofs)%2;
15074 switch (idx) {
15075 case 0:
15076 centerchan = (channel - 2);
15077 break;
15078 case 1:
15079 centerchan = (channel + 2);
15080 break;
15081 default:
15082 return -EINVAL;
15083 }
15084 }else if (width == 80){
15085 idx = ((channel/4) + chan_ofs)%4;
15086 switch (idx) {
15087 case 0:
15088 centerchan = (channel - 6);
15089 break;
15090 case 1:
15091 centerchan = (channel + 6);
15092 break;
15093 case 2:
15094 centerchan = (channel + 2);
15095 break;
15096 case 3:
15097 centerchan = (channel - 2);
15098 break;
15099 default:
15100 return -EINVAL;
15101 }
15102 }else if (width == 160){
15103 switch (channel) {
15104 case 1 ... 29:
15105 centerchan = 15;
15106 break;
15107 case 33 ... 61:
15108 centerchan = 47;
15109 break;
15110 case 65 ... 93:
15111 centerchan = 79;
15112 break;
15113 case 97 ... 125:
15114 centerchan = 111;
15115 break;
15116 case 129 ... 157:
15117 centerchan = 143;
15118 break;
15119 case 161 ... 189:
15120 centerchan = 175;
15121 break;
15122 case 193 ... 221:
15123 centerchan = 207;
15124 break;
15125 default:
15126 return -EINVAL;
15127 }
15128 }
15129 return centerchan;
developer72fb0bb2023-01-11 09:46:29 +080015130}
15131static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
15132{
developera3511852023-06-14 14:12:59 +080015133 BOOL onlyG, onlyN, onlyA;
15134 CHAR tmp[64];
15135 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
15136 if (ret == RETURN_OK) {
15137 sncopy(hw_mode, hw_mode_size, tmp);
15138 }
15139 return ret;
developer72fb0bb2023-01-11 09:46:29 +080015140}
15141
15142INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
15143{
developera3511852023-06-14 14:12:59 +080015144 // Sample commands:
15145 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
15146 // hostapd_cli -i wifi0 chan_switch 30 2437
15147 int ret = 0;
15148 char center_freq1_str[32] = ""; // center_freq1=%d
15149 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
15150 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
15151 char hw_mode[16] = ""; // n|ac
15152 char bw_mode[16] = ""; // ht|ht vht
15153 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
15154 char interface_name[16] = {0};
15155 int sec_chan_offset;
15156 int width;
15157 char config_file[64] = {0};
15158 char *ext_str = "None";
15159 wifi_band band = band_invalid;
15160 int center_chan = 0;
15161 int center_freq1 = 0;
developere40952c2023-06-15 18:46:43 +080015162 int res;
developerc3556192023-12-06 17:59:09 +080015163 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080015164
developerc3556192023-12-06 17:59:09 +080015165 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
15166 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
15167 return RETURN_ERR;
15168 }
developera47dfe22023-12-21 16:02:31 +080015169 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
15170 if (os_snprintf_error(sizeof(config_file), res)) {
15171 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15172 return RETURN_ERR;
15173 }
developerc3556192023-12-06 17:59:09 +080015174
15175 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080015176 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015177
developera3511852023-06-14 14:12:59 +080015178 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015179
developerc3556192023-12-06 17:59:09 +080015180 band = wifi_index_to_band(main_vap_idx);
developer72fb0bb2023-01-11 09:46:29 +080015181
developera3511852023-06-14 14:12:59 +080015182 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
developer72fb0bb2023-01-11 09:46:29 +080015183
developera3511852023-06-14 14:12:59 +080015184 // Get radio mode HT20|HT40|HT80 etc.
15185 if (channel){
developere40952c2023-06-15 18:46:43 +080015186 res = snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
15187 if (os_snprintf_error(sizeof(ht_mode), res)) {
15188 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15189 return RETURN_ERR;
15190 }
developer72fb0bb2023-01-11 09:46:29 +080015191
developera3511852023-06-14 14:12:59 +080015192 // Provide bandwith if specified
15193 if (channel_width_MHz > 20) {
15194 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
15195 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
15196 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
developer72fb0bb2023-01-11 09:46:29 +080015197
developere40952c2023-06-15 18:46:43 +080015198 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
developera3511852023-06-14 14:12:59 +080015199 }else if (channel_width_MHz == 20){
developere40952c2023-06-15 18:46:43 +080015200 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
developera3511852023-06-14 14:12:59 +080015201 }
developer72fb0bb2023-01-11 09:46:29 +080015202
developere40952c2023-06-15 18:46:43 +080015203 if (os_snprintf_error(sizeof(opt_chan_info_str), res)) {
15204 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15205 return RETURN_ERR;
15206 }
developer72fb0bb2023-01-11 09:46:29 +080015207
developera3511852023-06-14 14:12:59 +080015208 if (channel_width_MHz > 20) {
15209 if (band == band_6){
15210 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
15211 if(center_chan){
15212 center_freq1 = util_6G_chan_to_freq(center_chan);
15213 }
15214 }else{
15215 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
15216 if(center_chan){
15217 center_freq1 = util_chan_to_freq(center_chan);
15218 }
15219 }
developer69b61b02023-03-07 17:17:44 +080015220
developera3511852023-06-14 14:12:59 +080015221 if (center_freq1)
developere40952c2023-06-15 18:46:43 +080015222 res = snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080015223
developera3511852023-06-14 14:12:59 +080015224 }
developere40952c2023-06-15 18:46:43 +080015225 if (os_snprintf_error(sizeof(center_freq1_str), res)) {
15226 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15227 return RETURN_ERR;
15228 }
developer72fb0bb2023-01-11 09:46:29 +080015229
developera3511852023-06-14 14:12:59 +080015230 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
15231 if (band == band_6){
15232 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
15233 }else{
15234 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
15235 }
developere40952c2023-06-15 18:46:43 +080015236 if (sec_chan_offset != -EINVAL) {
15237 res = snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
15238 if (os_snprintf_error(sizeof(sec_chan_offset_str), res)) {
15239 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15240 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080015241 }
developere40952c2023-06-15 18:46:43 +080015242 }
developera3511852023-06-14 14:12:59 +080015243 // Only the first AP, other are hanging on the same radio
developera3511852023-06-14 14:12:59 +080015244 /* wifi_dbg_printf("execute: '%s'\n", cmd);
15245 ret = _syscmd(cmd, buf, sizeof(buf));
15246 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080015247
developera3511852023-06-14 14:12:59 +080015248 ret = wifi_setRadioChannel(radioIndex, channel);
15249 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080015250 wifi_debug(DEBUG_ERROR,"wifi_setRadioChannel return error.\n");
developera3511852023-06-14 14:12:59 +080015251 return RETURN_ERR;
15252 }
developer72fb0bb2023-01-11 09:46:29 +080015253
developera3511852023-06-14 14:12:59 +080015254 if (sec_chan_offset == 1)
15255 ext_str = "Above";
15256 else if (sec_chan_offset == -1)
15257 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080015258
developera3511852023-06-14 14:12:59 +080015259 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080015260
developera3511852023-06-14 14:12:59 +080015261 } else {
15262 if (channel_width_MHz > 20)
15263 ext_str = "Above";
15264 }
developer72fb0bb2023-01-11 09:46:29 +080015265
developera3511852023-06-14 14:12:59 +080015266 wifi_setRadioExtChannel(radioIndex, ext_str);
developer72fb0bb2023-01-11 09:46:29 +080015267
developera3511852023-06-14 14:12:59 +080015268 char mhz_str[16];
developere40952c2023-06-15 18:46:43 +080015269 res = snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
15270 if (os_snprintf_error(sizeof(mhz_str), res)) {
15271 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15272 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080015273 }
developera3511852023-06-14 14:12:59 +080015274 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
developer72fb0bb2023-01-11 09:46:29 +080015275
developera3511852023-06-14 14:12:59 +080015276 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015277
developera3511852023-06-14 14:12:59 +080015278 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015279}
15280
15281INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
15282{
developera3511852023-06-14 14:12:59 +080015283 int index = -1;
15284 wifi_neighbor_ap2_t *scan_array = NULL;
15285 char cmd[256]={0};
15286 char buf[128]={0};
15287 char file_name[32] = {0};
15288 char filter_SSID[32] = {0};
15289 char line[256] = {0};
15290 char interface_name[16] = {0};
15291 char *ret = NULL;
15292 int freq=0;
15293 FILE *f = NULL;
developer86035662023-06-28 19:21:12 +080015294 long int channels_num = 0;
developera3511852023-06-14 14:12:59 +080015295 int vht_channel_width = 0;
15296 int get_noise_ret = RETURN_ERR;
15297 bool filter_enable = false;
15298 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
15299 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080015300 int res;
developer32f2a182023-06-27 19:50:41 +080015301 unsigned long len;
developerb14b3462023-07-01 18:02:42 +080015302 struct channels_noise *channels_noise_arr = NULL;
developerc3556192023-12-06 17:59:09 +080015303 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080015304
developera3511852023-06-14 14:12:59 +080015305 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015306
developere40952c2023-06-15 18:46:43 +080015307 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
15308 if (os_snprintf_error(sizeof(file_name), res)) {
15309 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15310 return RETURN_ERR;
developer5b23cd02023-07-19 20:26:03 +080015311 }
developera3511852023-06-14 14:12:59 +080015312 f = fopen(file_name, "r");
15313 if (f != NULL) {
developer86035662023-06-28 19:21:12 +080015314 if (fgets(filter_SSID, sizeof(file_name), f) == NULL) {
15315 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerc14d83a2023-06-29 20:09:42 +080015316 if (fclose(f) != 0) {
15317 wifi_debug(DEBUG_ERROR, "fclose fail\n");
15318 }
developer86035662023-06-28 19:21:12 +080015319 return RETURN_ERR;
15320 }
developera3511852023-06-14 14:12:59 +080015321 if (strlen(filter_SSID) != 0)
15322 filter_enable = true;
developerd14dff12023-06-28 22:47:44 +080015323 if (fclose(f) != 0) {
15324 wifi_debug(DEBUG_ERROR, "fclose fail\n");
15325 return RETURN_ERR;
15326 }
developera3511852023-06-14 14:12:59 +080015327 }
developer72fb0bb2023-01-11 09:46:29 +080015328
developerc3556192023-12-06 17:59:09 +080015329 if (array_index_to_vap_index(radio_index, 0, &main_vap_idx) != RETURN_OK) {
15330 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_index);
15331 return RETURN_ERR;
15332 }
15333
15334 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080015335 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015336
developera3511852023-06-14 14:12:59 +080015337 phyId = radio_index_to_phy(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080015338
developer8078acf2023-08-04 18:52:48 +080015339 res = _syscmd_secure(buf, sizeof(buf), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
15340 if (res) {
15341 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080015342 }
developer86035662023-06-28 19:21:12 +080015343 if (hal_strtol(buf, 10, &channels_num) < 0) {
15344 wifi_debug(DEBUG_ERROR, "strtol fail\n");
15345 return RETURN_ERR;
15346 }
developer72fb0bb2023-01-11 09:46:29 +080015347
developer5b23cd02023-07-19 20:26:03 +080015348 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 +080015349 // 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 +080015350 if (os_snprintf_error(sizeof(cmd), res)) {
15351 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15352 return RETURN_ERR;
developer5b23cd02023-07-19 20:26:03 +080015353 }
developer32f2a182023-06-27 19:50:41 +080015354
developer86035662023-06-28 19:21:12 +080015355 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developer8078acf2023-08-04 18:52:48 +080015356
15357 f = v_secure_popen("r", "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
15358 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
15359
15360 if (f == NULL) {
15361 wifi_dbg_printf("%s: v_secure_popen %s error\n", __func__, cmd);
developera3511852023-06-14 14:12:59 +080015362 return RETURN_ERR;
15363 }
developer69b61b02023-03-07 17:17:44 +080015364
developerb14b3462023-07-01 18:02:42 +080015365 if (channels_num > 0 && channels_num <= 243) {
15366 channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
developer86035662023-06-28 19:21:12 +080015367
developerb14b3462023-07-01 18:02:42 +080015368 if (channels_noise_arr == NULL) {
15369 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15370 goto err;
15371 }
15372 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer9ce44382023-06-28 11:09:37 +080015373 }
developer86035662023-06-28 19:21:12 +080015374
developera3511852023-06-14 14:12:59 +080015375 ret = fgets(line, sizeof(line), f);
15376 while (ret != NULL) {
15377 if(strstr(line, "BSS") != NULL) { // new neighbor info
15378 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
15379 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
15380 // 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 +080015381
developera3511852023-06-14 14:12:59 +080015382 if (!filter_BSS) {
15383 index++;
developer5b23cd02023-07-19 20:26:03 +080015384 wifi_debug(DEBUG_OFF, "index=%d\n", index);
developera3511852023-06-14 14:12:59 +080015385 wifi_neighbor_ap2_t *tmp;
15386 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
15387 if (tmp == NULL) { // no more memory to use
15388 index--;
15389 wifi_dbg_printf("%s: realloc failed\n", __func__);
15390 break;
15391 }
15392 scan_array = tmp;
15393 }
15394 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +080015395
developera3511852023-06-14 14:12:59 +080015396 filter_BSS = false;
developer86035662023-06-28 19:21:12 +080015397 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
15398 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15399 goto err;
15400 }
developerc79e9172023-06-06 19:48:03 +080015401 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +080015402 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +080015403 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +080015404 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +080015405 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +080015406 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
developerb717e062023-11-17 14:13:19 +080015407 } else if (strstr(line, "freq:") != NULL) {
developer86035662023-06-28 19:21:12 +080015408 if (sscanf(line," freq: %d", &freq) != 1) {
15409 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
developerb14b3462023-07-01 18:02:42 +080015410 //goto err;
developer86035662023-06-28 19:21:12 +080015411 }
developera3511852023-06-14 14:12:59 +080015412 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080015413
developera3511852023-06-14 14:12:59 +080015414 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +080015415 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080015416 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +080015417 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080015418 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +080015419 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080015420 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
15421 }
15422 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +080015423 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080015424 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +080015425 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080015426 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +080015427 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080015428 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
15429 }
developer72fb0bb2023-01-11 09:46:29 +080015430
developera3511852023-06-14 14:12:59 +080015431 scan_array[index].ap_Noise = 0;
15432 if (get_noise_ret == RETURN_OK) {
15433 for (int i = 0; i < channels_num; i++) {
15434 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
15435 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
15436 break;
15437 }
15438 }
15439 }
15440 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +080015441 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
15442 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15443 goto err;
15444 }
developera3511852023-06-14 14:12:59 +080015445 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +080015446 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
15447 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15448 goto err;
15449 }
developer5b23cd02023-07-19 20:26:03 +080015450 } else if (strstr(line,"SSID:") != NULL) {
15451 int i;
15452 char *new_line = NULL;
15453
15454 for (i = 0; line[i] == '\t'; i++) {
15455 ;
developer86035662023-06-28 19:21:12 +080015456 }
developer5b23cd02023-07-19 20:26:03 +080015457 new_line = &line[i];
15458
15459 if (strncmp(new_line, "SSID: \n", strlen("SSID: \n")) == 0) {
15460 ret = fgets(line, sizeof(line), f);
15461 continue;
15462 }
15463 if (strstr(new_line, "HESSID") == NULL) {
15464 if (sscanf(new_line, "SSID: %63s", scan_array[index].ap_SSID) != 1) {
15465 wifi_debug(DEBUG_ERROR, "sscanf fail, index = %d\n", index);
15466 goto err;
15467 } else
15468 wifi_debug(DEBUG_ERROR, "index = %d, ssid=%s\n", index, scan_array[index].ap_SSID);
15469 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) == 0) {
15470 filter_BSS = true;
15471 }
developera3511852023-06-14 14:12:59 +080015472 }
15473 } else if (strstr(line, "Supported rates") != NULL) {
15474 char SRate[80] = {0}, *tmp = NULL;
15475 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080015476 len = strlen(line);
15477 if (len >= sizeof(SRate)) {
15478 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080015479 goto err;
developer32f2a182023-06-27 19:50:41 +080015480 }
15481 strncpy(SRate, line, len);
developera3511852023-06-14 14:12:59 +080015482 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +080015483 if (tmp == NULL)
15484 goto err;
developera3511852023-06-14 14:12:59 +080015485 tmp = strtok(NULL, ":");
developer5b23cd02023-07-19 20:26:03 +080015486 if (tmp == NULL)
developer86035662023-06-28 19:21:12 +080015487 goto err;
developer5b23cd02023-07-19 20:26:03 +080015488
developer32f2a182023-06-27 19:50:41 +080015489 len = strlen(tmp);
15490 if (len >= sizeof(buf)) {
15491 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
developer86035662023-06-28 19:21:12 +080015492 goto err;
developer32f2a182023-06-27 19:50:41 +080015493 }
15494 strncpy(buf, tmp, len);
developera3511852023-06-14 14:12:59 +080015495 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +080015496
developera3511852023-06-14 14:12:59 +080015497 tmp = strtok(buf, " \n");
15498 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +080015499 if ((sizeof(SRate) - strlen(SRate)) <= strlen(tmp)) {
15500 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080015501 goto err;
developer32f2a182023-06-27 19:50:41 +080015502 }
15503 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +080015504 if (SRate[strlen(SRate) - 1] == '*') {
15505 SRate[strlen(SRate) - 1] = '\0';
15506 }
developer32f2a182023-06-27 19:50:41 +080015507 if ((sizeof(SRate) - strlen(SRate)) <= 1) {
15508 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080015509 goto err;
developer32f2a182023-06-27 19:50:41 +080015510 }
15511 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +080015512
developera3511852023-06-14 14:12:59 +080015513 tmp = strtok(NULL, " \n");
15514 }
15515 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +080015516 len = strlen(SRate);
15517 if (len >= sizeof(scan_array[index].ap_SupportedDataTransferRates)) {
15518 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedDataTransferRates\n");
developer86035662023-06-28 19:21:12 +080015519 goto err;
developer32f2a182023-06-27 19:50:41 +080015520 }
15521 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, len);
15522 scan_array[index].ap_SupportedDataTransferRates[len] = '\0';
developera3511852023-06-14 14:12:59 +080015523 } else if (strstr(line, "DTIM") != NULL) {
developer5b23cd02023-07-19 20:26:03 +080015524 if (sscanf(line," TIM: DTIM Count %*d DTIM Period %d %*s", &(scan_array[index].ap_DTIMPeriod)) != 1) {
developer86035662023-06-28 19:21:12 +080015525 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
developer5b23cd02023-07-19 20:26:03 +080015526 goto err;
developer86035662023-06-28 19:21:12 +080015527 }
developera3511852023-06-14 14:12:59 +080015528 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080015529 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
15530 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080015531 goto err;
developer32f2a182023-06-27 19:50:41 +080015532 }
15533 strncat(scan_array[index].ap_SupportedStandards, ",ac",
15534 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
15535 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
15536 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +080015537 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080015538 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 2) {
15539 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080015540 goto err;
developer32f2a182023-06-27 19:50:41 +080015541 }
15542 strncat(scan_array[index].ap_SupportedStandards, ",n",
15543 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
15544 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
15545 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +080015546 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080015547 if (fgets(line, sizeof(line), f) == NULL) {
15548 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +080015549 break;
developer86035662023-06-28 19:21:12 +080015550 }
15551 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
15552 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15553 goto err;
15554 }
developera3511852023-06-14 14:12:59 +080015555 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +080015556 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +080015557 } else {
developere40952c2023-06-15 18:46:43 +080015558 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +080015559 }
developere40952c2023-06-15 18:46:43 +080015560 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
15561 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080015562 goto err;
developer5b23cd02023-07-19 20:26:03 +080015563 }
developere40952c2023-06-15 18:46:43 +080015564
developera3511852023-06-14 14:12:59 +080015565 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
15566 continue;
15567 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080015568 if (fgets(line, sizeof(line), f) == NULL) {
15569 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +080015570 break;
developer86035662023-06-28 19:21:12 +080015571 }
developer86035662023-06-28 19:21:12 +080015572 if (sscanf(line," * secondary channel offset: %127s", buf) != 1) {
15573 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15574 goto err;
15575 }
developera3511852023-06-14 14:12:59 +080015576 if (!strcmp(buf, "above")) {
15577 //40Mhz +
developere40952c2023-06-15 18:46:43 +080015578 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 +080015579 }
15580 else if (!strcmp(buf, "below")) {
15581 //40Mhz -
developere40952c2023-06-15 18:46:43 +080015582 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 +080015583 } else {
15584 //20Mhz
developere40952c2023-06-15 18:46:43 +080015585 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 +080015586 }
developere40952c2023-06-15 18:46:43 +080015587 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
15588 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080015589 goto err;
developer5b23cd02023-07-19 20:26:03 +080015590 }
developere40952c2023-06-15 18:46:43 +080015591
developer5b23cd02023-07-19 20:26:03 +080015592 if (strstr(line, "BSS") != NULL) { // prevent to get the next neighbor information
15593 wifi_debug(DEBUG_OFF, "continue\n");
developera3511852023-06-14 14:12:59 +080015594 continue;
developer5b23cd02023-07-19 20:26:03 +080015595 }
developera3511852023-06-14 14:12:59 +080015596 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080015597 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
15598 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080015599 goto err;
developer32f2a182023-06-27 19:50:41 +080015600 }
15601 strncat(scan_array[index].ap_SupportedStandards, ",ax",
15602 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
15603 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
15604 scan_array[index].ap_OperatingStandards[2] = '\0';
developerc14d83a2023-06-29 20:09:42 +080015605 if (fgets(line, sizeof(line), f) == NULL) {
15606 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerb717e062023-11-17 14:13:19 +080015607 break;
developerc14d83a2023-06-29 20:09:42 +080015608 }
developera3511852023-06-14 14:12:59 +080015609 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +080015610 if (strstr(line, "HE40/2.4GHz") != NULL) {
15611 len = strlen("11AXHE40PLUS");
15612 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
15613 } else {
15614 len = strlen("11AXHE20");
15615 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
15616 }
15617 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080015618 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
15619 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +080015620 len = strlen("11AXHE80");
15621 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
15622 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080015623 ret = fgets(line, sizeof(line), f);
developer5b23cd02023-07-19 20:26:03 +080015624 } else {
15625 wifi_debug(DEBUG_OFF, "continue\n");
developera3511852023-06-14 14:12:59 +080015626 continue;
developer5b23cd02023-07-19 20:26:03 +080015627 }
developer32f2a182023-06-27 19:50:41 +080015628 if (strstr(line, "HE160/5GHz") != NULL) {
15629 len = strlen("11AXHE160");
15630 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
15631 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
15632 }
developera3511852023-06-14 14:12:59 +080015633 }
developer5b23cd02023-07-19 20:26:03 +080015634 wifi_debug(DEBUG_OFF, "continue\n");
developera3511852023-06-14 14:12:59 +080015635 continue;
15636 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +080015637 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
15638 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080015639 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +080015640 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
15641 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080015642 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +080015643 if (sscanf(line, " * Group cipher: %63s", scan_array[index].ap_EncryptionMode) != 1) {
15644 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
15645 goto err;
15646 }
developera3511852023-06-14 14:12:59 +080015647 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +080015648 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
15649 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +080015650 }
15651 }
15652 ret = fgets(line, sizeof(line), f);
15653 }
developer72fb0bb2023-01-11 09:46:29 +080015654
developera3511852023-06-14 14:12:59 +080015655 if (!filter_BSS) {
15656 *output_array_size = index + 1;
15657 } else {
15658 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
15659 *output_array_size = index;
15660 }
15661 *neighbor_ap_array = scan_array;
developer8078acf2023-08-04 18:52:48 +080015662 v_secure_pclose(f);
developera3511852023-06-14 14:12:59 +080015663 free(channels_noise_arr);
15664 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15665 return RETURN_OK;
developer86035662023-06-28 19:21:12 +080015666err:
developer8078acf2023-08-04 18:52:48 +080015667 v_secure_pclose(f);
developer86035662023-06-28 19:21:12 +080015668 free(channels_noise_arr);
developerc14d83a2023-06-29 20:09:42 +080015669 if (scan_array)
15670 free(scan_array);
developer86035662023-06-28 19:21:12 +080015671 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015672}
15673
15674INT wifi_getApAssociatedDeviceStats(
developera3511852023-06-14 14:12:59 +080015675 INT apIndex,
15676 mac_address_t *clientMacAddress,
15677 wifi_associated_dev_stats_t *associated_dev_stats,
15678 u64 *handle)
developer72fb0bb2023-01-11 09:46:29 +080015679{
developera3511852023-06-14 14:12:59 +080015680 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
15681 char interface_name[50] = {0};
15682 char cmd[1024] = {0};
15683 char mac_str[18] = {0};
15684 char *key = NULL;
15685 char *val = NULL;
15686 FILE *f = NULL;
15687 char *line = NULL;
15688 size_t len = 0;
developer75bd10c2023-06-27 11:34:08 +080015689 int res;
developer72fb0bb2023-01-11 09:46:29 +080015690
developera3511852023-06-14 14:12:59 +080015691 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
15692 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
15693 return RETURN_ERR;
15694 }
developer72fb0bb2023-01-11 09:46:29 +080015695
developer32f2a182023-06-27 19:50:41 +080015696 res = snprintf(mac_str, sizeof(mac_str), "%x:%x:%x:%x:%x:%x",
15697 (*clientMacAddress)[0], (*clientMacAddress)[1], (*clientMacAddress)[2],
15698 (*clientMacAddress)[3], (*clientMacAddress)[4], (*clientMacAddress)[5]);
developer75bd10c2023-06-27 11:34:08 +080015699 if (os_snprintf_error(sizeof(mac_str), res)) {
15700 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15701 return RETURN_ERR;
15702 }
15703
15704 res = snprintf(cmd, sizeof(cmd), "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
15705 if (os_snprintf_error(sizeof(cmd), res)) {
15706 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15707 return RETURN_ERR;
15708 }
developer8078acf2023-08-04 18:52:48 +080015709 f = v_secure_popen("r", "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
15710 if(f == NULL) {
15711 wifi_dbg_printf("%s: v_secure_popen %s error\n", __func__, cmd);
developera3511852023-06-14 14:12:59 +080015712 return RETURN_ERR;
15713 }
developer72fb0bb2023-01-11 09:46:29 +080015714
developera3511852023-06-14 14:12:59 +080015715 while ((getline(&line, &len, f)) != -1) {
15716 key = strtok(line,":");
developer37646972023-06-29 10:58:43 +080015717 if (key == NULL)
15718 continue;
developera3511852023-06-14 14:12:59 +080015719 val = strtok(NULL,":");
developer37646972023-06-29 10:58:43 +080015720 if (val == NULL)
15721 continue;
developer72fb0bb2023-01-11 09:46:29 +080015722
developerb61d3362023-06-29 14:10:19 +080015723 if(!strncmp(key,"rx bytes",8))
15724 if (sscanf(val, "%llu", &dev_stats->cli_rx_bytes) != 1) {
15725 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
developer37646972023-06-29 10:58:43 +080015726 continue;
developerb61d3362023-06-29 14:10:19 +080015727 }
15728 if(!strncmp(key,"tx bytes",8))
15729 if (sscanf(val, "%llu", &dev_stats->cli_tx_bytes) != 1) {
15730 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
developer37646972023-06-29 10:58:43 +080015731 continue;
developerb61d3362023-06-29 14:10:19 +080015732 }
developer37646972023-06-29 10:58:43 +080015733 if(!strncmp(key,"rx packets",10)) {
15734 if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
15735 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15736 continue;
15737 }
15738 }
15739 if(!strncmp(key,"tx packets",10)) {
15740 if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
15741 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15742 continue;
15743 }
15744 }
15745 if(!strncmp(key,"tx retries",10)) {
15746 if (sscanf(val, "%llu", &dev_stats->cli_tx_retries) == EOF) {
15747 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15748 continue;
15749 }
15750 }
15751 if(!strncmp(key,"tx failed",9)) {
15752 if (sscanf(val, "%llu", &dev_stats->cli_tx_errors) == EOF) {
15753 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15754 continue;
15755 }
15756 }
15757 if(!strncmp(key,"rx drop misc",13)) {
15758 if (sscanf(val, "%llu", &dev_stats->cli_rx_errors) == EOF) {
15759 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15760 continue;
15761 }
developerd14dff12023-06-28 22:47:44 +080015762 }
developera3511852023-06-14 14:12:59 +080015763 if(!strncmp(key,"rx bitrate",10)) {
15764 val = strtok(val, " ");
developerc14d83a2023-06-29 20:09:42 +080015765 if (val == NULL)
15766 continue;
developer37646972023-06-29 10:58:43 +080015767 if (sscanf(val, "%lf", &dev_stats->cli_rx_rate) == EOF) {
15768 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15769 continue;
15770 }
developera3511852023-06-14 14:12:59 +080015771 }
15772 if(!strncmp(key,"tx bitrate",10)) {
15773 val = strtok(val, " ");
developerc14d83a2023-06-29 20:09:42 +080015774 if (val == NULL)
15775 continue;
developer37646972023-06-29 10:58:43 +080015776 if (sscanf(val, "%lf", &dev_stats->cli_tx_rate) == EOF) {
15777 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
15778 continue;
15779 }
developera3511852023-06-14 14:12:59 +080015780 }
15781 }
15782 free(line);
developer8078acf2023-08-04 18:52:48 +080015783 v_secure_pclose(f);
developera3511852023-06-14 14:12:59 +080015784 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015785}
15786
15787INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
15788{
developera3511852023-06-14 14:12:59 +080015789 char interface_name[IF_NAME_SIZE] = {0};
developer8078acf2023-08-04 18:52:48 +080015790 char buf[32] = {0};
developere40952c2023-06-15 18:46:43 +080015791 int res;
developer72fb0bb2023-01-11 09:46:29 +080015792
developera3511852023-06-14 14:12:59 +080015793 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080015794
developera3511852023-06-14 14:12:59 +080015795 if (NULL == output_string)
15796 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015797
developera3511852023-06-14 14:12:59 +080015798 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
15799 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080015800
developer8078acf2023-08-04 18:52:48 +080015801 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
15802 if (res) {
15803 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080015804 }
developer72fb0bb2023-01-11 09:46:29 +080015805
developera3511852023-06-14 14:12:59 +080015806 //size of SSID name restricted to value less than 32 bytes
developere40952c2023-06-15 18:46:43 +080015807 res = snprintf(output_string, 32, "%s", buf);
15808 if (os_snprintf_error(32, res)) {
15809 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15810 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080015811 }
developera3511852023-06-14 14:12:59 +080015812 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015813
developera3511852023-06-14 14:12:59 +080015814 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015815}
15816
15817INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
15818{
developer2edaf012023-05-24 14:24:53 +080015819 char *mac_arry_buf = NULL;
15820 INT policy = -1;
15821 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080015822
developer2edaf012023-05-24 14:24:53 +080015823 mac_arry_buf = malloc(buf_size);
15824 if (!mac_arry_buf) {
15825 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080015826 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080015827 }
15828 memset(mac_arry_buf, 0, buf_size);
15829 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
15830 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
15831 goto err;
15832 }
15833 /*
15834 mtk format to get policy:
15835 "policy=1
15836 00:11:22:33:44:55
15837 00:11:22:33:44:66
15838 "
15839 */
15840 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
15841 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
15842 goto err;
15843 }
15844 if (!(policy >=0 && policy <= 2)){
15845 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
15846 goto err;
15847 }
15848 *output_filterMode = policy;
15849 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
15850 free(mac_arry_buf);
15851 mac_arry_buf = NULL;
15852 return RETURN_OK;
15853err:
15854 free(mac_arry_buf);
15855 mac_arry_buf = NULL;
15856 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
15857 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015858}
15859
developer2edaf012023-05-24 14:24:53 +080015860
developer72fb0bb2023-01-11 09:46:29 +080015861INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
15862{
developera3511852023-06-14 14:12:59 +080015863 FILE *fp = NULL;
15864 char str[MAX_BUF_SIZE] = {0};
15865 int wificlientindex = 0 ;
15866 int count = 0;
15867 int signalstrength = 0;
15868 int arr[MACADDRESS_SIZE] = {0};
15869 unsigned char mac[MACADDRESS_SIZE] = {0};
15870 UINT wifi_count = 0;
developer8078acf2023-08-04 18:52:48 +080015871
developere40952c2023-06-15 18:46:43 +080015872 int res;
developer72fb0bb2023-01-11 09:46:29 +080015873
developera3511852023-06-14 14:12:59 +080015874 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15875 *output_array_size = 0;
15876 *associated_dev_array = NULL;
15877 char interface_name[50] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015878
developera3511852023-06-14 14:12:59 +080015879 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
15880 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
15881 return RETURN_ERR;
15882 }
developer72fb0bb2023-01-11 09:46:29 +080015883
developer8078acf2023-08-04 18:52:48 +080015884 fp = v_secure_popen( "r", "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
developera3511852023-06-14 14:12:59 +080015885 if (fp == NULL)
15886 {
15887 printf("Failed to run command inside function %s\n",__FUNCTION__ );
15888 return RETURN_ERR;
15889 }
developer72fb0bb2023-01-11 09:46:29 +080015890
developera3511852023-06-14 14:12:59 +080015891 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080015892 if (fgets(str, sizeof(str)-1, fp) == NULL) {
15893 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080015894 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080015895 return RETURN_ERR;
15896 }
developera3511852023-06-14 14:12:59 +080015897 wifi_count = (unsigned int) atoi ( str );
15898 *output_array_size = wifi_count;
15899 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
developer8078acf2023-08-04 18:52:48 +080015900 v_secure_pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080015901
developera3511852023-06-14 14:12:59 +080015902 if(wifi_count == 0)
15903 {
15904 return RETURN_OK;
15905 }
15906 else
15907 {
15908 wifi_associated_dev2_t* temp = NULL;
15909 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
15910 *associated_dev_array = temp;
15911 if(temp == NULL)
15912 {
15913 printf("Error Statement. Insufficient memory \n");
15914 return RETURN_ERR;
15915 }
developer72fb0bb2023-01-11 09:46:29 +080015916
developer33f13ba2023-07-12 16:19:06 +080015917 res = v_secure_system("iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
15918 if (res) {
15919 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developere40952c2023-06-15 18:46:43 +080015920 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080015921 }
developere40952c2023-06-15 18:46:43 +080015922
developera3511852023-06-14 14:12:59 +080015923 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
15924 if(fp == NULL)
15925 {
15926 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
15927 return RETURN_ERR;
15928 }
developere75ba632023-06-29 16:03:33 +080015929 if (fclose(fp) == EOF) {
15930 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
15931 return RETURN_ERR;
15932 }
developer72fb0bb2023-01-11 09:46:29 +080015933
developer8078acf2023-08-04 18:52:48 +080015934 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
developera3511852023-06-14 14:12:59 +080015935 if(fp)
15936 {
15937 for(count =0 ; count < wifi_count; count++)
15938 {
developer86035662023-06-28 19:21:12 +080015939 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
15940 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080015941 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080015942 return RETURN_ERR;
15943 }
developera3511852023-06-14 14:12:59 +080015944 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
15945 {
15946 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
15947 {
15948 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080015949
developera3511852023-06-14 14:12:59 +080015950 }
15951 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
15952 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]);
15953 }
15954 temp[count].cli_AuthenticationState = 1; //TODO
15955 temp[count].cli_Active = 1; //TODO
15956 }
developer8078acf2023-08-04 18:52:48 +080015957 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080015958 }
developer72fb0bb2023-01-11 09:46:29 +080015959
developera3511852023-06-14 14:12:59 +080015960 //Updating RSSI per client
developer8078acf2023-08-04 18:52:48 +080015961 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
developera3511852023-06-14 14:12:59 +080015962 if(fp)
15963 {
developer8078acf2023-08-04 18:52:48 +080015964 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080015965 }
developer8078acf2023-08-04 18:52:48 +080015966 fp = v_secure_popen("r", "cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080015967 if(fp)
15968 {
15969 for(count =0 ; count < wifi_count ;count++)
15970 {
developer86035662023-06-28 19:21:12 +080015971 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
15972 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080015973 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080015974 return RETURN_ERR;
15975 }
developera3511852023-06-14 14:12:59 +080015976 signalstrength = atoi(str);
15977 temp[count].cli_RSSI = signalstrength;
15978 }
developer8078acf2023-08-04 18:52:48 +080015979 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080015980 }
developer72fb0bb2023-01-11 09:46:29 +080015981
15982
developera3511852023-06-14 14:12:59 +080015983 //LastDataDownlinkRate
developer8078acf2023-08-04 18:52:48 +080015984 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
developera3511852023-06-14 14:12:59 +080015985 if (fp)
15986 {
developer8078acf2023-08-04 18:52:48 +080015987 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080015988 }
developer8078acf2023-08-04 18:52:48 +080015989 fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080015990 if (fp)
15991 {
developerc14d83a2023-06-29 20:09:42 +080015992 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080015993 for (count = 0; count < wifi_count; count++)
15994 {
developer86035662023-06-28 19:21:12 +080015995 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
15996 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080015997 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080015998 return RETURN_ERR;
15999 }
developerc14d83a2023-06-29 20:09:42 +080016000 if (hal_strtoul(str, 10, &tmp_u) < 0) {
16001 wifi_debug(DEBUG_ERROR, "strtol fail\n");
16002 }
16003 temp[count].cli_LastDataDownlinkRate = tmp_u;
developera3511852023-06-14 14:12:59 +080016004 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
16005 }
developer8078acf2023-08-04 18:52:48 +080016006 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080016007 }
developer72fb0bb2023-01-11 09:46:29 +080016008
developera3511852023-06-14 14:12:59 +080016009 //LastDataUplinkRate
developer8078acf2023-08-04 18:52:48 +080016010 fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
developera3511852023-06-14 14:12:59 +080016011 if (fp)
16012 {
developer8078acf2023-08-04 18:52:48 +080016013 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080016014 }
developer8078acf2023-08-04 18:52:48 +080016015 fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2");
developera3511852023-06-14 14:12:59 +080016016 if (fp)
16017 {
developerc14d83a2023-06-29 20:09:42 +080016018 unsigned long tmp_u;
developera3511852023-06-14 14:12:59 +080016019 for (count = 0; count < wifi_count; count++)
16020 {
developer86035662023-06-28 19:21:12 +080016021 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
16022 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080016023 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080016024 return RETURN_ERR;
16025 }
developerc14d83a2023-06-29 20:09:42 +080016026 if (hal_strtoul(str, 10, &tmp_u) < 0) {
16027 wifi_debug(DEBUG_ERROR, "strtol fail\n");
16028 }
16029 temp[count].cli_LastDataUplinkRate = tmp_u;
developera3511852023-06-14 14:12:59 +080016030 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
16031 }
developer8078acf2023-08-04 18:52:48 +080016032 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080016033 }
16034 }
16035 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16036 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016037
16038}
16039
16040INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
16041{
developera3511852023-06-14 14:12:59 +080016042 FILE *fp = NULL;
16043 char interface_name[50] = {0};
developer8078acf2023-08-04 18:52:48 +080016044
developera3511852023-06-14 14:12:59 +080016045 char str[256] = {0};
16046 wifi_ssidTrafficStats2_t *out = output_struct;
developer8078acf2023-08-04 18:52:48 +080016047
developerd14dff12023-06-28 22:47:44 +080016048 unsigned int recv;
developer72fb0bb2023-01-11 09:46:29 +080016049
developera3511852023-06-14 14:12:59 +080016050 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
16051 if (!output_struct)
16052 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016053
developera3511852023-06-14 14:12:59 +080016054 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
16055 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
16056 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080016057
16058
16059
16060
developer72fb0bb2023-01-11 09:46:29 +080016061
developer8078acf2023-08-04 18:52:48 +080016062
16063 fp = v_secure_popen("r", "cat /proc/net/dev | grep %s", interface_name);
developera3511852023-06-14 14:12:59 +080016064 if (fp == NULL) {
developer8078acf2023-08-04 18:52:48 +080016065 wifi_debug(DEBUG_ERROR, "%s: v_secure_popen failed\n", __func__);
developer86035662023-06-28 19:21:12 +080016066 return RETURN_ERR;
16067 }
16068 if (fgets(str, sizeof(str), fp) == NULL) {
16069 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080016070 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080016071 return RETURN_ERR;
16072 }
developer5b23cd02023-07-19 20:26:03 +080016073
developer8078acf2023-08-04 18:52:48 +080016074 v_secure_pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080016075
developera3511852023-06-14 14:12:59 +080016076 if (strlen(str) == 0) // interface not exist
16077 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016078
developerd14dff12023-06-28 22:47:44 +080016079 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 +080016080 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
developerd14dff12023-06-28 22:47:44 +080016081 if (recv != 8) {
16082 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
16083 return RETURN_ERR;
16084 }
developer72fb0bb2023-01-11 09:46:29 +080016085
developera3511852023-06-14 14:12:59 +080016086 memset(str, 0, sizeof(str));
developer75bd10c2023-06-27 11:34:08 +080016087
developer8078acf2023-08-04 18:52:48 +080016088
16089
16090
16091
16092
16093 fp = v_secure_popen("r", "tail -n1 /proc/net/netstat");
developera3511852023-06-14 14:12:59 +080016094 if (fp == NULL) {
developer8078acf2023-08-04 18:52:48 +080016095 wifi_debug(DEBUG_ERROR, "v_secure_popen failed\n");
developera3511852023-06-14 14:12:59 +080016096 return RETURN_ERR;
16097 }
developer86035662023-06-28 19:21:12 +080016098
16099 if (fgets(str, sizeof(str), fp) == NULL) {
16100 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080016101 v_secure_pclose(fp);
developer86035662023-06-28 19:21:12 +080016102 return RETURN_ERR;
16103 }
developer72fb0bb2023-01-11 09:46:29 +080016104
developer37646972023-06-29 10:58:43 +080016105 if (sscanf(str, "%*[^:]: %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
16106 &out->ssid_BroadcastPacketsSent) == EOF)
16107 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developer8078acf2023-08-04 18:52:48 +080016108 v_secure_pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080016109
developera3511852023-06-14 14:12:59 +080016110 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
16111 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +080016112
developera3511852023-06-14 14:12:59 +080016113 // Not supported
16114 output_struct->ssid_RetransCount = 0;
16115 output_struct->ssid_FailedRetransCount = 0;
16116 output_struct->ssid_RetryCount = 0;
16117 output_struct->ssid_MultipleRetryCount = 0;
16118 output_struct->ssid_ACKFailureCount = 0;
16119 output_struct->ssid_AggregatedPacketCount = 0;
developer72fb0bb2023-01-11 09:46:29 +080016120
developera3511852023-06-14 14:12:59 +080016121 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016122}
16123
developer37ad6bf2023-10-09 11:31:05 +080016124int mtk_get_ap_isolation_callback(struct nl_msg *msg, void *data) {
16125 struct nlattr *tb[NL80211_ATTR_MAX + 1];
16126 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX + 1];
16127 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
16128 unsigned char status;
16129 unsigned char *out_status = data;
16130 int err = 0;
16131
16132 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
16133 genlmsg_attrlen(gnlh, 0), NULL);
16134 if (err < 0){
16135 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
16136 return err;
16137 }
16138
16139 if (tb[NL80211_ATTR_VENDOR_DATA]) {
16140 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX,
16141 tb[NL80211_ATTR_VENDOR_DATA], NULL);
16142 if (err < 0){
16143 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
16144 return err;
16145 }
16146
16147 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_ISOLATION]) {
16148 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_ISOLATION]);
16149 if (status == 0) {
16150 wifi_debug(DEBUG_INFO, "disabled\n");
16151 } else {
16152 wifi_debug(DEBUG_INFO, "enabled\n");
16153 }
16154 *out_status = status;
16155 }
16156 }
16157 return 0;
16158
16159}
16160
developer72fb0bb2023-01-11 09:46:29 +080016161//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).
16162INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
16163{
developer37ad6bf2023-10-09 11:31:05 +080016164 char inf_name[IF_NAME_SIZE] = {0};
16165 unsigned int if_idx = 0;
16166 int ret = -1;
16167 struct unl unl_ins;
16168 struct nl_msg *msg = NULL;
16169 struct nlattr * msg_data = NULL;
16170 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080016171
developer37ad6bf2023-10-09 11:31:05 +080016172 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
16173 return RETURN_ERR;
16174 if_idx = if_nametoindex(inf_name);
developer75bd10c2023-06-27 11:34:08 +080016175
developer37ad6bf2023-10-09 11:31:05 +080016176 /*init mtk nl80211 vendor cmd*/
16177 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
16178 param.if_type = NL80211_ATTR_IFINDEX;
16179 param.if_idx = if_idx;
developer72fb0bb2023-01-11 09:46:29 +080016180
developer37ad6bf2023-10-09 11:31:05 +080016181 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
16182 if (ret) {
16183 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
16184 return RETURN_ERR;
16185 }
16186 /*add mtk vendor cmd data*/
16187 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_ISOLATION, 0xf)) {
16188 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
16189 nlmsg_free(msg);
16190 goto err;
16191 }
developer72fb0bb2023-01-11 09:46:29 +080016192
developer37ad6bf2023-10-09 11:31:05 +080016193 /*send mtk nl80211 vendor msg*/
16194 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_isolation_callback, output);
16195 if (ret) {
16196 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
16197 goto err;
16198 }
16199 /*deinit mtk nl80211 vendor msg*/
16200 mtk_nl80211_deint(&unl_ins);
16201 wifi_debug(DEBUG_INFO,"send cmd success, get output_bool:%d\n", *output);
16202 return RETURN_OK;
16203err:
16204 mtk_nl80211_deint(&unl_ins);
16205 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
16206 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016207}
16208
16209INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
16210{
developer37ad6bf2023-10-09 11:31:05 +080016211 char inf_name[IF_NAME_SIZE] = {0};
16212 unsigned int if_idx = 0;
16213 int ret = -1;
16214 struct unl unl_ins;
16215 struct nl_msg *msg = NULL;
16216 struct nlattr * msg_data = NULL;
16217 struct mtk_nl80211_param nl_param;
developer72fb0bb2023-01-11 09:46:29 +080016218
developer37ad6bf2023-10-09 11:31:05 +080016219 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
16220 return RETURN_ERR;
16221 if_idx = if_nametoindex(inf_name);
developer72fb0bb2023-01-11 09:46:29 +080016222
developer37ad6bf2023-10-09 11:31:05 +080016223 nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
16224 nl_param.if_type = NL80211_ATTR_IFINDEX;
16225 nl_param.if_idx = if_idx;
16226 /*init mtk nl80211 vendor cmd*/
16227 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_param);
16228 if (ret) {
16229 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
16230 return RETURN_ERR;
16231 }
16232 /*add mtk vendor cmd data*/
16233 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_ISOLATION, enable)) {
16234 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_ISOLATION);
16235 nlmsg_free(msg);
16236 goto err;
16237 }
developer75bd10c2023-06-27 11:34:08 +080016238
developer37ad6bf2023-10-09 11:31:05 +080016239 /*send mtk nl80211 vendor msg*/
16240 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
16241 if (ret) {
16242 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
16243 goto err;
16244 }
16245 /*deinit mtk nl80211 vendor msg*/
16246 mtk_nl80211_deint(&unl_ins);
16247 return RETURN_OK;
16248err:
16249 mtk_nl80211_deint(&unl_ins);
16250 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
16251 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016252}
16253
16254INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
16255{
developera3511852023-06-14 14:12:59 +080016256 char mgmtpwr_file[32] = {0};
developer8078acf2023-08-04 18:52:48 +080016257
developera3511852023-06-14 14:12:59 +080016258 char buf[32]={0};
developere40952c2023-06-15 18:46:43 +080016259 int res;
developerc14d83a2023-06-29 20:09:42 +080016260 long int tmp;
developera1255e42023-05-13 17:45:02 +080016261
developera3511852023-06-14 14:12:59 +080016262 if (NULL == output_dBm)
16263 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080016264 res = snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
16265 if (os_snprintf_error(sizeof(mgmtpwr_file), res)) {
16266 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16267 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080016268 }
developere40952c2023-06-15 18:46:43 +080016269
developer8078acf2023-08-04 18:52:48 +080016270 res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null", mgmtpwr_file);
16271 if (res) {
16272 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080016273 }
developer5b23cd02023-07-19 20:26:03 +080016274 if (strlen(buf) > 0) {
developerc14d83a2023-06-29 20:09:42 +080016275 if (hal_strtol(buf, 10, &tmp) < 0) {
16276 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080016277 }
developerc14d83a2023-06-29 20:09:42 +080016278 *output_dBm = tmp;
developerd14dff12023-06-28 22:47:44 +080016279 } else
developera1255e42023-05-13 17:45:02 +080016280 *output_dBm = 23;
developera3511852023-06-14 14:12:59 +080016281 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016282}
16283
16284INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
16285{
developera1255e42023-05-13 17:45:02 +080016286 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080016287 char mgmt_pwr_file[128]={0};
16288 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080016289 int if_idx, ret = 0;
16290 struct nl_msg *msg = NULL;
16291 struct nlattr * msg_data = NULL;
16292 struct mtk_nl80211_param param;
16293 struct unl unl_ins;
16294 char power[16] = {0};
developere40952c2023-06-15 18:46:43 +080016295 int res;
developera1255e42023-05-13 17:45:02 +080016296
16297 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16298
16299 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
16300 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080016301
16302 if_idx = if_nametoindex(interface_name);
16303 /*init mtk nl80211 vendor cmd*/
16304 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
16305 param.if_type = NL80211_ATTR_IFINDEX;
16306 param.if_idx = if_idx;
16307
16308 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
16309 if (ret) {
16310 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
16311 return RETURN_ERR;
16312 }
16313
16314 /*add mtk vendor cmd data*/
developere40952c2023-06-15 18:46:43 +080016315 res = snprintf(power, sizeof(power), "%d", dBm);
16316 if (os_snprintf_error(sizeof(power), res)) {
16317 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16318 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080016319 }
developere40952c2023-06-15 18:46:43 +080016320
developerfead3972023-05-25 20:15:02 +080016321 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
16322 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
16323 nlmsg_free(msg);
16324 goto err;
16325 }
16326
16327 /*send mtk nl80211 vendor msg*/
16328 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
16329 if (ret) {
16330 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
16331 goto err;
16332 }
16333
16334 /*deinit mtk nl80211 vendor msg*/
16335 mtk_nl80211_deint(&unl_ins);
16336 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
16337
developere40952c2023-06-15 18:46:43 +080016338 res = snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
16339 if (os_snprintf_error(sizeof(mgmt_pwr_file), res)) {
16340 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16341 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080016342 }
developere40952c2023-06-15 18:46:43 +080016343
developera1255e42023-05-13 17:45:02 +080016344 f = fopen(mgmt_pwr_file, "w");
16345 if (f == NULL) {
developerc14d83a2023-06-29 20:09:42 +080016346 wifi_debug(DEBUG_ERROR, "%s: fopen failed\n", __func__);
developera1255e42023-05-13 17:45:02 +080016347 return RETURN_ERR;
16348 }
16349 fprintf(f, "%d", dBm);
developerc14d83a2023-06-29 20:09:42 +080016350 if (fclose(f) == EOF)
16351 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
16352
developer72fb0bb2023-01-11 09:46:29 +080016353 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080016354err:
16355 mtk_nl80211_deint(&unl_ins);
16356 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
16357 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016358}
16359INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
16360{
developera3511852023-06-14 14:12:59 +080016361 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016362}
16363INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
16364{
developera3511852023-06-14 14:12:59 +080016365 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016366}
16367INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
16368{
developera3511852023-06-14 14:12:59 +080016369 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016370}
16371INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
16372{
developera3511852023-06-14 14:12:59 +080016373 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016374}
developer9f2358c2023-09-22 18:42:12 +080016375
developer72fb0bb2023-01-11 09:46:29 +080016376INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
16377{
developera3511852023-06-14 14:12:59 +080016378 char config_file[MAX_BUF_SIZE] = {0};
16379 struct params list;
developere40952c2023-06-15 18:46:43 +080016380 int res;
developer72fb0bb2023-01-11 09:46:29 +080016381
developera3511852023-06-14 14:12:59 +080016382 list.name = "bss_transition";
16383 list.value = activate?"1":"0";
developere40952c2023-06-15 18:46:43 +080016384 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
16385 if (os_snprintf_error(sizeof(config_file), res)) {
16386 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16387 return RETURN_ERR;
16388 }
developera3511852023-06-14 14:12:59 +080016389 wifi_hostapdWrite(config_file, &list, 1);
developer9f2358c2023-09-22 18:42:12 +080016390 wifi_hostapdProcessUpdate(apIndex, &list, 1);
16391 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080016392
developera3511852023-06-14 14:12:59 +080016393 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016394}
developer9f2358c2023-09-22 18:42:12 +080016395
16396
developer72fb0bb2023-01-11 09:46:29 +080016397wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
16398
16399void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
16400{
developera3511852023-06-14 14:12:59 +080016401 return;
developer72fb0bb2023-01-11 09:46:29 +080016402}
16403
16404INT wifi_setApCsaDeauth(INT apIndex, INT mode)
16405{
developera3511852023-06-14 14:12:59 +080016406 // TODO Implement me!
16407 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016408}
16409
16410INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
16411{
developera3511852023-06-14 14:12:59 +080016412 char file_name[128] = {0};
16413 FILE *f = NULL;
developer75bd10c2023-06-27 11:34:08 +080016414 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080016415
developera3511852023-06-14 14:12:59 +080016416 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016417
developera3511852023-06-14 14:12:59 +080016418 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
developercd0b70a2023-12-11 11:25:50 +080016419 for (int index = 0; index < get_runtime_max_radio(); index++) {
developere40952c2023-06-15 18:46:43 +080016420 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
16421 if (os_snprintf_error(sizeof(file_name), res)) {
16422 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16423 return RETURN_ERR;
16424 }
16425
developera3511852023-06-14 14:12:59 +080016426 f = fopen(file_name, "w");
16427 if (f == NULL)
16428 return RETURN_ERR;
16429 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080016430 if (mode) {
16431 ret = fprintf(f, "%s", essid);
16432 if (ret < 0)
16433 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
16434 }
developer72fb0bb2023-01-11 09:46:29 +080016435
developerd14dff12023-06-28 22:47:44 +080016436 if (fclose(f) != 0) {
16437 wifi_debug(DEBUG_ERROR, "fclose fail\n");
16438 return RETURN_ERR;
16439 }
developera3511852023-06-14 14:12:59 +080016440 }
16441 } else { // special case, need to set AP's SSID as filter for each radio.
developere40952c2023-06-15 18:46:43 +080016442 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
16443 if (os_snprintf_error(sizeof(file_name), res)) {
16444 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16445 return RETURN_ERR;
16446 }
16447
developera3511852023-06-14 14:12:59 +080016448 f = fopen(file_name, "w");
16449 if (f == NULL)
16450 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016451
developera3511852023-06-14 14:12:59 +080016452 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080016453 if (mode) {
16454 ret = fprintf(f, "%s", essid);
16455 if (ret < 0)
16456 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
16457 }
developer72fb0bb2023-01-11 09:46:29 +080016458
developer37646972023-06-29 10:58:43 +080016459 if (fclose(f) == EOF) {
16460 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
16461 return RETURN_ERR;
16462 }
developera3511852023-06-14 14:12:59 +080016463 }
developer72fb0bb2023-01-11 09:46:29 +080016464
developera3511852023-06-14 14:12:59 +080016465 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16466 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016467}
16468
16469INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
16470{
developera3511852023-06-14 14:12:59 +080016471 // TODO Implement me!
16472 //Apply wifi_pushRadioChannel() instantly
16473 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016474}
16475
16476INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
16477{
developera3511852023-06-14 14:12:59 +080016478 // TODO Implement me!
16479 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016480}
16481
developer72fb0bb2023-01-11 09:46:29 +080016482
developera3511852023-06-14 14:12:59 +080016483static int tidStats_callback(struct nl_msg *msg, void *arg) {
16484 struct nlattr *tb[NL80211_ATTR_MAX + 1];
16485 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
16486 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
16487 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
16488 int rem , tid_index = 0;
developer72fb0bb2023-01-11 09:46:29 +080016489
developera3511852023-06-14 14:12:59 +080016490 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
16491 wifi_associated_dev_tid_entry_t *stats_entry;
developer72fb0bb2023-01-11 09:46:29 +080016492
developera3511852023-06-14 14:12:59 +080016493 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
16494 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
16495 };
16496 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
16497 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
16498 };
developer72fb0bb2023-01-11 09:46:29 +080016499
developera3511852023-06-14 14:12:59 +080016500 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
16501 genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080016502
developer72fb0bb2023-01-11 09:46:29 +080016503
developera3511852023-06-14 14:12:59 +080016504 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080016505 wifi_debug(DEBUG_ERROR, "station stats missing!\n");
developera3511852023-06-14 14:12:59 +080016506 return NL_SKIP;
16507 }
developer72fb0bb2023-01-11 09:46:29 +080016508
developera3511852023-06-14 14:12:59 +080016509 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
16510 tb[NL80211_ATTR_STA_INFO],
16511 stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080016512 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080016513 return NL_SKIP;
16514 }
developer72fb0bb2023-01-11 09:46:29 +080016515
developera3511852023-06-14 14:12:59 +080016516 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
16517 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
16518 {
16519 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080016520
developera3511852023-06-14 14:12:59 +080016521 stats_entry->tid = tid_index;
16522 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080016523
developera3511852023-06-14 14:12:59 +080016524 if(sinfo[NL80211_STA_INFO_TID_STATS])
16525 {
16526 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
16527 printf("failed to parse nested stats attributes!");
16528 return NL_SKIP;
16529 }
16530 }
16531 if(stats_info[NL80211_TID_STATS_TX_MSDU])
16532 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080016533
developera3511852023-06-14 14:12:59 +080016534 if(tid_index < (PS_MAX_TID - 1))
16535 tid_index++;
16536 }
16537 }
16538 //ToDo: sum_time_ms, ewma_time_ms
16539 return NL_SKIP;
16540}
developer72fb0bb2023-01-11 09:46:29 +080016541
developera3511852023-06-14 14:12:59 +080016542INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
16543{
16544 Netlink nl;
16545 char if_name[IF_NAME_SIZE];
16546 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080016547 int res;
developerc3556192023-12-06 17:59:09 +080016548 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080016549
developerc3556192023-12-06 17:59:09 +080016550 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
16551 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
developera3511852023-06-14 14:12:59 +080016552 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +080016553 }
16554
16555 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
16556 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016557
developere40952c2023-06-15 18:46:43 +080016558 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
16559 if (os_snprintf_error(sizeof(if_name), res)) {
16560 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16561 return RETURN_ERR;
16562 }
developer72fb0bb2023-01-11 09:46:29 +080016563
developera3511852023-06-14 14:12:59 +080016564 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080016565
developera3511852023-06-14 14:12:59 +080016566 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080016567 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080016568 return -1;
16569 }
developer72fb0bb2023-01-11 09:46:29 +080016570
developera3511852023-06-14 14:12:59 +080016571 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080016572
developera3511852023-06-14 14:12:59 +080016573 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080016574 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080016575 nlfree(&nl);
16576 return -2;
16577 }
developer72fb0bb2023-01-11 09:46:29 +080016578
developera3511852023-06-14 14:12:59 +080016579 genlmsg_put(msg,
16580 NL_AUTO_PID,
16581 NL_AUTO_SEQ,
16582 nl.id,
16583 0,
16584 0,
16585 NL80211_CMD_GET_STATION,
16586 0);
developer72fb0bb2023-01-11 09:46:29 +080016587
developera3511852023-06-14 14:12:59 +080016588 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
16589 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
16590 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
16591 nl_send_auto_complete(nl.socket, msg);
16592 nl_recvmsgs(nl.socket, nl.cb);
16593 nlmsg_free(msg);
16594 nlfree(&nl);
16595 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016596}
16597
16598
16599INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
16600{
developera3511852023-06-14 14:12:59 +080016601 char interface_name[16] = {0};
developera3511852023-06-14 14:12:59 +080016602 char buf[128]={0};
16603 int freq = 0;
developere40952c2023-06-15 18:46:43 +080016604 int res;
developer72fb0bb2023-01-11 09:46:29 +080016605
developera3511852023-06-14 14:12:59 +080016606 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016607
developera3511852023-06-14 14:12:59 +080016608 // full mode is used to scan all channels.
16609 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
16610 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
16611 ieee80211_channel_to_frequency(chan_list[0], &freq);
developer72fb0bb2023-01-11 09:46:29 +080016612
developera3511852023-06-14 14:12:59 +080016613 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16614 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016615
developera3511852023-06-14 14:12:59 +080016616 if (freq)
developer8078acf2023-08-04 18:52:48 +080016617 res = _syscmd_secure(buf, sizeof(buf), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
developera3511852023-06-14 14:12:59 +080016618 else
developer8078acf2023-08-04 18:52:48 +080016619 res = _syscmd_secure(buf, sizeof(buf), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
16620 if (res) {
16621 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080016622 }
developer72fb0bb2023-01-11 09:46:29 +080016623
developera3511852023-06-14 14:12:59 +080016624 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016625
developera3511852023-06-14 14:12:59 +080016626 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016627}
16628
16629
16630INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
16631{
developera3511852023-06-14 14:12:59 +080016632 // TODO Implement me!
16633 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016634}
16635
16636INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
16637{
developera3511852023-06-14 14:12:59 +080016638 // TODO Implement me!
16639 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016640}
16641
16642INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
16643{
developera3511852023-06-14 14:12:59 +080016644 // TODO Implement me!
16645 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016646}
16647
16648INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
16649{
developera3511852023-06-14 14:12:59 +080016650 // TODO Implement me!
16651 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016652}
16653
16654INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
16655{
developera3511852023-06-14 14:12:59 +080016656 // TODO Implement me!
16657 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016658}
16659
16660INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
16661{
developera3511852023-06-14 14:12:59 +080016662 // TODO Implement me!
16663 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016664}
16665
16666INT wifi_steering_eventUnregister(void)
16667{
developera3511852023-06-14 14:12:59 +080016668 // TODO Implement me!
16669 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016670}
16671
16672INT wifi_delApAclDevices(INT apIndex)
16673{
developer7e4a2a62023-04-06 19:56:03 +080016674 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080016675 struct unl unl_ins;
16676 int if_idx = 0, ret = 0;
16677 struct nl_msg *msg = NULL;
16678 struct nlattr * msg_data = NULL;
16679 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080016680
developer7e4a2a62023-04-06 19:56:03 +080016681 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
16682 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080016683 if_idx = if_nametoindex(inf_name);
16684 if (!if_idx) {
16685 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
16686 return RETURN_ERR;
16687 }
16688 /*init mtk nl80211 vendor cmd*/
16689 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
16690 param.if_type = NL80211_ATTR_IFINDEX;
16691 param.if_idx = if_idx;
16692 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
16693 if (ret) {
16694 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
16695 return RETURN_ERR;
16696 }
16697 /*add mtk vendor cmd data*/
16698 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
16699 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
16700 nlmsg_free(msg);
16701 goto err;
16702 }
16703 /*send mtk nl80211 vendor msg*/
16704 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
16705 if (ret) {
16706 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
16707 goto err;
16708 }
16709 /*deinit mtk nl80211 vendor msg*/
16710 mtk_nl80211_deint(&unl_ins);
16711 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
16712 return RETURN_OK;
16713err:
16714 mtk_nl80211_deint(&unl_ins);
16715 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
16716 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016717
developera3511852023-06-14 14:12:59 +080016718 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016719}
16720
developer72fb0bb2023-01-11 09:46:29 +080016721static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080016722 struct nlattr *tb[NL80211_ATTR_MAX + 1];
16723 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developerc14d83a2023-06-29 20:09:42 +080016724 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
16725 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
developera3511852023-06-14 14:12:59 +080016726 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
16727 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080016728
developera3511852023-06-14 14:12:59 +080016729 nla_parse(tb,
16730 NL80211_ATTR_MAX,
16731 genlmsg_attrdata(gnlh, 0),
16732 genlmsg_attrlen(gnlh, 0),
16733 NULL);
developer72fb0bb2023-01-11 09:46:29 +080016734
developera3511852023-06-14 14:12:59 +080016735 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080016736 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080016737 return NL_SKIP;
16738 }
developer72fb0bb2023-01-11 09:46:29 +080016739
developera3511852023-06-14 14:12:59 +080016740 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080016741 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080016742 return NL_SKIP;
16743 }
16744 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080016745
developera3511852023-06-14 14:12:59 +080016746 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080016747
developera3511852023-06-14 14:12:59 +080016748 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
16749 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
developer75bd10c2023-06-27 11:34:08 +080016750 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080016751 return NL_SKIP;
16752 }
16753 }
developer72fb0bb2023-01-11 09:46:29 +080016754
developera3511852023-06-14 14:12:59 +080016755 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
16756 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
16757 printf("failed to parse nested stats attributes!");
16758 return NL_SKIP;
16759 }
16760 }
16761 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080016762
developera3511852023-06-14 14:12:59 +080016763 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
16764 {
16765 printf("Type is VHT\n");
16766 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
16767 ((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 +080016768
developera3511852023-06-14 14:12:59 +080016769 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
16770 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
16771 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
16772 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
16773 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
16774 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
16775 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
16776 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
16777 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
16778 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
16779 } else {
16780 printf(" OFDM or CCK \n");
16781 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
16782 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
16783 }
16784 }
developer72fb0bb2023-01-11 09:46:29 +080016785
developera3511852023-06-14 14:12:59 +080016786 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
developereff896f2023-05-29 14:52:55 +080016787 if(rinfo[NL80211_RATE_INFO_MCS])
16788 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
16789 }
developera3511852023-06-14 14:12:59 +080016790 if (sinfo[NL80211_STA_INFO_RX_BYTES64])
developereff896f2023-05-29 14:52:55 +080016791 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
16792 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
16793 ((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 +080016794
developera3511852023-06-14 14:12:59 +080016795 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
16796 if (stats_info[NL80211_TID_STATS_RX_MSDU])
developereff896f2023-05-29 14:52:55 +080016797 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
16798 }
developer72fb0bb2023-01-11 09:46:29 +080016799
developereff896f2023-05-29 14:52:55 +080016800 if (sinfo[NL80211_STA_INFO_SIGNAL])
16801 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
16802 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
16803 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
16804 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
16805 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
16806 //rssi_array need to be filled
16807 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080016808}
developer72fb0bb2023-01-11 09:46:29 +080016809
16810INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
16811{
developera3511852023-06-14 14:12:59 +080016812 Netlink nl;
16813 char if_name[32];
developerc3556192023-12-06 17:59:09 +080016814 int main_vap_idx;
16815
16816 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
16817 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
16818 return RETURN_ERR;
16819 }
16820
16821 if (wifi_GetInterfaceName(main_vap_idx, if_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080016822 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016823
developera3511852023-06-14 14:12:59 +080016824 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080016825
developera3511852023-06-14 14:12:59 +080016826 if (*output_array_size <= 0)
16827 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016828
developera3511852023-06-14 14:12:59 +080016829 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080016830
developera3511852023-06-14 14:12:59 +080016831 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080016832 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080016833 return 0;
16834 }
developer72fb0bb2023-01-11 09:46:29 +080016835
developera3511852023-06-14 14:12:59 +080016836 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080016837
developera3511852023-06-14 14:12:59 +080016838 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080016839 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080016840 nlfree(&nl);
16841 return 0;
16842 }
developer72fb0bb2023-01-11 09:46:29 +080016843
developera3511852023-06-14 14:12:59 +080016844 genlmsg_put(msg,
16845 NL_AUTO_PID,
16846 NL_AUTO_SEQ,
16847 nl.id,
16848 0,
16849 0,
16850 NL80211_CMD_GET_STATION,
16851 0);
developer72fb0bb2023-01-11 09:46:29 +080016852
developera3511852023-06-14 14:12:59 +080016853 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
16854 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
16855 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
16856 nl_send_auto_complete(nl.socket, msg);
16857 nl_recvmsgs(nl.socket, nl.cb);
16858 nlmsg_free(msg);
16859 nlfree(&nl);
16860 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016861}
16862
developer72fb0bb2023-01-11 09:46:29 +080016863static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080016864 struct nlattr *tb[NL80211_ATTR_MAX + 1];
16865 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developerc14d83a2023-06-29 20:09:42 +080016866 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
16867 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
developera3511852023-06-14 14:12:59 +080016868 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
16869 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080016870
developera3511852023-06-14 14:12:59 +080016871 nla_parse(tb,
16872 NL80211_ATTR_MAX,
16873 genlmsg_attrdata(gnlh, 0),
16874 genlmsg_attrlen(gnlh, 0),
16875 NULL);
developer72fb0bb2023-01-11 09:46:29 +080016876
developera3511852023-06-14 14:12:59 +080016877 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080016878 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080016879 return NL_SKIP;
16880 }
developer72fb0bb2023-01-11 09:46:29 +080016881
developera3511852023-06-14 14:12:59 +080016882 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080016883 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080016884 return NL_SKIP;
16885 }
developer72fb0bb2023-01-11 09:46:29 +080016886
developera3511852023-06-14 14:12:59 +080016887 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080016888
developera3511852023-06-14 14:12:59 +080016889 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080016890
developera3511852023-06-14 14:12:59 +080016891 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
16892 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +080016893 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080016894 return NL_SKIP;
16895 }
16896 }
developer72fb0bb2023-01-11 09:46:29 +080016897
developera3511852023-06-14 14:12:59 +080016898 if(sinfo[NL80211_STA_INFO_TID_STATS])
16899 {
16900 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
16901 printf("failed to parse nested stats attributes!");
16902 return NL_SKIP;
16903 }
16904 }
16905 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
16906 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
16907 {
16908 printf("Type is VHT\n");
16909 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
16910 ((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 +080016911
developera3511852023-06-14 14:12:59 +080016912 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
16913 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
16914 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
16915 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
16916 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
16917 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
16918 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
16919 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
16920 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
16921 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
16922 }
16923 else
16924 {
16925 printf(" OFDM or CCK \n");
16926 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
16927 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
16928 }
16929 }
developer72fb0bb2023-01-11 09:46:29 +080016930
developera3511852023-06-14 14:12:59 +080016931 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
16932 if(rinfo[NL80211_RATE_INFO_MCS])
16933 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
16934 }
developer72fb0bb2023-01-11 09:46:29 +080016935
developera3511852023-06-14 14:12:59 +080016936 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
16937 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
16938 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
16939 ((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 +080016940
developera3511852023-06-14 14:12:59 +080016941 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
16942 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
16943 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080016944
developera3511852023-06-14 14:12:59 +080016945 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
16946 if(stats_info[NL80211_TID_STATS_TX_MSDU])
16947 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
16948 }
developer72fb0bb2023-01-11 09:46:29 +080016949
developera3511852023-06-14 14:12:59 +080016950 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
16951 ((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 +080016952
developera3511852023-06-14 14:12:59 +080016953 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
16954 ((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 +080016955
developera3511852023-06-14 14:12:59 +080016956 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080016957}
developer72fb0bb2023-01-11 09:46:29 +080016958
16959INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
16960{
developera3511852023-06-14 14:12:59 +080016961 Netlink nl;
16962 char if_name[IF_NAME_SIZE];
16963 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080016964 int res;
developerc3556192023-12-06 17:59:09 +080016965 int main_vap_idx;
developere40952c2023-06-15 18:46:43 +080016966
developerc3556192023-12-06 17:59:09 +080016967 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
16968 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
16969 return RETURN_ERR;
16970 }
developera3511852023-06-14 14:12:59 +080016971
developerc3556192023-12-06 17:59:09 +080016972 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080016973 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016974
developera3511852023-06-14 14:12:59 +080016975 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080016976
developera3511852023-06-14 14:12:59 +080016977 if (*output_array_size <= 0)
16978 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016979
developere40952c2023-06-15 18:46:43 +080016980 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
16981 if (os_snprintf_error(sizeof(if_name), res)) {
16982 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16983 return RETURN_ERR;
16984 }
developer72fb0bb2023-01-11 09:46:29 +080016985
developera3511852023-06-14 14:12:59 +080016986 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080016987
developera3511852023-06-14 14:12:59 +080016988 if(nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080016989 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080016990 return 0;
16991 }
developer72fb0bb2023-01-11 09:46:29 +080016992
developera3511852023-06-14 14:12:59 +080016993 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080016994
developera3511852023-06-14 14:12:59 +080016995 if(!msg) {
developer75bd10c2023-06-27 11:34:08 +080016996 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080016997 nlfree(&nl);
16998 return 0;
16999 }
developer72fb0bb2023-01-11 09:46:29 +080017000
developera3511852023-06-14 14:12:59 +080017001 genlmsg_put(msg,
17002 NL_AUTO_PID,
17003 NL_AUTO_SEQ,
17004 nl.id,
17005 0,
17006 0,
17007 NL80211_CMD_GET_STATION,
17008 0);
developer72fb0bb2023-01-11 09:46:29 +080017009
developera3511852023-06-14 14:12:59 +080017010 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
17011 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
17012 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
17013 nl_send_auto_complete(nl.socket, msg);
17014 nl_recvmsgs(nl.socket, nl.cb);
17015 nlmsg_free(msg);
17016 nlfree(&nl);
17017 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017018}
17019
17020INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
17021{
developera3511852023-06-14 14:12:59 +080017022 // TODO Implement me!
17023 char buf[MAX_BUF_SIZE] = {0};
17024 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080017025 int res;
developer72fb0bb2023-01-11 09:46:29 +080017026
developere40952c2023-06-15 18:46:43 +080017027 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
17028 if (os_snprintf_error(sizeof(config_file), res)) {
17029 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17030 return RETURN_ERR;
17031 }
developera3511852023-06-14 14:12:59 +080017032 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
17033 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080017034
developera3511852023-06-14 14:12:59 +080017035 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017036}
17037
17038INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
17039{
developera3511852023-06-14 14:12:59 +080017040 char config_file[MAX_BUF_SIZE] = {0};
17041 struct params list;
developer75bd10c2023-06-27 11:34:08 +080017042 int res;
developer72fb0bb2023-01-11 09:46:29 +080017043
developera3511852023-06-14 14:12:59 +080017044 list.name = "rrm_neighbor_report";
17045 list.value = activate?"1":"0";
developer75bd10c2023-06-27 11:34:08 +080017046 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
17047 if (os_snprintf_error(sizeof(config_file), res)) {
17048 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17049 return RETURN_ERR;
17050 }
developer9f2358c2023-09-22 18:42:12 +080017051
developera3511852023-06-14 14:12:59 +080017052 wifi_hostapdWrite(config_file, &list, 1);
developer9f2358c2023-09-22 18:42:12 +080017053 wifi_hostapdProcessUpdate(apIndex, &list, 1);
17054 wifi_quick_reload_ap(apIndex);
developer9f2358c2023-09-22 18:42:12 +080017055
developera3511852023-06-14 14:12:59 +080017056 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017057}
17058
developer9f2358c2023-09-22 18:42:12 +080017059
developer72fb0bb2023-01-11 09:46:29 +080017060INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
17061{
developera3511852023-06-14 14:12:59 +080017062 char buf[32] = {0};
17063 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080017064 int res;
developer72fb0bb2023-01-11 09:46:29 +080017065
developer75bd10c2023-06-27 11:34:08 +080017066 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
17067 if (os_snprintf_error(sizeof(config_file), res)) {
17068 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17069 return RETURN_ERR;
17070 }
developera3511852023-06-14 14:12:59 +080017071 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
17072 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080017073
developera3511852023-06-14 14:12:59 +080017074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017075}
17076#undef HAL_NETLINK_IMPL
17077#ifdef HAL_NETLINK_IMPL
17078static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080017079 struct nlattr *tb[NL80211_ATTR_MAX + 1];
17080 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
17081 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
17082 char dev[20];
17083 int freq =0 ;
17084 static int i=0;
developer72fb0bb2023-01-11 09:46:29 +080017085
developera3511852023-06-14 14:12:59 +080017086 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
developer72fb0bb2023-01-11 09:46:29 +080017087
developera3511852023-06-14 14:12:59 +080017088 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
17089 };
developer72fb0bb2023-01-11 09:46:29 +080017090
developera3511852023-06-14 14:12:59 +080017091 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080017092
developera3511852023-06-14 14:12:59 +080017093 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080017094
developera3511852023-06-14 14:12:59 +080017095 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
17096 fprintf(stderr, "survey data missing!\n");
17097 return NL_SKIP;
17098 }
developer72fb0bb2023-01-11 09:46:29 +080017099
developera3511852023-06-14 14:12:59 +080017100 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
17101 {
17102 fprintf(stderr, "failed to parse nested attributes!\n");
17103 return NL_SKIP;
17104 }
developer72fb0bb2023-01-11 09:46:29 +080017105
17106
developera3511852023-06-14 14:12:59 +080017107 if(out[0].array_size == 1 )
17108 {
17109 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
17110 {
17111 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
17112 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
17113 out[0].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080017114
developera3511852023-06-14 14:12:59 +080017115 if (sinfo[NL80211_SURVEY_INFO_NOISE])
17116 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
17117 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
17118 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
17119 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
17120 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
17121 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
17122 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
17123 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
17124 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
17125 if (sinfo[NL80211_SURVEY_INFO_TIME])
17126 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
17127 return NL_STOP;
17128 }
17129 } else {
17130 if ( i <= out[0].array_size ) {
17131 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
17132 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
17133 out[i].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080017134
developera3511852023-06-14 14:12:59 +080017135 if (sinfo[NL80211_SURVEY_INFO_NOISE])
17136 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
17137 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
17138 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
17139 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
17140 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
17141 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
17142 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
17143 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
17144 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
17145 if (sinfo[NL80211_SURVEY_INFO_TIME])
17146 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
17147 }
17148 }
developer72fb0bb2023-01-11 09:46:29 +080017149
developera3511852023-06-14 14:12:59 +080017150 i++;
17151 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080017152}
17153#endif
17154
17155static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
17156{
developer8078acf2023-08-04 18:52:48 +080017157 char output[MAX_BUF_SIZE];
developera3511852023-06-14 14:12:59 +080017158 FILE *fp;
developer8078acf2023-08-04 18:52:48 +080017159
developer72fb0bb2023-01-11 09:46:29 +080017160
developera3511852023-06-14 14:12:59 +080017161 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
17162 {
17163 printf("Creating Frequency-Channel Map\n");
developer33f13ba2023-07-12 16:19:06 +080017164 v_secure_system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
developera3511852023-06-14 14:12:59 +080017165 }
developere40952c2023-06-15 18:46:43 +080017166
developer8078acf2023-08-04 18:52:48 +080017167 if((fp = v_secure_popen("r", "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel)))
developera3511852023-06-14 14:12:59 +080017168 {
developerc14d83a2023-06-29 20:09:42 +080017169 if (fgets(output, sizeof(output), fp) == NULL) {
17170 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developer8078acf2023-08-04 18:52:48 +080017171 v_secure_pclose(fp);
developerc14d83a2023-06-29 20:09:42 +080017172 return RETURN_ERR;
17173 }
developera3511852023-06-14 14:12:59 +080017174 *freqMHz = atoi(output);
developer8078acf2023-08-04 18:52:48 +080017175 v_secure_pclose(fp);
developera3511852023-06-14 14:12:59 +080017176 }
developer72fb0bb2023-01-11 09:46:29 +080017177
developera3511852023-06-14 14:12:59 +080017178 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017179}
17180
developer2f79c922023-06-02 17:33:42 +080017181static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
developer72fb0bb2023-01-11 09:46:29 +080017182{
developera3511852023-06-14 14:12:59 +080017183 int freqMHz = -1;
17184 char cmd[MAX_CMD_SIZE] = {'\0'};
17185 char interface_name[16] = {0};
developer32f2a182023-06-27 19:50:41 +080017186 int res;
developerc3556192023-12-06 17:59:09 +080017187 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080017188
developera3511852023-06-14 14:12:59 +080017189 ieee80211_channel_to_frequency(channel, &freqMHz);
17190 if (freqMHz == -1) {
17191 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
17192 return -1;
17193 }
developer72fb0bb2023-01-11 09:46:29 +080017194
developerc3556192023-12-06 17:59:09 +080017195 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
17196 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
17197 return RETURN_ERR;
17198 }
17199
17200 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017201 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
17202 }
developer32f2a182023-06-27 19:50:41 +080017203 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz);
17204 if (os_snprintf_error(sizeof(cmd), res)) {
17205 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17206 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080017207 }
developer72fb0bb2023-01-11 09:46:29 +080017208
developer8078acf2023-08-04 18:52:48 +080017209 if (_syscmd_secure(buf, bufsz, "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) == RETURN_ERR) {
developera3511852023-06-14 14:12:59 +080017210 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
17211 return -1;
17212 }
developer72fb0bb2023-01-11 09:46:29 +080017213
developera3511852023-06-14 14:12:59 +080017214 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017215}
17216
17217static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
17218{
developera3511852023-06-14 14:12:59 +080017219 const char *ptr = buf;
17220 char *key = NULL;
17221 char *val = NULL;
17222 char line[256] = { '\0' };
developer72fb0bb2023-01-11 09:46:29 +080017223
developera3511852023-06-14 14:12:59 +080017224 while ((ptr = get_line_from_str_buf(ptr, line))) {
17225 if (strstr(line, "Frequency")) continue;
developer72fb0bb2023-01-11 09:46:29 +080017226
developera3511852023-06-14 14:12:59 +080017227 key = strtok(line, ":");
developerc14d83a2023-06-29 20:09:42 +080017228 if (key == NULL)
17229 continue;
developera3511852023-06-14 14:12:59 +080017230 val = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080017231 if (val == NULL)
17232 continue;
developera3511852023-06-14 14:12:59 +080017233 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
developer72fb0bb2023-01-11 09:46:29 +080017234
developera3511852023-06-14 14:12:59 +080017235 if (!strcmp(key, "noise")) {
developer37646972023-06-29 10:58:43 +080017236 if (sscanf(val, "%d", &stats->ch_noise) == EOF)
17237 continue;
developera3511852023-06-14 14:12:59 +080017238 if (stats->ch_noise == 0) {
17239 // Workaround for missing noise information.
17240 // Assume -95 for 2.4G and -103 for 5G
17241 if (radioIndex == 0) stats->ch_noise = -95;
17242 if (radioIndex == 1) stats->ch_noise = -103;
17243 }
17244 }
17245 else if (!strcmp(key, "channel active time")) {
developer37646972023-06-29 10:58:43 +080017246 if (sscanf(val, "%llu", &stats->ch_utilization_total) == EOF)
17247 continue;
developera3511852023-06-14 14:12:59 +080017248 }
17249 else if (!strcmp(key, "channel busy time")) {
developer37646972023-06-29 10:58:43 +080017250 if (sscanf(val, "%llu", &stats->ch_utilization_busy) == EOF)
17251 continue;
developera3511852023-06-14 14:12:59 +080017252 }
17253 else if (!strcmp(key, "channel receive time")) {
developer37646972023-06-29 10:58:43 +080017254 if (sscanf(val, "%llu", &stats->ch_utilization_busy_rx) == EOF)
17255 continue;
developera3511852023-06-14 14:12:59 +080017256 }
17257 else if (!strcmp(key, "channel transmit time")) {
developer37646972023-06-29 10:58:43 +080017258 if (sscanf(val, "%llu", &stats->ch_utilization_busy_tx) == EOF)
17259 continue;
developera3511852023-06-14 14:12:59 +080017260 }
17261 };
developer72fb0bb2023-01-11 09:46:29 +080017262
developera3511852023-06-14 14:12:59 +080017263 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017264}
17265
17266INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
17267{
developera3511852023-06-14 14:12:59 +080017268 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017269#ifdef HAL_NETLINK_IMPL
developera3511852023-06-14 14:12:59 +080017270 Netlink nl;
17271 wifi_channelStats_t_loc local[array_size];
17272 char if_name[32];
developerc3556192023-12-06 17:59:09 +080017273 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080017274
developera3511852023-06-14 14:12:59 +080017275 local[0].array_size = array_size;
developer72fb0bb2023-01-11 09:46:29 +080017276
developerc3556192023-12-06 17:59:09 +080017277 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
17278 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
17279 return RETURN_ERR;
17280 }
17281
17282 if (wifi_GetInterfaceName(main_vap_idx, if_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080017283 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017284
developera3511852023-06-14 14:12:59 +080017285 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080017286
developera3511852023-06-14 14:12:59 +080017287 if (nl.id < 0) {
developerc14d83a2023-06-29 20:09:42 +080017288 wifi_debug(DEBUG_ERROR,, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080017289 return -1;
17290 }
developer72fb0bb2023-01-11 09:46:29 +080017291
developera3511852023-06-14 14:12:59 +080017292 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080017293
developera3511852023-06-14 14:12:59 +080017294 if (!msg) {
developerc14d83a2023-06-29 20:09:42 +080017295 wifi_debug(DEBUG_ERROR,, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080017296 nlfree(&nl);
17297 return -2;
17298 }
developer72fb0bb2023-01-11 09:46:29 +080017299
developera3511852023-06-14 14:12:59 +080017300 genlmsg_put(msg,
17301 NL_AUTO_PID,
17302 NL_AUTO_SEQ,
17303 nl.id,
17304 0,
17305 NLM_F_DUMP,
17306 NL80211_CMD_GET_SURVEY,
17307 0);
developer72fb0bb2023-01-11 09:46:29 +080017308
developera3511852023-06-14 14:12:59 +080017309 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
17310 nl_send_auto_complete(nl.socket, msg);
17311 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
17312 nl_recvmsgs(nl.socket, nl.cb);
17313 nlmsg_free(msg);
17314 nlfree(&nl);
17315 //Copying the Values
17316 for(int i=0;i<array_size;i++)
17317 {
17318 input_output_channelStats_array[i].ch_number = local[i].ch_number;
17319 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
17320 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
17321 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
17322 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
17323 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
17324 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
17325 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
17326 }
developer72fb0bb2023-01-11 09:46:29 +080017327#else
developera3511852023-06-14 14:12:59 +080017328 ULONG channel = 0;
17329 int i;
17330 int number_of_channels = array_size;
17331 char buf[512];
developer72fb0bb2023-01-11 09:46:29 +080017332
developera3511852023-06-14 14:12:59 +080017333 if (number_of_channels == 0) {
17334 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
17335 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
17336 return RETURN_ERR;
17337 }
17338 number_of_channels = 1;
17339 input_output_channelStats_array[0].ch_number = channel;
17340 }
developer72fb0bb2023-01-11 09:46:29 +080017341
developera3511852023-06-14 14:12:59 +080017342 for (i = 0; i < number_of_channels; i++) {
developer72fb0bb2023-01-11 09:46:29 +080017343
developera3511852023-06-14 14:12:59 +080017344 input_output_channelStats_array[i].ch_noise = 0;
17345 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
17346 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
17347 input_output_channelStats_array[i].ch_utilization_busy = 0;
17348 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
17349 input_output_channelStats_array[i].ch_utilization_total = 0;
developer72fb0bb2023-01-11 09:46:29 +080017350
developera3511852023-06-14 14:12:59 +080017351 memset(buf, 0, sizeof(buf));
17352 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
17353 return RETURN_ERR;
17354 }
17355 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
17356 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
17357 return RETURN_ERR;
17358 }
developer72fb0bb2023-01-11 09:46:29 +080017359
developera3511852023-06-14 14:12:59 +080017360 // XXX: fake missing 'self' counter which is not available in iw survey output
17361 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
17362 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 +080017363
developera3511852023-06-14 14:12:59 +080017364 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
17365 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
17366 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
17367 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
17368 input_output_channelStats_array[i].ch_utilization_total *= 1000;
developer72fb0bb2023-01-11 09:46:29 +080017369
developera3511852023-06-14 14:12:59 +080017370 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",
17371 __func__,
17372 input_output_channelStats_array[i].ch_number,
17373 input_output_channelStats_array[i].ch_noise,
17374 input_output_channelStats_array[i].ch_utilization_total,
17375 input_output_channelStats_array[i].ch_utilization_busy,
17376 input_output_channelStats_array[i].ch_utilization_busy_rx,
17377 input_output_channelStats_array[i].ch_utilization_busy_tx,
17378 input_output_channelStats_array[i].ch_utilization_busy_self,
17379 input_output_channelStats_array[i].ch_utilization_busy_ext);
17380 }
developer72fb0bb2023-01-11 09:46:29 +080017381#endif
developera3511852023-06-14 14:12:59 +080017382 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17383 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017384}
17385#define HAL_NETLINK_IMPL
17386
17387/* Hostapd events */
17388
17389#ifndef container_of
17390#define offset_of(st, m) ((size_t)&(((st *)0)->m))
17391#define container_of(ptr, type, member) \
developera3511852023-06-14 14:12:59 +080017392 ((type *)((char *)ptr - offset_of(type, member)))
developer72fb0bb2023-01-11 09:46:29 +080017393#endif /* container_of */
17394
17395struct ctrl {
developera3511852023-06-14 14:12:59 +080017396 char sockpath[128];
17397 char sockdir[128];
17398 char bss[IFNAMSIZ];
17399 char reply[4096];
17400 int ssid_index;
17401 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
17402 void (*overrun)(struct ctrl *ctrl);
17403 struct wpa_ctrl *wpa;
17404 unsigned int ovfl;
17405 size_t reply_len;
17406 int initialized;
17407 ev_timer retry;
17408 ev_timer watchdog;
17409 ev_stat stat;
17410 ev_io io;
developer72fb0bb2023-01-11 09:46:29 +080017411};
17412static wifi_newApAssociatedDevice_callback clients_connect_cb;
17413static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
17414static struct ctrl wpa_ctrl[MAX_APS];
17415static int initialized;
17416
17417static unsigned int ctrl_get_drops(struct ctrl *ctrl)
17418{
developera3511852023-06-14 14:12:59 +080017419 char cbuf[256] = {};
17420 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
17421 struct cmsghdr *cmsg;
17422 unsigned int ovfl = ctrl->ovfl;
developer86035662023-06-28 19:21:12 +080017423 unsigned int drop = 0;
developer72fb0bb2023-01-11 09:46:29 +080017424
developer86035662023-06-28 19:21:12 +080017425 if (recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT) < 0)
17426 return drop;
developera3511852023-06-14 14:12:59 +080017427 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
17428 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
17429 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
developer72fb0bb2023-01-11 09:46:29 +080017430
developera3511852023-06-14 14:12:59 +080017431 drop = ovfl - ctrl->ovfl;
17432 ctrl->ovfl = ovfl;
developer72fb0bb2023-01-11 09:46:29 +080017433
developera3511852023-06-14 14:12:59 +080017434 return drop;
developer72fb0bb2023-01-11 09:46:29 +080017435}
17436
17437static void ctrl_close(struct ctrl *ctrl)
17438{
developera3511852023-06-14 14:12:59 +080017439 if (ctrl->io.cb)
17440 ev_io_stop(EV_DEFAULT_ &ctrl->io);
17441 if (ctrl->retry.cb)
17442 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
17443 if (!ctrl->wpa)
17444 return;
developer72fb0bb2023-01-11 09:46:29 +080017445
developera3511852023-06-14 14:12:59 +080017446 wpa_ctrl_detach(ctrl->wpa);
17447 wpa_ctrl_close(ctrl->wpa);
17448 ctrl->wpa = NULL;
17449 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
developer72fb0bb2023-01-11 09:46:29 +080017450}
17451
17452static void ctrl_process(struct ctrl *ctrl)
17453{
developera3511852023-06-14 14:12:59 +080017454 const char *str;
17455 int drops;
17456 int level;
developer72fb0bb2023-01-11 09:46:29 +080017457
developera3511852023-06-14 14:12:59 +080017458 /* Example events:
17459 *
17460 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
17461 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
17462 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
17463 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
17464 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
17465 */
17466 if (!(str = index(ctrl->reply, '>')))
17467 return;
17468 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
17469 return;
developer72fb0bb2023-01-11 09:46:29 +080017470
developera3511852023-06-14 14:12:59 +080017471 str++;
developer72fb0bb2023-01-11 09:46:29 +080017472
developera3511852023-06-14 14:12:59 +080017473 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
17474 if (!(str = index(ctrl->reply, ' ')))
17475 return;
17476 wifi_associated_dev_t sta;
17477 memset(&sta, 0, sizeof(sta));
developer72fb0bb2023-01-11 09:46:29 +080017478
developere75ba632023-06-29 16:03:33 +080017479 if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
17480 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
17481 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]) == EOF) {
17482 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
17483 return;
17484 }
developer72fb0bb2023-01-11 09:46:29 +080017485
developera3511852023-06-14 14:12:59 +080017486 sta.cli_Active=true;
developer72fb0bb2023-01-11 09:46:29 +080017487
developera3511852023-06-14 14:12:59 +080017488 (clients_connect_cb)(ctrl->ssid_index, &sta);
17489 goto handled;
17490 }
developer72fb0bb2023-01-11 09:46:29 +080017491
developera3511852023-06-14 14:12:59 +080017492 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
17493 if (!(str = index(ctrl->reply, ' ')))
17494 return;
developer72fb0bb2023-01-11 09:46:29 +080017495
developera3511852023-06-14 14:12:59 +080017496 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
17497 goto handled;
17498 }
developer72fb0bb2023-01-11 09:46:29 +080017499
developera3511852023-06-14 14:12:59 +080017500 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
17501 printf("CTRL_WPA: handle TERMINATING event\n");
17502 goto retry;
17503 }
developer72fb0bb2023-01-11 09:46:29 +080017504
developera3511852023-06-14 14:12:59 +080017505 if (strncmp("AP-DISABLED", str, 11) == 0) {
17506 printf("CTRL_WPA: handle AP-DISABLED\n");
17507 goto retry;
17508 }
developer72fb0bb2023-01-11 09:46:29 +080017509
developera3511852023-06-14 14:12:59 +080017510 printf("Event not supported!!\n");
developer72fb0bb2023-01-11 09:46:29 +080017511
17512handled:
17513
developera3511852023-06-14 14:12:59 +080017514 if ((drops = ctrl_get_drops(ctrl))) {
17515 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
17516 if (ctrl->overrun)
17517 ctrl->overrun(ctrl);
17518 }
developer72fb0bb2023-01-11 09:46:29 +080017519
developera3511852023-06-14 14:12:59 +080017520 return;
developer72fb0bb2023-01-11 09:46:29 +080017521
17522retry:
developera3511852023-06-14 14:12:59 +080017523 printf("WPA_CTRL: closing\n");
17524 ctrl_close(ctrl);
17525 printf("WPA_CTRL: retrying from ctrl prcoess\n");
17526 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
developer72fb0bb2023-01-11 09:46:29 +080017527}
17528
17529static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
17530{
developera3511852023-06-14 14:12:59 +080017531 struct ctrl *ctrl = container_of(io, struct ctrl, io);
17532 int err;
developer72fb0bb2023-01-11 09:46:29 +080017533
developera3511852023-06-14 14:12:59 +080017534 memset(ctrl->reply, 0, sizeof(ctrl->reply));
17535 ctrl->reply_len = sizeof(ctrl->reply) - 1;
17536 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
17537 ctrl->reply[ctrl->reply_len] = 0;
17538 if (err < 0) {
17539 if (errno == EAGAIN || errno == EWOULDBLOCK)
17540 return;
17541 ctrl_close(ctrl);
17542 ev_timer_again(EV_A_ &ctrl->retry);
17543 return;
17544 }
developer72fb0bb2023-01-11 09:46:29 +080017545
developera3511852023-06-14 14:12:59 +080017546 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080017547}
17548
17549static int ctrl_open(struct ctrl *ctrl)
17550{
developera3511852023-06-14 14:12:59 +080017551 int fd;
developer72fb0bb2023-01-11 09:46:29 +080017552
developera3511852023-06-14 14:12:59 +080017553 if (ctrl->wpa)
17554 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017555
developera3511852023-06-14 14:12:59 +080017556 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
17557 if (!ctrl->wpa)
17558 goto err;
developer72fb0bb2023-01-11 09:46:29 +080017559
developera3511852023-06-14 14:12:59 +080017560 if (wpa_ctrl_attach(ctrl->wpa) < 0)
17561 goto err_close;
developer72fb0bb2023-01-11 09:46:29 +080017562
developera3511852023-06-14 14:12:59 +080017563 fd = wpa_ctrl_get_fd(ctrl->wpa);
17564 if (fd < 0)
17565 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080017566
developera3511852023-06-14 14:12:59 +080017567 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
17568 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080017569
developera3511852023-06-14 14:12:59 +080017570 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
17571 ev_io_start(EV_DEFAULT_ &ctrl->io);
developer72fb0bb2023-01-11 09:46:29 +080017572
developera3511852023-06-14 14:12:59 +080017573 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017574
17575err_detach:
developera3511852023-06-14 14:12:59 +080017576 wpa_ctrl_detach(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080017577err_close:
developera3511852023-06-14 14:12:59 +080017578 wpa_ctrl_close(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080017579err:
developera3511852023-06-14 14:12:59 +080017580 ctrl->wpa = NULL;
17581 return -1;
developer72fb0bb2023-01-11 09:46:29 +080017582}
17583
17584static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
17585{
developera3511852023-06-14 14:12:59 +080017586 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
developer72fb0bb2023-01-11 09:46:29 +080017587
developera3511852023-06-14 14:12:59 +080017588 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
17589 ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080017590}
17591
17592static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
17593{
developera3511852023-06-14 14:12:59 +080017594 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
developer72fb0bb2023-01-11 09:46:29 +080017595
developera3511852023-06-14 14:12:59 +080017596 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
17597 if (ctrl_open(ctrl) == 0) {
17598 printf("WPA_CTRL: retry successful\n");
17599 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
17600 }
developer72fb0bb2023-01-11 09:46:29 +080017601}
17602
17603int ctrl_enable(struct ctrl *ctrl)
17604{
developera3511852023-06-14 14:12:59 +080017605 if (ctrl->wpa)
17606 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017607
developera3511852023-06-14 14:12:59 +080017608 if (!ctrl->stat.cb) {
17609 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
17610 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
17611 }
developer72fb0bb2023-01-11 09:46:29 +080017612
developera3511852023-06-14 14:12:59 +080017613 if (!ctrl->retry.cb) {
17614 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
17615 }
developer72fb0bb2023-01-11 09:46:29 +080017616
developera3511852023-06-14 14:12:59 +080017617 return ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080017618}
17619
17620static void
17621ctrl_msg_cb(char *buf, size_t len)
17622{
developera3511852023-06-14 14:12:59 +080017623 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
developer72fb0bb2023-01-11 09:46:29 +080017624
developera3511852023-06-14 14:12:59 +080017625 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
17626 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080017627}
17628
17629static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
17630{
developera3511852023-06-14 14:12:59 +080017631 int err;
developer72fb0bb2023-01-11 09:46:29 +080017632
developera3511852023-06-14 14:12:59 +080017633 if (!ctrl->wpa)
17634 return -1;
17635 if (*reply_len < 2)
17636 return -1;
developer72fb0bb2023-01-11 09:46:29 +080017637
developera3511852023-06-14 14:12:59 +080017638 (*reply_len)--;
17639 ctrl->reply_len = sizeof(ctrl->reply);
17640 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
17641 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
17642 if (err < 0)
17643 return err;
developer72fb0bb2023-01-11 09:46:29 +080017644
developera3511852023-06-14 14:12:59 +080017645 if (ctrl->reply_len > *reply_len)
17646 ctrl->reply_len = *reply_len;
developer72fb0bb2023-01-11 09:46:29 +080017647
developera3511852023-06-14 14:12:59 +080017648 *reply_len = ctrl->reply_len;
17649 memcpy(reply, ctrl->reply, *reply_len);
17650 reply[*reply_len - 1] = 0;
17651 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
17652 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017653}
17654
17655static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
17656{
developera3511852023-06-14 14:12:59 +080017657 const char *pong = "PONG";
17658 const char *ping = "PING";
17659 char reply[1024];
17660 size_t len = sizeof(reply);
17661 int err;
17662 ULONG s, snum;
17663 INT ret;
17664 BOOL status;
developer72fb0bb2023-01-11 09:46:29 +080017665
developera3511852023-06-14 14:12:59 +080017666 printf("WPA_CTRL: watchdog cb\n");
developer72fb0bb2023-01-11 09:46:29 +080017667
developera3511852023-06-14 14:12:59 +080017668 ret = wifi_getSSIDNumberOfEntries(&snum);
17669 if (ret != RETURN_OK) {
17670 printf("%s: failed to get SSID count", __func__);
17671 return;
17672 }
developer72fb0bb2023-01-11 09:46:29 +080017673
developera3511852023-06-14 14:12:59 +080017674 if (snum > MAX_APS) {
17675 printf("more ssid than supported! %lu\n", snum);
17676 return;
17677 }
developer72fb0bb2023-01-11 09:46:29 +080017678
developera3511852023-06-14 14:12:59 +080017679 for (s = 0; s < snum; s++) {
17680 if (wifi_getApEnable(s, &status) != RETURN_OK) {
17681 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
17682 continue;
17683 }
17684 if (status == false) continue;
developer72fb0bb2023-01-11 09:46:29 +080017685
developera3511852023-06-14 14:12:59 +080017686 memset(reply, 0, sizeof(reply));
17687 len = sizeof(reply);
17688 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
17689 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
17690 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
17691 continue;
developer72fb0bb2023-01-11 09:46:29 +080017692
developera3511852023-06-14 14:12:59 +080017693 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
17694 ctrl_close(&wpa_ctrl[s]);
17695 printf("WPA_CTRL: ev_timer_again %lu\n", s);
17696 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
17697 }
developer72fb0bb2023-01-11 09:46:29 +080017698}
17699
17700static int init_wpa()
17701{
developer9ce44382023-06-28 11:09:37 +080017702 int ret = 0;
developera3511852023-06-14 14:12:59 +080017703 ULONG s, snum;
developer72fb0bb2023-01-11 09:46:29 +080017704
developera3511852023-06-14 14:12:59 +080017705 ret = wifi_getSSIDNumberOfEntries(&snum);
17706 if (ret != RETURN_OK) {
17707 printf("%s: failed to get SSID count", __func__);
17708 return RETURN_ERR;
17709 }
developer72fb0bb2023-01-11 09:46:29 +080017710
developera3511852023-06-14 14:12:59 +080017711 if (snum > MAX_APS) {
17712 printf("more ssid than supported! %lu\n", snum);
17713 return RETURN_ERR;
17714 }
developer72fb0bb2023-01-11 09:46:29 +080017715
developera3511852023-06-14 14:12:59 +080017716 for (s = 0; s < snum; s++) {
17717 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
developer32f2a182023-06-27 19:50:41 +080017718 ret = snprintf(wpa_ctrl[s].sockpath, sizeof(wpa_ctrl[s].sockpath), "%s%lu", SOCK_PREFIX, s);
17719 if (os_snprintf_error(sizeof(wpa_ctrl[s].sockpath), ret)) {
17720 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17721 return RETURN_ERR;
17722 }
developera3511852023-06-14 14:12:59 +080017723 wpa_ctrl[s].ssid_index = s;
17724 ctrl_enable(&wpa_ctrl[s]);
17725 }
developer72fb0bb2023-01-11 09:46:29 +080017726
developera3511852023-06-14 14:12:59 +080017727 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
17728 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
developer72fb0bb2023-01-11 09:46:29 +080017729
developera3511852023-06-14 14:12:59 +080017730 initialized = 1;
17731 printf("WPA_CTRL: initialized\n");
developer72fb0bb2023-01-11 09:46:29 +080017732
developera3511852023-06-14 14:12:59 +080017733 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017734}
17735
17736void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
17737{
developera3511852023-06-14 14:12:59 +080017738 clients_connect_cb = callback_proc;
17739 if (!initialized)
17740 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080017741}
17742
17743void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
17744{
developera3511852023-06-14 14:12:59 +080017745 clients_disconnect_cb = callback_proc;
17746 if (!initialized)
17747 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080017748}
17749
17750INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
17751{
developera3511852023-06-14 14:12:59 +080017752 // TODO Implement me!
17753 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017754}
17755
17756INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
17757{
developera3511852023-06-14 14:12:59 +080017758 // TODO Implement me!
17759 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017760}
17761
17762INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
17763{
developera3511852023-06-14 14:12:59 +080017764 int i;
17765 int phyId = -1;
17766 char cmd[256] = {0};
17767 char channel_numbers_buf[256] = {0};
17768 char dfs_state_buf[256] = {0};
17769 char line[256] = {0};
17770 const char *ptr;
17771 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +080017772 int res;
developer72fb0bb2023-01-11 09:46:29 +080017773
developera3511852023-06-14 14:12:59 +080017774 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080017775
developera3511852023-06-14 14:12:59 +080017776 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
17777 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080017778
developere40952c2023-06-15 18:46:43 +080017779 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\\|");
17780 if (os_snprintf_error(sizeof(cmd), res)) {
17781 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17782 return RETURN_ERR;
17783 }
developer72fb0bb2023-01-11 09:46:29 +080017784
developer8078acf2023-08-04 18:52:48 +080017785 if (_syscmd_secure(channel_numbers_buf, sizeof(channel_numbers_buf), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v '%sno IR\\|5340\\|5480' | awk '{print $4}' | tr -d '[]'", phyId, dfs_enable?"":"radar\\|") == RETURN_ERR) {
developera3511852023-06-14 14:12:59 +080017786 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
17787 return RETURN_ERR;
17788 }
developer72fb0bb2023-01-11 09:46:29 +080017789
developera3511852023-06-14 14:12:59 +080017790 ptr = channel_numbers_buf;
17791 i = 0;
17792 while ((ptr = get_line_from_str_buf(ptr, line))) {
17793 if (i >= outputMapSize) {
17794 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
17795 return RETURN_ERR;
17796 }
developerd14dff12023-06-28 22:47:44 +080017797 if (sscanf(line, "%d", &outputMap[i].ch_number) != 1) {
17798 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
17799 return RETURN_ERR;
17800 }
developerd1824452023-05-18 12:30:04 +080017801
developera3511852023-06-14 14:12:59 +080017802 memset(cmd, 0, sizeof(cmd));
17803 // Below command should fetch string for DFS state (usable, available or unavailable)
17804 // Example line: "DFS state: usable (for 78930 sec)"
17805 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) {
17806 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
17807 return RETURN_ERR;
17808 }
developer72fb0bb2023-01-11 09:46:29 +080017809
developera3511852023-06-14 14:12:59 +080017810 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
developer8078acf2023-08-04 18:52:48 +080017811 if (_syscmd_secure(dfs_state_buf, sizeof(dfs_state_buf),"iw list | grep -A 2 '\\[%d\\]' | tr -d '\\t' | grep 'DFS state' | awk '{print $3}' | tr -d '\\n'", outputMap[i].ch_number) == RETURN_ERR) {
developera3511852023-06-14 14:12:59 +080017812 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
17813 return RETURN_ERR;
17814 }
developer72fb0bb2023-01-11 09:46:29 +080017815
developera3511852023-06-14 14:12:59 +080017816 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080017817
developera3511852023-06-14 14:12:59 +080017818 if (!strcmp(dfs_state_buf, "usable")) {
17819 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
17820 } else if (!strcmp(dfs_state_buf, "available")) {
17821 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
17822 } else if (!strcmp(dfs_state_buf, "unavailable")) {
17823 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
17824 } else {
17825 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
17826 }
17827 i++;
17828 }
developer40ba1762023-05-13 11:03:49 +080017829
developera3511852023-06-14 14:12:59 +080017830 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +080017831
developera3511852023-06-14 14:12:59 +080017832 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
17833 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017834}
17835
17836INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
17837{
developera3511852023-06-14 14:12:59 +080017838 // TODO Implement me!
17839 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017840}
17841
17842INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
17843{
developer0155a502023-06-19 20:33:57 +080017844 int ret = -1;
17845 char inf_name[IF_NAME_SIZE] = {0};
17846 int if_idx = 0;
17847 struct unl unl_ins;
17848 struct nl_msg *msg = NULL;
17849 struct nlattr * msg_data = NULL;
17850 struct mtk_nl80211_param param;
17851 struct mtk_nl80211_cb_data cb_data;
17852 wdev_ap_metric ap_metric;
developerc3556192023-12-06 17:59:09 +080017853 int main_vap_idx;
developer0155a502023-06-19 20:33:57 +080017854
17855 /*init mtk nl80211 vendor cmd*/
17856
developerc3556192023-12-06 17:59:09 +080017857 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
17858 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
17859 return RETURN_ERR;
17860 }
17861
17862 if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
developer0155a502023-06-19 20:33:57 +080017863 return RETURN_ERR;
17864 if_idx = if_nametoindex(inf_name);
17865 if (!if_idx) {
17866 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
17867 return RETURN_ERR;
17868 }
17869
17870 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STATISTIC;
17871 param.if_type = NL80211_ATTR_IFINDEX;
17872 param.if_idx = if_idx;
17873
17874 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
17875 if (ret) {
17876 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
17877 return RETURN_ERR;
17878 }
17879
17880 /*add mtk vendor cmd data*/
17881
17882 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS, sizeof(wdev_ap_metric), (char *)&ap_metric)) {
17883 wifi_debug(DEBUG_ERROR, "Nla put GET_AP_METRICS attribute error\n");
17884 nlmsg_free(msg);
17885 goto err;
17886 }
17887
17888 /*send mtk nl80211 vendor msg*/
17889 cb_data.out_buf = (char *)output_percentage;
17890 cb_data.out_len = sizeof(wdev_ap_metric);
17891 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_metrics, &cb_data);
17892 if (ret) {
17893 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
17894 goto err;
17895 }
17896
17897 /*deinit mtk nl80211 vendor msg*/
17898 mtk_nl80211_deint(&unl_ins);
developer8461fe52023-11-07 16:11:44 +080017899 wifi_debug(DEBUG_INFO, "set cmd success.\n");
developer0155a502023-06-19 20:33:57 +080017900 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17901
developera3511852023-06-14 14:12:59 +080017902 return RETURN_OK;
developer0155a502023-06-19 20:33:57 +080017903err:
17904 mtk_nl80211_deint(&unl_ins);
17905 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
17906 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017907}
17908
developer0155a502023-06-19 20:33:57 +080017909
developer72fb0bb2023-01-11 09:46:29 +080017910INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
17911{
developerbbbafe32023-12-14 14:34:59 +080017912 unsigned char mac[ETH_ALEN] = {0};
developer6f35aa12023-11-13 14:52:39 +080017913
developerbbbafe32023-12-14 14:34:59 +080017914 if (hwaddr_aton2(mac_addr, mac) < 0) {
17915 wifi_debug(DEBUG_ERROR, "invalid device mac address %s\n", mac_addr);
developer6f35aa12023-11-13 14:52:39 +080017916 return RETURN_ERR;
17917 }
17918
developerbbbafe32023-12-14 14:34:59 +080017919 if (fill_dev3_statistics_by_mac(apIndex, dev_conn, (unsigned char *)mac)) {
17920 wifi_debug(DEBUG_ERROR, "fail to get dev3(%02x:%02x:%02x:%02x:%02x:%02x)"
17921 " statistic information from logan driver\n", mac[0],
17922 mac[1], mac[2], mac[3], mac[4], mac[5]);
17923 return RETURN_ERR;
17924 }
17925 memcpy(dev_conn->cli_MACAddress, mac, ETH_ALEN);
developer6f35aa12023-11-13 14:52:39 +080017926 dev_conn->cli_Active = 1;
17927 dev_conn->cli_AuthenticationState = 1;
17928
17929 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017930}
17931
17932INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
17933{
developera3511852023-06-14 14:12:59 +080017934 // TODO API refrence Implementaion is present on RPI hal
17935 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017936}
17937
17938INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
17939{
developera3511852023-06-14 14:12:59 +080017940 ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080017941
developera3511852023-06-14 14:12:59 +080017942 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17943 if(txpwr_pcntg == NULL)
developerdaf24792023-06-06 11:40:04 +080017944 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017945
developera1255e42023-05-13 17:45:02 +080017946 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
17947 *txpwr_pcntg = pwr_percentage;
developera3511852023-06-14 14:12:59 +080017948 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17949 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017950}
17951
17952INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
17953{
developera3511852023-06-14 14:12:59 +080017954 // TODO precac feature.
17955 struct params params[2] = {0};
17956 char config_file[128] = {0};
17957 BOOL dfs_enable = false;
17958 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080017959 int res;
developer72fb0bb2023-01-11 09:46:29 +080017960
developera3511852023-06-14 14:12:59 +080017961 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerdfd270b2023-12-12 10:24:30 +080017962 band = radio_index_to_band(radioIndex);
developera3511852023-06-14 14:12:59 +080017963 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080017964
developera3511852023-06-14 14:12:59 +080017965 if (dfs_enable == false) {
17966 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
17967 return RETURN_ERR;
17968 }
17969 params[0].name = "DfsZeroWaitDefault";
17970 params[0].value = enable?"1":"0";
17971 params[1].name = "DfsDedicatedZeroWait";
17972 params[1].value = enable?"1":"0";
developere40952c2023-06-15 18:46:43 +080017973 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
17974 if (os_snprintf_error(sizeof(config_file), res)) {
17975 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17976 return RETURN_ERR;
17977 }
developera3511852023-06-14 14:12:59 +080017978 wifi_datfileWrite(config_file, params, 2);
17979 wifi_reloadAp(radioIndex);
17980 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080017981
developera3511852023-06-14 14:12:59 +080017982 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17983 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017984}
17985
17986INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
17987{
developera3511852023-06-14 14:12:59 +080017988 char config_file[128] = {0};
17989 char buf1[32] = {0};
17990 char buf2[32] = {0};
17991 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080017992 int res;
developer72fb0bb2023-01-11 09:46:29 +080017993
developera3511852023-06-14 14:12:59 +080017994 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17995 if (NULL == enable || NULL == precac)
17996 return RETURN_ERR;
developerdfd270b2023-12-12 10:24:30 +080017997 band = radio_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080017998 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
17999 if (os_snprintf_error(sizeof(config_file), res)) {
18000 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18001 return RETURN_ERR;
18002 }
developera3511852023-06-14 14:12:59 +080018003 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
18004 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
18005 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
18006 *enable = true;
18007 else
18008 *enable = false;
developer72fb0bb2023-01-11 09:46:29 +080018009
developera3511852023-06-14 14:12:59 +080018010 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080018011
developera3511852023-06-14 14:12:59 +080018012 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18013 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018014}
18015
18016INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
18017{
developera3511852023-06-14 14:12:59 +080018018 *supported = TRUE;
18019 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018020}
18021
18022INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
18023{
developer863a4a62023-06-06 16:55:59 +080018024 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080018025 wifi_band band = band_invalid;
18026 char ofdmabuf[32] = {'\0'};
18027 char mimobuf[32] = {'\0'};
18028 char new_ofdmabuf[32] = {'\0'};
18029 char new_mimobuf[32] = {'\0'};
18030 struct params params[2];
developera1255e42023-05-13 17:45:02 +080018031 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
18032 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
18033 UCHAR bss_cnt = 0;
18034 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080018035 int res;
developer72fb0bb2023-01-11 09:46:29 +080018036
developera3511852023-06-14 14:12:59 +080018037 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +080018038 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
18039 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
18040 printf("%s:mu_type input Error", __func__);
18041 return RETURN_ERR;
18042 }
developerdfd270b2023-12-12 10:24:30 +080018043 band = radio_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080018044 if (band == band_invalid) {
18045 printf("%s:Band Error\n", __func__);
18046 return RETURN_ERR;
18047 }
developere40952c2023-06-15 18:46:43 +080018048 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
18049 if (os_snprintf_error(sizeof(dat_file), res)) {
18050 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18051 return RETURN_ERR;
18052 }
18053
developera1255e42023-05-13 17:45:02 +080018054 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080018055 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
18056 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080018057 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
18058 get_bssnum_byindex(radio_index, &bss_cnt);
18059 val_cnt = 2*bss_cnt - 1;
18060 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
18061 if ((val_cnt >= sizeof(new_ofdmabuf))
18062 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080018063 printf("%s:bss cnt Error", __func__);
developera1255e42023-05-13 17:45:02 +080018064 return RETURN_ERR;
18065 }
18066 /*translate set value*/
18067 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
18068 strncpy(new_ofdmabuf, str_zero, val_cnt);
18069 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080018070 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080018071 strncpy(new_ofdmabuf, str_one, val_cnt);
18072 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080018073 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080018074 strncpy(new_ofdmabuf, str_zero, val_cnt);
18075 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080018076 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
developera1255e42023-05-13 17:45:02 +080018077 strncpy(new_ofdmabuf, str_one, val_cnt);
18078 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080018079 }
developera1255e42023-05-13 17:45:02 +080018080 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
18081 /*same value, not operation*/
18082 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
18083 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
18084 printf("%s:Reduntant value\n", __func__);
18085 return RETURN_OK;
18086 }
18087 /*modify dat file to new file*/
18088 params[0].name="MuOfdmaDlEnable";
18089 params[0].value=new_ofdmabuf;
18090 params[1].name="MuMimoDlEnable";
18091 params[1].value=new_mimobuf;
18092 wifi_datfileWrite(dat_file, params, 2);
18093 /*hostapd control restarp ap to take effect on these new value*/
18094 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080018095 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18096 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018097}
18098
18099INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
18100{
developer5a333cf2023-06-06 18:18:50 +080018101 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080018102 wifi_band band = band_invalid;
18103 char ofdmabuf[32] = {'\0'};
18104 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080018105 char *token = NULL;
developerc14d83a2023-06-29 20:09:42 +080018106 long int ofdma = 0;
18107 long int mimo = 0;
developere40952c2023-06-15 18:46:43 +080018108 int res;
developer72fb0bb2023-01-11 09:46:29 +080018109
developera3511852023-06-14 14:12:59 +080018110 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018111
developera3511852023-06-14 14:12:59 +080018112 if (mu_type == NULL)
18113 return RETURN_ERR;
developerdfd270b2023-12-12 10:24:30 +080018114 band = radio_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080018115 if (band == band_invalid) {
18116 printf("%s:Band Error\n", __func__);
18117 return RETURN_ERR;
18118 }
developere40952c2023-06-15 18:46:43 +080018119 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
18120 if (os_snprintf_error(sizeof(dat_file), res)) {
18121 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18122 return RETURN_ERR;
18123 }
developera1255e42023-05-13 17:45:02 +080018124 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080018125 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
18126 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080018127
developera1255e42023-05-13 17:45:02 +080018128 token = strtok(ofdmabuf, ";");
developerd14dff12023-06-28 22:47:44 +080018129 if (token == NULL) {
18130 wifi_debug(DEBUG_ERROR, "strtok fail\n");
18131 return RETURN_ERR;
18132 }
developerc14d83a2023-06-29 20:09:42 +080018133 if (hal_strtol(token, 10, &ofdma) < 0) {
18134 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developerd14dff12023-06-28 22:47:44 +080018135 }
developerc14d83a2023-06-29 20:09:42 +080018136
developera1255e42023-05-13 17:45:02 +080018137 token = strtok(mimobuf, ";");
developer37646972023-06-29 10:58:43 +080018138 if (token == NULL) {
18139 wifi_debug(DEBUG_ERROR, "Unexpected strtok fail\n");
18140 return RETURN_ERR;
18141 }
developerc14d83a2023-06-29 20:09:42 +080018142
18143 if (hal_strtol(token, 10, &mimo) < 0) {
18144 wifi_debug(DEBUG_ERROR, "strtol fail\n");
developer37646972023-06-29 10:58:43 +080018145 }
developerc14d83a2023-06-29 20:09:42 +080018146
developer9f2358c2023-09-22 18:42:12 +080018147 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%ld,mimo=%ld\n", __func__, ofdma, mimo);
developera1255e42023-05-13 17:45:02 +080018148 if ((ofdma == 1) && (mimo == 1))
18149 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
18150 else if ((ofdma == 0) && (mimo == 1))
18151 *mu_type = WIFI_DL_MU_TYPE_MIMO;
18152 else if ((ofdma == 1) && (mimo == 0))
18153 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
18154 else
18155 *mu_type = WIFI_DL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080018156 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18157 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018158}
18159
18160INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
18161{
developera3511852023-06-14 14:12:59 +080018162 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developer863a4a62023-06-06 16:55:59 +080018163 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080018164 wifi_band band = band_invalid;
18165 char ofdmabuf[32] = {'\0'};
18166 char mimobuf[32] = {'\0'};
18167 char new_ofdmabuf[32] = {'\0'};
18168 char new_mimobuf[32] = {'\0'};
18169 struct params params[2];
developera1255e42023-05-13 17:45:02 +080018170 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
18171 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
18172 UCHAR bss_cnt = 0;
18173 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080018174 int res;
developer72fb0bb2023-01-11 09:46:29 +080018175
developera3511852023-06-14 14:12:59 +080018176 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerdfd270b2023-12-12 10:24:30 +080018177 band = radio_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080018178 if (band == band_invalid) {
18179 printf("%s:Band Error\n", __func__);
18180 return RETURN_ERR;
18181 }
18182 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
18183 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
18184 printf("%s:mu_type input Error\n", __func__);
18185 return RETURN_ERR;
18186 }
developere40952c2023-06-15 18:46:43 +080018187 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
18188 if (os_snprintf_error(sizeof(dat_file), res)) {
18189 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18190 return RETURN_ERR;
18191 }
developera1255e42023-05-13 17:45:02 +080018192 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080018193 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
18194 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080018195 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
18196 get_bssnum_byindex(radio_index, &bss_cnt);
18197 val_cnt = 2*bss_cnt - 1;
18198 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
18199 if ((val_cnt >= sizeof(new_ofdmabuf))
18200 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080018201 printf("%s:bss cnt Error\n", __func__);
developera1255e42023-05-13 17:45:02 +080018202 return RETURN_ERR;
18203 }
18204 /*translate set value*/
18205 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
18206 strncpy(new_ofdmabuf, str_zero, val_cnt);
18207 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080018208 }
developera1255e42023-05-13 17:45:02 +080018209 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
18210 strncpy(new_ofdmabuf, str_one, val_cnt);
18211 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080018212 }
developera1255e42023-05-13 17:45:02 +080018213 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
18214 /*same value, not operation*/
18215 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
18216 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
18217 printf("%s:Reduntant value\n", __func__);
18218 return RETURN_OK;
18219 }
18220 /*modify dat file to new file*/
18221 params[0].name="MuOfdmaUlEnable";
18222 params[0].value=new_ofdmabuf;
18223 params[1].name="MuMimoUlEnable";
18224 params[1].value=new_mimobuf;
18225 wifi_datfileWrite(dat_file, params, 2);
18226 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080018227 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18228 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018229}
18230
18231INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
18232{
developer863a4a62023-06-06 16:55:59 +080018233 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080018234 wifi_band band = band_invalid;
18235 char ofdmabuf[32] = {'\0'};
18236 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080018237 char *token = NULL;
18238 UCHAR ofdma = 0;
18239 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080018240 int res;
developerc14d83a2023-06-29 20:09:42 +080018241 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080018242
developera3511852023-06-14 14:12:59 +080018243 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018244
developera3511852023-06-14 14:12:59 +080018245 if (mu_type == NULL)
18246 return RETURN_ERR;
developerdfd270b2023-12-12 10:24:30 +080018247 band = radio_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080018248 if (band == band_invalid) {
18249 printf("%s:Band Error", __func__);
18250 return RETURN_ERR;
18251 }
developere40952c2023-06-15 18:46:43 +080018252 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
18253 if (os_snprintf_error(sizeof(dat_file), res)) {
18254 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18255 return RETURN_ERR;
18256 }
developera1255e42023-05-13 17:45:02 +080018257 /*get current value in dat file*/
18258 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
18259 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080018260
developera1255e42023-05-13 17:45:02 +080018261 token = strtok(ofdmabuf, ";");
developerd14dff12023-06-28 22:47:44 +080018262 if (token == NULL) {
18263 wifi_debug(DEBUG_ERROR, "strtok fail\n");
18264 return RETURN_ERR;
18265 }
developerc14d83a2023-06-29 20:09:42 +080018266
18267 if (hal_strtoul(token, 10, &tmp) < 0) {
18268 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerd14dff12023-06-28 22:47:44 +080018269 }
developerc14d83a2023-06-29 20:09:42 +080018270 ofdma = tmp;
developera1255e42023-05-13 17:45:02 +080018271 token = strtok(mimobuf, ";");
developer37646972023-06-29 10:58:43 +080018272 if (token == NULL) {
18273 wifi_debug(DEBUG_ERROR, "strtok fail\n");
18274 return RETURN_ERR;
18275 }
developer5b23cd02023-07-19 20:26:03 +080018276
developerc14d83a2023-06-29 20:09:42 +080018277 if (hal_strtoul(token, 10, &tmp) < 0) {
18278 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developer37646972023-06-29 10:58:43 +080018279 }
developerc14d83a2023-06-29 20:09:42 +080018280 mimo = tmp;
18281
developera1255e42023-05-13 17:45:02 +080018282 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
18283 if ((ofdma == 1) && (mimo == 0))
18284 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
18285 else
18286 *mu_type = WIFI_UL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080018287 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18288 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018289}
18290
18291
18292INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
18293{
developer8078acf2023-08-04 18:52:48 +080018294
developera3511852023-06-14 14:12:59 +080018295 char buf[256] = {0};
18296 char config_file[64] = {0};
18297 char GI[8] = {0};
18298 UINT mode_map = 0;
18299 FILE *f = NULL;
18300 wifi_band band = band_invalid;
18301 char dat_file[64] = {'\0'};
18302 struct params params[3];
developere40952c2023-06-15 18:46:43 +080018303 int res;
developer72fb0bb2023-01-11 09:46:29 +080018304
developera3511852023-06-14 14:12:59 +080018305 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018306
developera3511852023-06-14 14:12:59 +080018307 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
18308 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
18309 return RETURN_ERR;
18310 }
developera1255e42023-05-13 17:45:02 +080018311 /*sanity check*/
18312 if (((guard_interval == wifi_guard_interval_1600)
18313 || (guard_interval == wifi_guard_interval_3200))
developerdaf24792023-06-06 11:40:04 +080018314 && ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
developera3511852023-06-14 14:12:59 +080018315 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
18316 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080018317 }
developere40952c2023-06-15 18:46:43 +080018318 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
18319 if (os_snprintf_error(sizeof(config_file), res)) {
18320 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18321 return RETURN_ERR;
18322 }
developerdfd270b2023-12-12 10:24:30 +080018323 band = radio_index_to_band(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080018324
developera3511852023-06-14 14:12:59 +080018325 // Hostapd are not supported HE mode GI 1600, 3200 ns.
18326 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
developer8078acf2023-08-04 18:52:48 +080018327 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
18328 if (res) {
18329 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
18330
developere40952c2023-06-15 18:46:43 +080018331 }
developer8078acf2023-08-04 18:52:48 +080018332
developera3511852023-06-14 14:12:59 +080018333 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
18334 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
18335 if (strstr(buf, "[SHORT-GI-") == NULL) {
developer8078acf2023-08-04 18:52:48 +080018336 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
18337 if (res) {
18338 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
18339
developere40952c2023-06-15 18:46:43 +080018340 }
developer8078acf2023-08-04 18:52:48 +080018341
developera3511852023-06-14 14:12:59 +080018342 }
18343 if (band == band_5) {
18344 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
18345 if (strstr(buf, "[SHORT-GI-") == NULL) {
developer8078acf2023-08-04 18:52:48 +080018346 res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
18347 if (res) {
18348 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
18349
developere40952c2023-06-15 18:46:43 +080018350 }
developer8078acf2023-08-04 18:52:48 +080018351
developera3511852023-06-14 14:12:59 +080018352 }
18353 }
18354 }
18355 /*wifi_reloadAp(radio_index);
developera1255e42023-05-13 17:45:02 +080018356 caller "wifi_setRadioOperatingParameters" have done this step.
18357 */
developere40952c2023-06-15 18:46:43 +080018358 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
18359 if (os_snprintf_error(sizeof(dat_file), res)) {
18360 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18361 return RETURN_ERR;
18362 }
developera3511852023-06-14 14:12:59 +080018363 if (guard_interval == wifi_guard_interval_400) {
developera1255e42023-05-13 17:45:02 +080018364 params[0].name = "HT_GI";
18365 params[0].value = "1";
18366 params[1].name = "VHT_SGI";
18367 params[1].value = "1";
18368 wifi_datfileWrite(dat_file, params, 2);
developer32f2a182023-06-27 19:50:41 +080018369 memcpy(GI, "0.4", 3);
developera1255e42023-05-13 17:45:02 +080018370 } else {
18371 params[0].name = "HT_GI";
18372 params[0].value = "0";
18373 params[1].name = "VHT_SGI";
18374 params[1].value = "0";
18375 /*should enable FIXED_HE_GI_SUPPORT in driver*/
18376 params[2].name = "FgiFltf";
18377 if (guard_interval == wifi_guard_interval_800) {
18378 params[2].value = "800";
developer32f2a182023-06-27 19:50:41 +080018379 memcpy(GI, "0.8", 3);
developera1255e42023-05-13 17:45:02 +080018380 } else if (guard_interval == wifi_guard_interval_1600) {
18381 params[2].value = "1600";
developer32f2a182023-06-27 19:50:41 +080018382 memcpy(GI, "1.6", 3);
developera1255e42023-05-13 17:45:02 +080018383 } else if (guard_interval == wifi_guard_interval_3200) {
18384 params[2].value = "3200";
developer32f2a182023-06-27 19:50:41 +080018385 memcpy(GI, "3.2", 3);
developera1255e42023-05-13 17:45:02 +080018386 } else if (guard_interval == wifi_guard_interval_auto) {
18387 params[2].value = "0";
developer32f2a182023-06-27 19:50:41 +080018388 memcpy(GI, "auto", 4);
developera1255e42023-05-13 17:45:02 +080018389 }
18390 wifi_datfileWrite(dat_file, params, 3);
18391 }
developera3511852023-06-14 14:12:59 +080018392 // Record GI for get GI function
developere40952c2023-06-15 18:46:43 +080018393 res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
18394 if (os_snprintf_error(sizeof(buf), res)) {
18395 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18396 return RETURN_ERR;
18397 }
developera3511852023-06-14 14:12:59 +080018398 f = fopen(buf, "w");
18399 if (f == NULL)
18400 return RETURN_ERR;
18401 fprintf(f, "%s", GI);
developerc14d83a2023-06-29 20:09:42 +080018402 if (fclose(f) == EOF)
18403 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera3511852023-06-14 14:12:59 +080018404 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18405 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018406}
18407
18408INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
18409{
developera3511852023-06-14 14:12:59 +080018410 char buf[32] = {0};
developere40952c2023-06-15 18:46:43 +080018411 int res;
developer72fb0bb2023-01-11 09:46:29 +080018412
developera3511852023-06-14 14:12:59 +080018413 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018414
developera3511852023-06-14 14:12:59 +080018415 if (guard_interval == NULL)
18416 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018417
developer8078acf2023-08-04 18:52:48 +080018418 res = _syscmd_secure(buf, sizeof(buf), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
18419 if (res) {
18420 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080018421 }
developer72fb0bb2023-01-11 09:46:29 +080018422
developera3511852023-06-14 14:12:59 +080018423 if (strncmp(buf, "0.4", 3) == 0)
18424 *guard_interval = wifi_guard_interval_400;
18425 else if (strncmp(buf, "0.8", 3) == 0)
18426 *guard_interval = wifi_guard_interval_800;
18427 else if (strncmp(buf, "1.6", 3) == 0)
18428 *guard_interval = wifi_guard_interval_1600;
18429 else if (strncmp(buf, "3.2", 3) == 0)
18430 *guard_interval = wifi_guard_interval_3200;
18431 else
18432 *guard_interval = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +080018433
developera3511852023-06-14 14:12:59 +080018434 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18435 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018436}
18437
18438INT wifi_setBSSColor(INT radio_index, UCHAR color)
18439{
developera3511852023-06-14 14:12:59 +080018440 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
18441 struct params params = {0};
18442 char config_file[128] = {0};
18443 char bss_color[4] ={0};
developere40952c2023-06-15 18:46:43 +080018444 int res;
developer72fb0bb2023-01-11 09:46:29 +080018445
developera1255e42023-05-13 17:45:02 +080018446 if (color < 1 || color > 63) {
18447 wifi_dbg_printf("color value is err:%d.\n", color);
18448 return RETURN_ERR;
18449 }
developera3511852023-06-14 14:12:59 +080018450 params.name = "he_bss_color";
developere40952c2023-06-15 18:46:43 +080018451 res = snprintf(bss_color, sizeof(bss_color), "%hhu", color);
18452 if (os_snprintf_error(sizeof(bss_color), res)) {
18453 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18454 return RETURN_ERR;
18455 }
developera3511852023-06-14 14:12:59 +080018456 params.value = bss_color;
developer75bd10c2023-06-27 11:34:08 +080018457
18458 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
18459 if (os_snprintf_error(sizeof(config_file), res)) {
18460 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18461 return RETURN_ERR;
18462 }
developera3511852023-06-14 14:12:59 +080018463 wifi_hostapdWrite(config_file, &params, 1);
18464 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
developera1255e42023-05-13 17:45:02 +080018465 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080018466
developera3511852023-06-14 14:12:59 +080018467 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18468 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018469}
18470
18471INT wifi_getBSSColor(INT radio_index, UCHAR *color)
18472{
developera3511852023-06-14 14:12:59 +080018473 char config_file[128] = {0};
18474 char buf[64] = {0};
18475 char temp_output[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +080018476 int res;
developerc14d83a2023-06-29 20:09:42 +080018477 unsigned long tmp;
developer72fb0bb2023-01-11 09:46:29 +080018478
developera3511852023-06-14 14:12:59 +080018479 wifi_dbg_printf("\nFunc=%s\n", __func__);
18480 if (NULL == color)
18481 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018482
developer75bd10c2023-06-27 11:34:08 +080018483 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
18484 if (os_snprintf_error(sizeof(config_file), res)) {
18485 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18486 return RETURN_ERR;
18487 }
developera3511852023-06-14 14:12:59 +080018488 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080018489
developera3511852023-06-14 14:12:59 +080018490 if(strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +080018491 res = snprintf(temp_output, sizeof(temp_output), "%s", buf);
developera3511852023-06-14 14:12:59 +080018492 } else {
developere40952c2023-06-15 18:46:43 +080018493 res = snprintf(temp_output, sizeof(temp_output), "1"); // default value
18494 }
18495 if (os_snprintf_error(sizeof(temp_output), res)) {
18496 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18497 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080018498 }
developer72fb0bb2023-01-11 09:46:29 +080018499
developerc14d83a2023-06-29 20:09:42 +080018500 if (hal_strtoul(temp_output, 10, &tmp) < 0) {
18501 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerd14dff12023-06-28 22:47:44 +080018502 }
developerc14d83a2023-06-29 20:09:42 +080018503 *color = tmp;
developera3511852023-06-14 14:12:59 +080018504 wifi_dbg_printf("\noutput_string=%s\n", color);
developer72fb0bb2023-01-11 09:46:29 +080018505
developera3511852023-06-14 14:12:59 +080018506 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018507}
18508
18509/* multi-psk support */
18510INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
18511{
developera3511852023-06-14 14:12:59 +080018512 char cmd[256];
18513 char interface_name[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080018514 int res;
developer72fb0bb2023-01-11 09:46:29 +080018515
developera3511852023-06-14 14:12:59 +080018516 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
18517 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018518
developer75bd10c2023-06-27 11:34:08 +080018519 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 +080018520 interface_name,
18521 mac[0],
18522 mac[1],
18523 mac[2],
18524 mac[3],
18525 mac[4],
18526 mac[5]
18527 );
developer75bd10c2023-06-27 11:34:08 +080018528 if (os_snprintf_error(sizeof(cmd), res)) {
18529 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18530 return RETURN_ERR;
18531 }
developera3511852023-06-14 14:12:59 +080018532 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
developer8078acf2023-08-04 18:52:48 +080018533
18534 res = _syscmd_secure(key->wifi_keyId, 64, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",interface_name,mac[0],mac[1],mac[2], mac[3], mac[4], mac[5]);
18535 if(res) {
18536 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
18537 }
developer72fb0bb2023-01-11 09:46:29 +080018538
18539
developera3511852023-06-14 14:12:59 +080018540 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018541}
18542
18543INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
18544{
developera3511852023-06-14 14:12:59 +080018545 char interface_name[16] = {0};
18546 FILE *fd = NULL;
18547 char fname[100];
developer8078acf2023-08-04 18:52:48 +080018548
developera3511852023-06-14 14:12:59 +080018549 char out[64] = {0};
18550 wifi_key_multi_psk_t * key = NULL;
developer75bd10c2023-06-27 11:34:08 +080018551 int res, ret;
developere40952c2023-06-15 18:46:43 +080018552
developera3511852023-06-14 14:12:59 +080018553 if(keysNumber < 0)
18554 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018555
developere40952c2023-06-15 18:46:43 +080018556 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
18557 if (os_snprintf_error(sizeof(fname), res)) {
18558 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18559 return RETURN_ERR;
18560 }
developera3511852023-06-14 14:12:59 +080018561 fd = fopen(fname, "w");
18562 if (!fd) {
18563 return RETURN_ERR;
18564 }
18565 key= (wifi_key_multi_psk_t *) keys;
18566 for(int i=0; i<keysNumber; ++i, key++) {
developer75bd10c2023-06-27 11:34:08 +080018567 ret = fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
18568 if (ret < 0)
18569 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developera3511852023-06-14 14:12:59 +080018570 }
developerd14dff12023-06-28 22:47:44 +080018571 if (fclose(fd) != 0) {
18572 wifi_debug(DEBUG_ERROR, "fclose fail\n");
18573 return RETURN_ERR;
18574 }
developer72fb0bb2023-01-11 09:46:29 +080018575
developera3511852023-06-14 14:12:59 +080018576 //reload file
18577 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
18578 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080018579 res = _syscmd_secure(out, 64, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
developer32f2a182023-06-27 19:50:41 +080018580
developer8078acf2023-08-04 18:52:48 +080018581 if (res) {
18582 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
18583
developer32f2a182023-06-27 19:50:41 +080018584 }
developer8078acf2023-08-04 18:52:48 +080018585
developera3511852023-06-14 14:12:59 +080018586 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018587}
18588
18589INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
18590{
developera3511852023-06-14 14:12:59 +080018591 FILE *fd = NULL;
18592 char fname[100];
18593 char * line = NULL;
18594 char * pos = NULL;
18595 size_t len = 0;
18596 ssize_t read = 0;
18597 INT ret = RETURN_OK;
18598 wifi_key_multi_psk_t *keys_it = NULL;
developere40952c2023-06-15 18:46:43 +080018599 int res;
developer72fb0bb2023-01-11 09:46:29 +080018600
developera3511852023-06-14 14:12:59 +080018601 if (keysNumber < 1) {
18602 return RETURN_ERR;
18603 }
developer72fb0bb2023-01-11 09:46:29 +080018604
developere40952c2023-06-15 18:46:43 +080018605 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
18606 if (os_snprintf_error(sizeof(fname), res)) {
18607 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18608 return RETURN_ERR;
18609 }
developera3511852023-06-14 14:12:59 +080018610 fd = fopen(fname, "r");
18611 if (!fd) {
18612 return RETURN_ERR;
18613 }
developer72fb0bb2023-01-11 09:46:29 +080018614
developera3511852023-06-14 14:12:59 +080018615 if (keys == NULL) {
18616 ret = RETURN_ERR;
18617 goto close;
18618 }
developer72fb0bb2023-01-11 09:46:29 +080018619
developera3511852023-06-14 14:12:59 +080018620 keys_it = keys;
18621 while ((read = getline(&line, &len, fd)) != -1) {
18622 //Strip trailing new line if present
18623 if (read > 0 && line[read-1] == '\n') {
18624 line[read-1] = '\0';
18625 }
developer72fb0bb2023-01-11 09:46:29 +080018626
developera3511852023-06-14 14:12:59 +080018627 if(strcmp(line,"keyid=")) {
developer37646972023-06-29 10:58:43 +080018628 if (sscanf(line, "keyid=%63s", keys_it->wifi_keyId) == EOF)
18629 continue;
developera3511852023-06-14 14:12:59 +080018630 if (!(pos = index(line, ' '))) {
18631 ret = RETURN_ERR;
18632 goto close;
18633 }
18634 pos++;
18635 //Here should be 00:00:00:00:00:00
18636 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
18637 printf("Not supported MAC: %s\n", pos);
18638 }
18639 if (!(pos = index(pos, ' '))) {
18640 ret = RETURN_ERR;
18641 goto close;
18642 }
18643 pos++;
developer72fb0bb2023-01-11 09:46:29 +080018644
developera3511852023-06-14 14:12:59 +080018645 //The rest is PSK
developere40952c2023-06-15 18:46:43 +080018646 res = snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
18647 if (os_snprintf_error(sizeof(keys_it->wifi_psk), res)) {
18648 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developerc14d83a2023-06-29 20:09:42 +080018649 if (fclose(fd) == EOF)
18650 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developer5b23cd02023-07-19 20:26:03 +080018651
developere40952c2023-06-15 18:46:43 +080018652 return RETURN_ERR;
18653 }
18654
developera3511852023-06-14 14:12:59 +080018655 keys_it++;
developer72fb0bb2023-01-11 09:46:29 +080018656
developera3511852023-06-14 14:12:59 +080018657 if(--keysNumber <= 0)
developer72fb0bb2023-01-11 09:46:29 +080018658 break;
developera3511852023-06-14 14:12:59 +080018659 }
18660 }
developer72fb0bb2023-01-11 09:46:29 +080018661
18662close:
developera3511852023-06-14 14:12:59 +080018663 free(line);
developer37646972023-06-29 10:58:43 +080018664 if (fclose(fd) == EOF)
18665 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera3511852023-06-14 14:12:59 +080018666 return ret;
developer72fb0bb2023-01-11 09:46:29 +080018667}
18668/* end of multi-psk support */
18669
18670INT wifi_setNeighborReports(UINT apIndex,
developera3511852023-06-14 14:12:59 +080018671 UINT numNeighborReports,
18672 wifi_NeighborReport_t *neighborReports)
developer72fb0bb2023-01-11 09:46:29 +080018673{
developera3511852023-06-14 14:12:59 +080018674 char hex_bssid[13] = { 0 };
18675 char bssid[18] = { 0 };
18676 char nr[100] = { 0 };
developera19a38f2023-11-27 19:30:48 +080018677 char ssid[MAX_SSID_NAME_LEN];
18678 char hex_ssid[MAX_SSID_NAME_LEN];
developera3511852023-06-14 14:12:59 +080018679 char interface_name[16] = {0};
18680 INT ret;
developere40952c2023-06-15 18:46:43 +080018681 int res;
developerd14dff12023-06-28 22:47:44 +080018682 unsigned char hex_ssid_len;
developer72fb0bb2023-01-11 09:46:29 +080018683
developera3511852023-06-14 14:12:59 +080018684 /*rmeove all neighbors*/
18685 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
18686 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
18687 return RETURN_ERR;
developer33f13ba2023-07-12 16:19:06 +080018688
18689 res = v_secure_system("hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
developer32f2a182023-06-27 19:50:41 +080018690 interface_name, interface_name);
18691
developer33f13ba2023-07-12 16:19:06 +080018692 if (res) {
18693 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developer75bd10c2023-06-27 11:34:08 +080018694 return RETURN_ERR;
18695 }
developer72fb0bb2023-01-11 09:46:29 +080018696
developera3511852023-06-14 14:12:59 +080018697 for(unsigned int i = 0; i < numNeighborReports; i++)
18698 {
18699 memset(ssid, 0, sizeof(ssid));
18700 ret = wifi_getSSIDName(apIndex, ssid);
18701 if (ret != RETURN_OK)
18702 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018703
developera3511852023-06-14 14:12:59 +080018704 memset(hex_ssid, 0, sizeof(hex_ssid));
developerd14dff12023-06-28 22:47:44 +080018705 hex_ssid_len = sizeof(hex_ssid);
18706 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 ) {
18707 res = snprintf(hex_ssid + k, hex_ssid_len, "%02x", ssid[j]);
18708
18709 if (os_snprintf_error(hex_ssid_len, res)) {
18710 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18711 return RETURN_ERR;
18712 }
18713 hex_ssid_len = sizeof(hex_ssid) - strlen(hex_ssid);
18714 }
developer72fb0bb2023-01-11 09:46:29 +080018715
developere40952c2023-06-15 18:46:43 +080018716 res = snprintf(hex_bssid, sizeof(hex_bssid),
developera3511852023-06-14 14:12:59 +080018717 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
18718 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 +080018719 if (os_snprintf_error(sizeof(hex_bssid), res)) {
18720 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18721 return RETURN_ERR;
18722 }
18723 res = snprintf(bssid, sizeof(bssid),
developera3511852023-06-14 14:12:59 +080018724 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
18725 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 +080018726 if (os_snprintf_error(sizeof(bssid), res)) {
18727 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18728 return RETURN_ERR;
18729 }
developer72fb0bb2023-01-11 09:46:29 +080018730
developere40952c2023-06-15 18:46:43 +080018731 res = snprintf(nr, sizeof(nr),
developera3511852023-06-14 14:12:59 +080018732 "%s" // bssid
18733 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
18734 "%02hhx" // operclass
18735 "%02hhx" // channel
18736 "%02hhx", // phy_mode
18737 hex_bssid,
18738 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
18739 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
18740 neighborReports[i].opClass,
18741 neighborReports[i].channel,
18742 neighborReports[i].phyTable);
developere40952c2023-06-15 18:46:43 +080018743 if (os_snprintf_error(sizeof(nr), res)) {
18744 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18745 return RETURN_ERR;
18746 }
developer72fb0bb2023-01-11 09:46:29 +080018747
developer33f13ba2023-07-12 16:19:06 +080018748 res = v_secure_system("hostapd_cli set_neighbor %s ssid=%s nr=%s -i %s",
18749 bssid, hex_ssid, nr, interface_name);
18750 if (res) {
18751 wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
developere40952c2023-06-15 18:46:43 +080018752 return RETURN_ERR;
18753 }
developera3511852023-06-14 14:12:59 +080018754 }
developer72fb0bb2023-01-11 09:46:29 +080018755
developera3511852023-06-14 14:12:59 +080018756 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018757}
18758
18759INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
18760{
developera3511852023-06-14 14:12:59 +080018761 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018762}
18763
developer8461fe52023-11-07 16:11:44 +080018764INT mtk_wifi_set_get_mru_info(
18765 INT radioIndex, INT vendor_data_attr, char data, mtk_nl80211_cb call_back, void *output)
18766{
18767 int ret = -1;
18768 struct unl unl_ins;
18769 struct nl_msg *msg = NULL;
18770 struct nlattr * msg_data = NULL;
18771 struct mtk_nl80211_param param;
18772
18773 /*init mtk nl80211 vendor cmd*/
18774 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_RADIO;
18775 param.if_type = NL80211_ATTR_WIPHY;
18776 param.if_idx = radio_index_to_phy(radioIndex);
18777
18778 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
18779 if (ret) {
18780 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
18781 return RETURN_ERR;
18782 }
18783 /*add mtk vendor cmd data*/
18784 if (nla_put_u8(msg, vendor_data_attr, data)) {
18785 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
18786 nlmsg_free(msg);
18787 goto err;
18788 }
18789
18790 /*send mtk nl80211 vendor msg*/
18791 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
18792 if (ret) {
18793 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
18794 goto err;
18795 }
18796 /*deinit mtk nl80211 vendor msg*/
18797 mtk_nl80211_deint(&unl_ins);
18798 wifi_debug(DEBUG_INFO, "send cmd success.\n");
18799
18800 return RETURN_OK;
18801err:
18802 mtk_nl80211_deint(&unl_ins);
18803 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
18804 return RETURN_ERR;
18805}
18806
18807int get_mru_info_handler(struct nl_msg *msg, void *data)
18808{
18809 struct nlattr *tb[NL80211_ATTR_MAX + 1];
18810 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_RADIO_ATTR_MAX + 1];
18811 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
18812 unsigned char *enable = (unsigned char *)data;
18813 int err = 0;
18814
18815 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
18816 genlmsg_attrlen(gnlh, 0), NULL);
18817 if (err < 0)
18818 return err;
18819
18820 if (tb[NL80211_ATTR_VENDOR_DATA]) {
18821 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_RADIO_ATTR_MAX,
18822 tb[NL80211_ATTR_VENDOR_DATA], NULL);
18823 if (err < 0)
18824 return err;
18825
18826 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO]) {
18827 *enable = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO]);
18828 }
18829 }
18830
18831 return 0;
18832}
18833
18834INT wifi_setRadioMRUEnable(INT radioIndex, BOOL Enable)
18835{
18836 struct params dat_param = {0};
18837 char dat_file[MAX_BUF_SIZE] = {0};
18838 int res;
18839
18840 if (mtk_wifi_set_get_mru_info(radioIndex, MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO, Enable,
18841 NULL, NULL)!= RETURN_OK) {
18842 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO cmd fails\n");
18843 return RETURN_ERR;
18844 }
18845
18846 dat_param.name = "PPEnable";
18847 dat_param.value = Enable ? "1" : "0";
18848
18849 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
18850 if (os_snprintf_error(sizeof(dat_file), res)) {
18851 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18852 return RETURN_ERR;
18853 }
18854
18855 wifi_datfileWrite(dat_file, &dat_param, 1);
18856
18857 return RETURN_OK;
18858}
18859
18860INT wifi_getRadioMRUEnable(INT radioIndex, BOOL *output)
18861{
18862 BOOL enable;
18863
18864 if (mtk_wifi_set_get_mru_info(radioIndex, MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO, 0xf,
18865 get_mru_info_handler, &enable)!= RETURN_OK) {
18866 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO cmd fails\n");
18867 return RETURN_ERR;
18868 }
18869
18870 *output = enable;
18871
18872 return RETURN_OK;
18873}
developerda25c112023-11-21 15:35:26 +080018874INT wifi_getApWpsLastConnectionStatus(INT apIndex, CHAR *output_string);
developer8461fe52023-11-07 16:11:44 +080018875
developer72fb0bb2023-01-11 09:46:29 +080018876#ifdef _WIFI_HAL_TEST_
18877int main(int argc,char **argv)
18878{
developera3511852023-06-14 14:12:59 +080018879 int index;
18880 INT ret=0;
18881 char buf[1024]="";
developerc3556192023-12-06 17:59:09 +080018882 wifi_ParseProfile();
developera3511852023-06-14 14:12:59 +080018883 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
18884 if(argc<3)
18885 {
18886 if(argc==2)
18887 {
18888 if(!strcmp(argv[1], "init"))
18889 return wifi_init();
18890 if(!strcmp(argv[1], "reset"))
18891 return wifi_reset();
18892 if(!strcmp(argv[1], "wifi_getHalVersion"))
18893 {
18894 char buffer[64];
18895 if(wifi_getHalVersion(buffer)==RETURN_OK)
18896 printf("Version: %s\n", buffer);
18897 else
18898 printf("Error in wifi_getHalVersion\n");
18899 return RETURN_OK;
18900 }
18901 }
18902 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
18903 exit(-1);
18904 }
developer72fb0bb2023-01-11 09:46:29 +080018905
developera3511852023-06-14 14:12:59 +080018906 index = atoi(argv[2]);
developer33f13ba2023-07-12 16:19:06 +080018907 if (strstr(argv[1], "test_system")!=NULL) {
18908 ret = v_secure_system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
18909 printf("ret = %d\n", ret);
18910
18911 ret = v_secure_system("hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
18912 "ra0", "ra0");
18913 printf("ret = %d\n", ret);
18914
18915 ret = v_secure_system("echo %s > /var/prevchanval2G_AutoChannelEnable", "1,2,3");
18916 printf("ret = %d\n", ret);
18917
18918 ret = v_secure_system("ifconfig -a %s > /tmp/Radio_Stats.txt", "rai0");
18919 printf("ret = %d\n", ret);
18920
18921 ret = v_secure_system("ifconfig %s > /tmp/SSID_Stats.txt", "rax0");
18922 printf("ret = %d\n", ret);
18923
18924 ret = v_secure_system("iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", "ra0");
18925 printf("ret = %d\n", ret);
18926 ret = v_secure_system("iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", "ra0");
18927 printf("ret = %d\n", ret);
18928 ret = v_secure_system("ping -q -c 1 -W 1 \"%s\" > /dev/console 2>&1", "20.1.1.101");
18929 printf("ret = %d\n", ret);
18930
18931 return 0;
18932 }
18933
18934 if (strstr(argv[1], "test_popen")!=NULL) {
18935 FILE *fp = v_secure_popen("w", "cat");
18936 fprintf(fp, "popen write success\n");
18937 fclose(fp);
18938
18939 char buf[1024];
18940 memset(buf, 0, sizeof(buf));
18941 fp = v_secure_popen("r", "echo popen read success");
18942 if (fp == NULL) {
18943 printf("v_secure_popen failed\n");
18944 } else {
18945 if (fgets(buf, sizeof(buf), fp) == NULL) {
18946 printf("v_secure_popen read error\n");
18947 } else {
18948 printf("%s\n", buf);
18949 }
18950 v_secure_pclose(fp);
18951 }
18952
18953#if 0
18954 fp = v_secure_popen("r", "hostapd_cli -i %s reload", "ra0");
18955 if (fp == NULL) {
18956 printf("v_secure_popen failed\n");
18957 } else {
18958 if (fgets(buf, sizeof(buf), fp) == NULL) {
18959 printf("v_secure_popen read error\n");
18960 } else {
18961 printf("%s", buf);
18962 }
18963 v_secure_pclose(fp);
18964 }
18965#endif
18966
18967 long int band;
18968 memset(buf, 0, sizeof(buf));
18969 ret = _syscmd_secure(buf, sizeof(buf),
18970 "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", 0);
18971 if (hal_strtol(buf, 16, &band) < 0) {
18972 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18973 }
18974 printf("ret = %d, band0=%ld\n", ret, band);
18975
18976 memset(buf, 0, sizeof(buf));
18977 ret = _syscmd_secure(buf, sizeof(buf),
18978 "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", 1);
18979 if (hal_strtol(buf, 16, &band) < 0) {
18980 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18981 }
18982 printf("ret = %d, band1=%ld\n", ret, band);
18983
18984 memset(buf, 0, sizeof(buf));
18985 ret = _syscmd_secure(buf, sizeof(buf),
18986 "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", 2);
18987 if (hal_strtol(buf, 16, &band) < 0) {
18988 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18989 }
18990 printf("ret = %d, band2=%ld\n", ret, band);
18991 }
18992
developera3511852023-06-14 14:12:59 +080018993 if(strstr(argv[1], "wifi_getApName")!=NULL)
18994 {
18995 wifi_getApName(index,buf);
18996 printf("Ap name is %s \n",buf);
18997 return 0;
18998 }
developerb14b3462023-07-01 18:02:42 +080018999 if(strstr(argv[1], "wifi_getRadioExtChannel")!=NULL)
19000 {
19001 wifi_getRadioExtChannel(index,buf);
19002 printf("extchannel is %s \n",buf);
19003 return 0;
19004 }
developerda25c112023-11-21 15:35:26 +080019005
19006 if(strstr(argv[1], "wifi_getApWpsLastConnectionStatus")!=NULL) {
19007 char buf[32] = {0};
19008 int res;
19009
19010 res = wifi_getApWpsLastConnectionStatus(index, buf);
19011 if (res == RETURN_OK)
19012 printf("ap_index=%d, wifi_getApWpsLastConnectionStatus=%s\n", index, buf);
19013 else
19014 printf("fail to get AP wps last connection status for ap_index=%d\n", index);
19015 }
developerb340de62023-11-22 20:10:05 +080019016
developer5fb72242023-11-23 15:48:16 +080019017#ifndef WIFI_7992
19018 /*it is only suitable for eagle*/
developerb340de62023-11-22 20:10:05 +080019019 if (strstr(argv[1], "mlo_test")) {
19020 wifi_vap_info_map_t vap[3];
19021 int i;
19022 unsigned char mld_mac[6] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
19023 unsigned char mld_mac2[6] = {0x00, 0x0c, 0x43, 0x44, 0x55, 0x66};
19024 radio_band[0] = band_2_4;
19025 radio_band[1] = band_5;
19026 radio_band[2] = band_6;
19027
19028 if (eht_mld_config_init() != RETURN_OK)
19029 printf("eht_mld_config_init() fail!\n");
19030
19031 memset(vap, 0, sizeof(vap));
19032 for (i = 0; i < 3; i++) {
19033 if (wifi_getRadioVapInfoMap(i, &vap[i]) != RETURN_OK)
19034 printf("wifi_getRadioVapInfoMap fail[%d]", i);
19035 }
19036
19037 /*case 1-create mld[5], transfer ra0 mld[1]->mld[5]*/
19038 vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_enable = 1;
19039 vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_index = 5;
19040 memcpy(vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac, 6);
19041
19042 /*case 2-create mld[6], transfer ra1 mld[2]->mld[6]*/
19043 vap[0].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 1;
19044 vap[0].vap_array[1].u.bss_info.mld_info.common_info.mld_index = 6;
19045 memcpy(vap[0].vap_array[1].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
19046 if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
19047 printf("wifi_createVAP[0] fail\n");
19048
19049 /*case 3-rai0 keep in mld[1]*/
19050 vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_enable = 1;
19051 vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_index = 1;
19052 memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac, 6);
19053
19054 /*case 4-rai1 leave mld[2]*/
19055 vap[1].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 0;
19056 vap[1].vap_array[1].u.bss_info.mld_info.common_info.mld_index = 2;
19057 memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
19058
19059 if (wifi_createVAP(1, &vap[1]) != RETURN_OK)
19060 printf("wifi_createVAP[0] fail\n");
19061
19062 /*case 5-rax1 leave mld[2]->null*/
19063 vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 0;
19064 vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_index = 2;
19065 memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
19066
19067 if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
19068 printf("wifi_createVAP[0] fail\n");
19069
19070 /*case 6-rax1 null->join mld[7]*/
19071 vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 1;
19072 vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_index = 7;
19073 memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
19074
19075 if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
19076 printf("wifi_createVAP[0] fail\n");
19077
19078 /*case 7-ra0 leve mld[5]->null, mld[5] destroy*/
19079 vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_enable = 0;
19080 vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_index = 5;
19081 memcpy(vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac, 6);
19082 if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
19083 printf("wifi_createVAP[0] fail\n");
19084
19085 mld_info_display();
19086 }
developerac5919a2023-12-04 18:18:54 +080019087
19088 if (strstr(argv[1], "change_bridge_test")) {
19089 wifi_vap_info_map_t vap[3];
19090 int i;
19091 radio_band[0] = band_2_4;
19092 radio_band[1] = band_5;
19093 radio_band[2] = band_6;
19094
19095 if (eht_mld_config_init() != RETURN_OK)
19096 printf("eht_mld_config_init() fail!\n");
19097
19098 memset(vap, 0, sizeof(vap));
19099 for (i = 0; i < 3; i++) {
19100 if (wifi_getRadioVapInfoMap(i, &vap[i]) != RETURN_OK)
19101 printf("wifi_getRadioVapInfoMap fail[%d]", i);
19102 }
19103
19104 /*case 1-change bridge name of ra0*/
19105 strncpy(vap[0].vap_array[0].bridge_name, "brlan1", sizeof(vap[0].vap_array[0].bridge_name));
19106 if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
19107 printf("wifi_createVAP[0] fail\n");
19108
19109 /*case 2-change bridge name of rai1*/
19110 strncpy(vap[1].vap_array[1].bridge_name, "brlan2", sizeof(vap[1].vap_array[1].bridge_name));
19111 if (wifi_createVAP(1, &vap[1]) != RETURN_OK)
19112 printf("wifi_createVAP[1] fail\n");
19113
19114 /*case 2-change bridge name of rax0*/
19115 strncpy(vap[2].vap_array[0].bridge_name, "brlan3", sizeof(vap[2].vap_array[2].bridge_name));
19116 if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
19117 printf("wifi_createVAP[2] fail\n");
19118 }
developer9635f402023-12-25 19:48:21 +080019119
19120 if (strstr(argv[1], "dynamic_vap_test")) {
19121 wifi_vap_info_map_t vap[3];
19122 int i;
19123 radio_band[0] = band_2_4;
19124 radio_band[1] = band_5;
19125 radio_band[2] = band_6;
19126
19127 if (eht_mld_config_init() != RETURN_OK)
19128 printf("eht_mld_config_init() fail!\n");
19129
19130 memset(vap, 0, sizeof(vap));
19131 for (i = 0; i < 3; i++) {
19132 if (wifi_getRadioVapInfoMap(i, &vap[i]) != RETURN_OK)
19133 printf("wifi_getRadioVapInfoMap fail[%d]", i);
19134 }
19135
19136 /*case 1-enable vap[4/6/8/10/12/14] ra2/ra3/ra4/ra5/ra6/ra7*/
19137 for (i = 2; i < 8; i++)
19138 vap[0].vap_array[i].u.bss_info.enabled = 1;
19139 if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
19140 printf("wifi_createVAP[0] fail\n");
19141
19142 /*case 2-disable vap[1/3] rai0/rai1*/
19143 for (i = 0; i < 2; i++)
19144 vap[1].vap_array[i].u.bss_info.enabled = 0;
19145 if (wifi_createVAP(1, &vap[1]) != RETURN_OK)
19146 printf("wifi_createVAP[0] fail\n");
19147
19148 /*case 3-disable vap[16/17] rax0/rax1, enable vap[18/19/20/21/22/23] rax2,rax3,rax4,rax5,rax6,rax7*/
19149 for (i = 0; i < 2; i++)
19150 vap[2].vap_array[i].u.bss_info.enabled = 0;
19151 if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
19152 printf("wifi_createVAP[0] fail\n");
19153
19154 for (i = 2; i < 8; i++)
19155 vap[2].vap_array[i].u.bss_info.enabled = 1;
19156 if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
19157 printf("wifi_createVAP[0] fail\n");
19158 }
developer5fb72242023-11-23 15:48:16 +080019159#endif
19160
developer6f35aa12023-11-13 14:52:39 +080019161 if(strstr(argv[1], "wifi_getApAssociatedDeviceDiagnosticResult3")!=NULL)
19162 {
19163 wifi_associated_dev3_t *associated_dev_array = NULL, *dev3;
19164 INT sta_count, i, j;
19165 wifi_getApAssociatedDeviceDiagnosticResult3(index, &associated_dev_array, (unsigned int *)(&sta_count));
19166 printf("wifi_getApAssociatedDeviceDiagnosticResult3\n");
19167 if (associated_dev_array == NULL) {
19168 printf("wifi_getApAssociatedDeviceDiagnosticResult3 fail\n");
19169 return 0;
19170 }
19171 for (i = 0; i < sta_count; i++) {
19172 dev3 = (wifi_associated_dev3_t *)(associated_dev_array + i);
19173 printf("mac(%02x:%02x:%02x:%02x:%02x:%02x:)\n", dev3->cli_MACAddress[0], dev3->cli_MACAddress[1],
19174 dev3->cli_MACAddress[2], dev3->cli_MACAddress[3], dev3->cli_MACAddress[4], dev3->cli_MACAddress[5]);
developerb340de62023-11-22 20:10:05 +080019175 printf("\t tx_rate=%u, rx_rate=%u, snr=%u, rx_bytes=%lu, tx_bytes=%lu, rssi=%hhd, tx_pkts=%lu, rx_pkts=%lu\n"
developer6f35aa12023-11-13 14:52:39 +080019176 "mlo_enable=%u\n", dev3->cli_LastDataUplinkRate , dev3->cli_LastDataDownlinkRate,
19177 dev3->cli_SNR, dev3->cli_BytesReceived, dev3->cli_BytesSent, dev3->cli_RSSI, dev3->cli_PacketsReceived,
19178 dev3->cli_BytesSent, dev3->mld_enable);
19179
19180 if (dev3->mld_enable) {
19181 printf("\tmld mac(%02x:%02x:%02x:%02x:%02x:%02x:)\n", dev3->mld_addr[0], dev3->mld_addr[1],
19182 dev3->mld_addr[2], dev3->mld_addr[3], dev3->mld_addr[4], dev3->mld_addr[5]);
19183
19184 for (j = 0; j < 3; j++) {
19185 if (!dev3->mld_link_info[j].valid)
19186 continue;
19187 printf("\tlink mac(%02x:%02x:%02x:%02x:%02x:%02x:)\n", dev3->mld_link_info[j].link_addr[0],
19188 dev3->mld_link_info[j].link_addr[1],
19189 dev3->mld_link_info[j].link_addr[2], dev3->mld_link_info[j].link_addr[3], dev3->mld_link_info[j].link_addr[4],
19190 dev3->mld_link_info[j].link_addr[5]);
developerb340de62023-11-22 20:10:05 +080019191 printf("\trssi=%hhd, tx_rate=%lu, rx_rate=%lu, tx_bytes=%llu, rx_bytes=%llu\n",
developer6f35aa12023-11-13 14:52:39 +080019192 dev3->mld_link_info[j].rssi, dev3->mld_link_info[j].tx_rate, dev3->mld_link_info[j].rx_rate,
19193 dev3->mld_link_info[j].tx_bytes, dev3->mld_link_info[j].rx_bytes);
19194 }
19195
19196 }
19197 }
19198 return 0;
19199 }
developer37ad6bf2023-10-09 11:31:05 +080019200 if (strstr(argv[1], "wifi_setRadioAMSDUEnable")!=NULL) {
19201 unsigned char enable = atoi(argv[3]);
19202 BOOL out_put;
19203 if (enable)
19204 wifi_setRadioAMSDUEnable(index, TRUE);
19205 else
19206 wifi_setRadioAMSDUEnable(index, FALSE);
19207 wifi_getRadioAMSDUEnable(index, &out_put);
19208 printf("amsdu = %d\n", out_put);
19209 }
19210 if (strstr(argv[1], "wifi_setApIsolationEnable")!=NULL) {
19211 unsigned char enable = atoi(argv[3]);
19212 BOOL out_put;
19213 if (enable)
19214 wifi_setApIsolationEnable(index, TRUE);
19215 else
19216 wifi_setApIsolationEnable(index, FALSE);
19217 wifi_getApIsolationEnable(index, &out_put);
19218 printf("isolation input=%d, output=%d\n", enable, out_put);
19219 }
developerfead3972023-05-25 20:15:02 +080019220 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080019221 {
developer2a6abc92023-10-17 17:19:14 +080019222 UINT pureMode;
19223 if(argc <= 3)
19224 {
19225 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19226 exit(-1);
19227 }
developerfead3972023-05-25 20:15:02 +080019228
developer2a6abc92023-10-17 17:19:14 +080019229 pureMode = atoi(argv[3]);
developera3511852023-06-14 14:12:59 +080019230 wifi_setRadioMode(index, NULL, pureMode);
19231 printf("Ap SET Radio mode 0x%x\n", pureMode);
19232 return 0;
19233 }
19234 if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
developer2a6abc92023-10-17 17:19:14 +080019235 unsigned char enable;
19236 if(argc <= 3)
19237 {
19238 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19239 exit(-1);
19240 }
19241 enable = atoi(argv[3]);
developera3511852023-06-14 14:12:59 +080019242 if (enable)
19243 wifi_setRadioAutoBlockAckEnable(index, TRUE);
19244 else
19245 wifi_setRadioAutoBlockAckEnable(index, FALSE);
19246 printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
19247 }
developera39cfb22023-06-20 16:28:17 +080019248 if(strstr(argv[1], "wifi_setRadioTrafficStatsRadioStatisticsEnable")!=NULL)
19249 {
19250 wifi_setRadioTrafficStatsRadioStatisticsEnable(index, TRUE);
19251 printf("Ap SET wifi_setRadioTrafficStatsRadioStatisticsEnable\n");
19252 return 0;
19253 }
19254 if(strstr(argv[1], "wifi_setRadioTrafficStatsMeasure")!=NULL)
19255 {
19256 wifi_radioTrafficStatsMeasure_t input = {30, 200};
19257
19258 wifi_setRadioTrafficStatsMeasure(index, &input);
19259 printf("Ap SET wifi_setRadioTrafficStatsMeasure\n");
19260 return 0;
19261 }
developerfead3972023-05-25 20:15:02 +080019262 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
developera3511852023-06-14 14:12:59 +080019263 {
developer2a6abc92023-10-17 17:19:14 +080019264 ULONG TransmitPower;
19265 if(argc <= 3)
19266 {
19267 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19268 exit(-1);
19269 }
19270 TransmitPower = atoi(argv[3]);
developera3511852023-06-14 14:12:59 +080019271 wifi_setRadioTransmitPower(index, TransmitPower);
19272 printf("Ap SET TransmitPower %lu\n", TransmitPower);
19273 return 0;
19274 }
developerfead3972023-05-25 20:15:02 +080019275 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
developera3511852023-06-14 14:12:59 +080019276 {
developer2a6abc92023-10-17 17:19:14 +080019277 INT TransmitPower;
19278 if(argc <= 3)
19279 {
19280 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19281 exit(-1);
19282 }
19283 TransmitPower = atoi(argv[3]);
developera3511852023-06-14 14:12:59 +080019284 wifi_setApManagementFramePowerControl(index, TransmitPower);
19285 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
19286 return 0;
19287 }
developereef7d562023-10-21 16:04:21 +080019288 if(strstr(argv[1], "wifi_setRadioBW") != NULL)
developera3511852023-06-14 14:12:59 +080019289 {
developer2a6abc92023-10-17 17:19:14 +080019290 if(argc <= 3)
19291 {
19292 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19293 exit(-1);
19294 }
developerfead3972023-05-25 20:15:02 +080019295
developer2a6abc92023-10-17 17:19:14 +080019296 wifi_setRadioOperatingChannelBandwidth(index, argv[3]);
19297 printf("Ap SET bw %s\n", argv[3]);
developera3511852023-06-14 14:12:59 +080019298 return 0;
19299 }
developereef7d562023-10-21 16:04:21 +080019300
19301 if(strstr(argv[1], "wifi_setChannel") != NULL)
19302 {
19303 UINT channel;
19304 if(argc <= 3)
19305 {
19306 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19307 exit(-1);
19308 }
19309 channel = atoi(argv[3]);
19310
19311 wifi_setRadioChannel(index, channel);
19312 printf("Ap SET channel %d\n", channel);
19313 return 0;
19314 }
19315
19316 if(strstr(argv[1], "wifi_setExtCh") != NULL)
19317 {
19318 if(argc <= 3)
19319 {
19320 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19321 exit(-1);
19322 }
19323
19324 wifi_setRadioExtChannel(index, argv[3]);
19325 printf("Ap SET ExtChannel %s\n", argv[3]);
19326 return 0;
19327 }
19328
19329 if(strstr(argv[1], "wifi_setHtCoex") != NULL)
19330 {
19331 UINT ht_coex;
19332 BOOL enable = FALSE;
19333 if(argc <= 3)
19334 {
19335 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19336 exit(-1);
19337 }
19338 ht_coex = atoi(argv[3]);
19339
19340 if (ht_coex == 1)
19341 enable = TRUE;
19342 wifi_setRadioObssCoexistenceEnable(index, enable);
19343 printf("Ap SET ht_coex %d\n", enable);
19344 return 0;
19345 }
19346
19347 if(strstr(argv[1], "wifi_setChMode") != NULL)
19348 {
19349 if(argc <= 3)
19350 {
19351 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19352 exit(-1);
19353 }
19354
19355 wifi_setRadioChannelMode(index, argv[3], FALSE, FALSE, FALSE);
19356 printf("Ap SET ChannelMode %s\n", argv[3]);
19357 return 0;
19358 }
19359
19360 if(strstr(argv[1], "wifi_set80211h") != NULL)
19361 {
19362 UINT en_11h;
19363 BOOL enable = FALSE;
19364 if(argc <= 3)
19365 {
19366 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19367 exit(-1);
19368 }
19369 en_11h = atoi(argv[3]);
19370
19371 if (en_11h == 1)
19372 enable = TRUE;
19373 wifi_setRadioIEEE80211hEnabled(index, enable);
19374 printf("Ap SET 80211h %d\n", enable);
19375 return 0;
19376 }
19377
developerfead3972023-05-25 20:15:02 +080019378 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
developera3511852023-06-14 14:12:59 +080019379 {
19380 wifi_factoryResetRadio(index);
19381 printf("wifi_factoryResetRadio ok!\n");
19382 return 0;
19383 }
developerfead3972023-05-25 20:15:02 +080019384 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
developera3511852023-06-14 14:12:59 +080019385 {
19386 ULONG rst_cnt;
19387 wifi_getRadioResetCount(index, &rst_cnt);
19388 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
19389 return 0;
19390 }
developer2edaf012023-05-24 14:24:53 +080019391 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080019392 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080019393 {
19394 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19395 exit(-1);
19396 }
developer49b17232023-05-19 16:35:19 +080019397 wifi_addApAclDevice(index, argv[3]);
19398 return 0;
19399 }
developer2edaf012023-05-24 14:24:53 +080019400 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
19401 wifi_getApAclDevices(index, buf, 1024);
19402 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080019403 return 0;
19404 }
developer2edaf012023-05-24 14:24:53 +080019405 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
19406 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080019407 {
19408 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19409 exit(-1);
19410 }
developer2edaf012023-05-24 14:24:53 +080019411 wifi_delApAclDevice(index, argv[3]);
19412 return 0;
19413 }
19414 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
19415 wifi_delApAclDevices(index);
19416 return 0;
19417 }
19418 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
developer863a4a62023-06-06 16:55:59 +080019419 UINT acl_num = 0;
developer2edaf012023-05-24 14:24:53 +080019420 wifi_getApAclDeviceNum(index, &acl_num);
19421 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
19422 return 0;
19423 }
19424 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
19425 wifi_getApDenyAclDevices(index, buf, 1024);
19426 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
19427 return 0;
19428 }
19429 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
19430 int filter_mode = 0;
19431 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080019432 {
19433 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19434 exit(-1);
19435 }
developer2edaf012023-05-24 14:24:53 +080019436 filter_mode = atoi(argv[3]);
19437 wifi_setApMacAddressControlMode(index,filter_mode);
19438 return 0;
19439 }
developer5cd4c862023-05-26 09:34:42 +080019440 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
19441 BOOL output_bool = 0;
19442 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
19443 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
19444 return 0;
19445 }
19446 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
19447 BOOL output_bool = 0;
19448 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
19449 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
19450 return 0;
19451 }
19452
19453 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
19454 int filter_mode = 0;
19455 wifi_getApMacAddressControlMode(index, &filter_mode);
19456 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
19457 return 0;
19458 }
19459 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
19460 int enable = 0;
19461 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080019462 {
19463 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19464 exit(-1);
19465 }
developer5cd4c862023-05-26 09:34:42 +080019466 enable = (BOOL)atoi(argv[3]);
19467 wifi_setRadioIGMPSnoopingEnable(index, enable);
19468 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
19469 return 0;
19470 }
developer2a6abc92023-10-17 17:19:14 +080019471 if (strncmp(argv[1], "wifi_setRadioDCSEnable", strlen(argv[1])) == 0) {
developer326d4232023-06-15 16:45:30 +080019472 int enable = 0;
19473 if(argc <= 3 )
19474 {
19475 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19476 exit(-1);
19477 }
19478 enable = (BOOL)atoi(argv[3]);
19479 wifi_setRadioDCSEnable(index, enable);
19480 wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
19481 return 0;
19482 }
developer2a6abc92023-10-17 17:19:14 +080019483 if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod", strlen(argv[1])) == 0) {
developer326d4232023-06-15 16:45:30 +080019484 ULONG period = 0;
developer5cd4c862023-05-26 09:34:42 +080019485
developer326d4232023-06-15 16:45:30 +080019486 wifi_getRadioAutoChannelRefreshPeriod(index, &period);
19487 wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
19488 return 0;
19489 }
developer2a6abc92023-10-17 17:19:14 +080019490 if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod", strlen(argv[1])) == 0) {
developer326d4232023-06-15 16:45:30 +080019491 ULONG period = 0;
developer2a6abc92023-10-17 17:19:14 +080019492 if(argc <= 3)
19493 {
19494 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19495 exit(-1);
19496 }
developer326d4232023-06-15 16:45:30 +080019497 period = (ULONG)atoi(argv[3]);
19498 wifi_setRadioDfsRefreshPeriod(index, period);
19499 wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
19500 return 0;
19501 }
developer2a6abc92023-10-17 17:19:14 +080019502 if (strncmp(argv[1], "wifi_setRadioDCSChannelPool", strlen(argv[1])) == 0) {
developer326d4232023-06-15 16:45:30 +080019503 char pool[256] = {'\0'};
developer2a6abc92023-10-17 17:19:14 +080019504 if(argc <= 3)
19505 {
19506 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19507 exit(-1);
19508 }
developerc14d83a2023-06-29 20:09:42 +080019509 strncpy(pool, argv[3], strlen(argv[3]));
developer326d4232023-06-15 16:45:30 +080019510 wifi_setRadioDCSChannelPool(index, pool);
19511 wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
19512 return 0;
19513 }
developer2a6abc92023-10-17 17:19:14 +080019514 if (strncmp(argv[1], "wifi_getRadioDCSChannelPool", strlen(argv[1])) == 0) {
developer326d4232023-06-15 16:45:30 +080019515 char pool[256] = {'\0'};
19516
19517 wifi_getRadioDCSChannelPool(index, pool);
19518 wifi_debug(DEBUG_NOTICE, "Get DCSChannelPool: %s\n", pool);
19519 return 0;
19520 }
developer5cd4c862023-05-26 09:34:42 +080019521 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
19522 BOOL out_status = 0;
19523 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
19524 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
19525 return 0;
19526 }
developer121a8e72023-05-22 09:19:39 +080019527
developer95c045d2023-05-24 19:26:28 +080019528 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
19529 int enable = 0;
19530 if(argc <= 3)
19531 {
19532 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19533 exit(-1);
19534 }
19535 enable = atoi(argv[3]);
19536 wifi_setApWmmEnable(index,enable);
19537 return 0;
19538 }
developerc1aa6532023-06-09 09:37:01 +080019539 if (strncmp(argv[1], "wifi_pushSsidAdvertisementEnable", strlen(argv[1])) == 0) {
19540 int enable = 0;
19541 if(argc <= 3)
19542 {
19543 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19544 exit(-1);
19545 }
19546 enable = atoi(argv[3]);
19547 wifi_pushSsidAdvertisementEnable(index,enable);
19548 return 0;
19549 }
developer56fbedb2023-05-30 16:47:05 +080019550 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
19551 wifi_down();
19552 return 0;
19553 }
developer95c045d2023-05-24 19:26:28 +080019554
developer56fbedb2023-05-30 16:47:05 +080019555 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
19556 BOOL enable = 0;
19557
19558 wifi_getRadioStatus(index, &enable);
19559 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
19560 return 0;
19561 }
developer333c1eb2023-05-31 14:59:39 +080019562
developer95c045d2023-05-24 19:26:28 +080019563 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
19564 BOOL enable = 0;
19565
19566 wifi_getApWMMCapability(index, &enable);
19567 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
19568 return 0;
19569 }
19570
19571 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
19572 BOOL enable = 0;
19573
19574 wifi_getApWmmEnable(index, &enable);
19575 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
19576 return 0;
19577 }
19578
developer2edaf012023-05-24 14:24:53 +080019579 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
19580 int filter_mode = 0;
19581 wifi_getApMacAddressControlMode(index, &filter_mode);
19582 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
19583 return 0;
19584 }
developer0f10c772023-05-16 21:43:39 +080019585 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080019586 {
developer863a4a62023-06-06 16:55:59 +080019587 UINT mode = 0;
developer0f10c772023-05-16 21:43:39 +080019588
developera3511852023-06-14 14:12:59 +080019589 wifi_getRadioMode(index, buf, &mode);
19590 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
19591 return 0;
19592 }
19593 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
19594 {
19595 BOOL b = FALSE;
19596 BOOL *output_bool = &b;
19597 wifi_getRadioAutoChannelEnable(index,output_bool);
19598 printf("Channel enabled = %d \n",b);
19599 return 0;
19600 }
19601 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
19602 {
19603 wifi_getApWpaEncryptionMode(index,buf);
19604 printf("encryption enabled = %s\n",buf);
19605 return 0;
19606 }
19607 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
19608 {
19609 BOOL b = FALSE;
19610 BOOL *output_bool = &b;
19611 wifi_getApSsidAdvertisementEnable(index,output_bool);
19612 printf("advertisment enabled = %d\n",b);
19613 return 0;
19614 }
19615 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
19616 {
19617 if(argc <= 3 )
19618 {
19619 printf("Insufficient arguments \n");
19620 exit(-1);
19621 }
developer72fb0bb2023-01-11 09:46:29 +080019622
developera3511852023-06-14 14:12:59 +080019623 char sta[20] = {'\0'};
19624 ULLONG handle= 0;
developerc14d83a2023-06-29 20:09:42 +080019625 strncpy(sta,argv[3], strlen(argv[3]));
developera3511852023-06-14 14:12:59 +080019626 mac_address_t st;
developer72fb0bb2023-01-11 09:46:29 +080019627 mac_addr_aton(st,sta);
19628
developera3511852023-06-14 14:12:59 +080019629 wifi_associated_dev_tid_stats_t tid_stats;
19630 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
19631 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
19632 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);
19633 }
developer72fb0bb2023-01-11 09:46:29 +080019634
developera3511852023-06-14 14:12:59 +080019635 if(strstr(argv[1], "getApEnable")!=NULL) {
19636 BOOL enable;
19637 ret=wifi_getApEnable(index, &enable);
19638 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
19639 }
19640 else if(strstr(argv[1], "setApEnable")!=NULL) {
developer2a6abc92023-10-17 17:19:14 +080019641 BOOL enable;
19642 if(argc <= 3)
19643 {
19644 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19645 exit(-1);
19646 }
19647 enable = atoi(argv[3]);
developera3511852023-06-14 14:12:59 +080019648 ret=wifi_setApEnable(index, enable);
19649 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
19650 }
19651 else if(strstr(argv[1], "getApStatus")!=NULL) {
19652 char status[64];
19653 ret=wifi_getApStatus(index, status);
19654 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
19655 }
19656 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
19657 {
19658 wifi_getSSIDNameStatus(index,buf);
19659 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
19660 return 0;
19661 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
19662 wifi_resetApVlanCfg(index);
19663 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
19664 return 0;
19665 }
19666 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
19667 wifi_ssidTrafficStats2_t stats={0};
19668 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
19669 printf("%s %d: returns %d\n", argv[1], index, ret);
19670 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
19671 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
19672 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
19673 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
19674 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
19675 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
19676 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
19677 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
19678 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
19679 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
19680 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
19681 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
19682 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
19683 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
19684 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
19685 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
19686 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
19687 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
19688 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
19689 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
19690 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
19691 }
19692 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
19693 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
19694 UINT array_size=0;
19695 UINT i=0;
19696 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
19697 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
19698 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
19699 printf(" neighbor %d:\n", i);
19700 printf(" ap_SSID =%s\n", pt->ap_SSID);
19701 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
19702 printf(" ap_Mode =%s\n", pt->ap_Mode);
19703 printf(" ap_Channel =%d\n", pt->ap_Channel);
19704 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
19705 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
19706 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
19707 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
19708 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
19709 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
19710 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
19711 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
19712 printf(" ap_Noise =%d\n", pt->ap_Noise);
19713 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
19714 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
19715 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
19716 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
19717 }
19718 if(neighbor_ap_array)
19719 free(neighbor_ap_array); //make sure to free the list
19720 }
19721 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
19722 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
19723 UINT array_size=0;
19724 UINT i=0;
19725 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
19726 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
19727 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
19728 printf(" associated_dev %d:\n", i);
19729 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
19730 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
19731 printf(" cli_SNR =%d\n", pt->cli_SNR);
19732 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
19733 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
19734 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
19735 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
19736 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
19737 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
19738 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
19739 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
19740 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
19741 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
19742 }
19743 if(associated_dev_array)
19744 free(associated_dev_array); //make sure to free the list
19745 }
developer72fb0bb2023-01-11 09:46:29 +080019746
developera3511852023-06-14 14:12:59 +080019747 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
19748 {
developer72fb0bb2023-01-11 09:46:29 +080019749#define MAX_ARRAY_SIZE 64
developera3511852023-06-14 14:12:59 +080019750 int i, array_size;
19751 char *p, *ch_str;
19752 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
developer72fb0bb2023-01-11 09:46:29 +080019753
developera3511852023-06-14 14:12:59 +080019754 if(argc != 5)
19755 {
19756 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
19757 exit(-1);
19758 }
19759 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
developer72fb0bb2023-01-11 09:46:29 +080019760
developera3511852023-06-14 14:12:59 +080019761 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
19762 {
19763 strtok_r(ch_str, ",", &p);
19764 input_output_channelStats_array[i].ch_number = atoi(ch_str);
19765 }
19766 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
19767 if(!array_size)
19768 array_size=1;//Need to print current channel statistics
19769 for(i=0; i<array_size; i++)
19770 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
19771 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
19772 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
19773 input_output_channelStats_array[i].ch_number,\
19774 input_output_channelStats_array[i].ch_noise,\
19775 input_output_channelStats_array[i].ch_utilization_busy_rx,\
19776 input_output_channelStats_array[i].ch_utilization_busy_tx,\
19777 input_output_channelStats_array[i].ch_utilization_busy,\
19778 input_output_channelStats_array[i].ch_utilization_busy_ext,\
19779 input_output_channelStats_array[i].ch_utilization_total);
19780 }
developer72fb0bb2023-01-11 09:46:29 +080019781
developera3511852023-06-14 14:12:59 +080019782 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
19783 {
19784 if(argc <= 3 )
19785 {
19786 printf("Insufficient arguments \n");
19787 exit(-1);
19788 }
19789 char mac_addr[20] = {'\0'};
19790 wifi_device_t output_struct;
19791 int dev_index = atoi(argv[3]);
developer72fb0bb2023-01-11 09:46:29 +080019792
developera3511852023-06-14 14:12:59 +080019793 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
19794 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
19795 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);
19796 }
developer72fb0bb2023-01-11 09:46:29 +080019797
developera3511852023-06-14 14:12:59 +080019798 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
19799 {
19800 if (argc <= 3)
19801 {
19802 printf("Insufficient arguments\n");
19803 exit(-1);
19804 }
19805 char args[256];
19806 wifi_NeighborReport_t *neighborReports;
developer72fb0bb2023-01-11 09:46:29 +080019807
developera3511852023-06-14 14:12:59 +080019808 neighborReports = calloc(argc - 2, sizeof(neighborReports));
19809 if (!neighborReports)
19810 {
19811 printf("Failed to allocate memory");
19812 exit(-1);
19813 }
developer72fb0bb2023-01-11 09:46:29 +080019814
developera3511852023-06-14 14:12:59 +080019815 for (int i = 3; i < argc; ++i)
19816 {
19817 char *val;
19818 int j = 0;
developerc14d83a2023-06-29 20:09:42 +080019819 unsigned long tmp;
developera3511852023-06-14 14:12:59 +080019820 memset(args, 0, sizeof(args));
19821 strncpy(args, argv[i], sizeof(args));
19822 val = strtok(args, ";");
19823 while (val != NULL)
19824 {
19825 if (j == 0)
19826 {
19827 mac_addr_aton(neighborReports[i - 3].bssid, val);
19828 } else if (j == 1)
19829 {
developerc14d83a2023-06-29 20:09:42 +080019830 if (hal_strtoul(val, 16, &tmp) < 0) {
19831 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080019832 }
19833 neighborReports[i - 3].info = tmp;
developera3511852023-06-14 14:12:59 +080019834 } else if (j == 2)
19835 {
developerc14d83a2023-06-29 20:09:42 +080019836 if (hal_strtoul(val, 16, &tmp) < 0) {
19837 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080019838 }
19839 neighborReports[i - 3].opClass = tmp;
developer5b23cd02023-07-19 20:26:03 +080019840
developera3511852023-06-14 14:12:59 +080019841 } else if (j == 3)
19842 {
developerc14d83a2023-06-29 20:09:42 +080019843 if (hal_strtoul(val, 16, &tmp) < 0) {
19844 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080019845 }
19846 neighborReports[i - 3].channel = tmp;
developera3511852023-06-14 14:12:59 +080019847 } else if (j == 4)
19848 {
developerc14d83a2023-06-29 20:09:42 +080019849 if (hal_strtoul(val, 16, &tmp) < 0) {
19850 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080019851 }
19852 neighborReports[i - 3].phyTable = tmp;
developera3511852023-06-14 14:12:59 +080019853 } else {
19854 printf("Insufficient arguments]n\n");
19855 exit(-1);
19856 }
19857 val = strtok(NULL, ";");
19858 j++;
19859 }
19860 }
developer72fb0bb2023-01-11 09:46:29 +080019861
developera3511852023-06-14 14:12:59 +080019862 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
19863 if (ret != RETURN_OK)
19864 {
19865 printf("wifi_setNeighborReports ret = %d", ret);
19866 exit(-1);
19867 }
19868 }
19869 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
19870 {
19871 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
19872 printf("%s.\n", buf);
19873 else
19874 printf("Error returned\n");
19875 }
19876 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
19877 {
19878 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
19879 printf("%s.\n", buf);
19880 else
19881 printf("Error returned\n");
19882 }
19883 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
19884 {
19885 if (argc <= 2)
19886 {
19887 printf("Insufficient arguments\n");
19888 exit(-1);
19889 }
19890 char buf[64]= {'\0'};
19891 wifi_getRadioOperatingChannelBandwidth(index,buf);
developerb57e9a82023-11-22 18:29:55 +080019892 printf("Current operating bandwidth is %s \n",buf);
19893 return 0;
19894 }
19895 if(strstr(argv[1],"wifi_getRadioConfiguredChannelBandwidth") != NULL)
19896 {
19897 if (argc <= 2)
19898 {
19899 printf("Insufficient arguments\n");
19900 exit(-1);
19901 }
19902 char buf[64]= {'\0'};
19903 wifi_getRadioConfiguredChannelBandwidth(index, buf);
19904 printf("Current config bandwidth is %s \n",buf);
19905 return 0;
19906 }
19907 if(strstr(argv[1],"wifi_getRadioChannelsInUse") != NULL)
19908 {
19909 if (argc <= 2)
19910 {
19911 printf("Insufficient arguments\n");
19912 exit(-1);
19913 }
19914 char buf[256]= {'\0'};
19915 wifi_getRadioChannelsInUse(index, buf);
19916 printf("RadioChannelsInUse is %s \n",buf);
developera3511852023-06-14 14:12:59 +080019917 return 0;
19918 }
19919 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
19920 {
19921 if (argc <= 5)
19922 {
19923 printf("Insufficient arguments\n");
19924 exit(-1);
19925 }
19926 UINT channel = atoi(argv[3]);
19927 UINT width = atoi(argv[4]);
19928 UINT beacon = atoi(argv[5]);
19929 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
19930 printf("Result = %d", ret);
19931 }
developer408cde72023-10-19 13:44:02 +080019932 if(strstr(argv[1],"wifi_getRadioChannel")!=NULL)
19933 {
19934 ULONG channel = 0;
19935 wifi_getRadioChannel(index, &channel);
19936 printf("channel is %ld \n",channel);
19937 return 0;
19938 }
developercc5cbfb2023-06-13 18:29:52 +080019939 if(strstr(argv[1],"wifi_getApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080019940 {
developercc5cbfb2023-06-13 18:29:52 +080019941 char br_name[64], ip[64], subset[64] = {0};
19942 wifi_getApBridgeInfo(0, br_name, ip, subset);
19943 printf("wifi_getApBridgeInfo br_name = %s, ip = %s, subset = %s\n", br_name, ip, subset);
developera3511852023-06-14 14:12:59 +080019944 }
developercc5cbfb2023-06-13 18:29:52 +080019945 if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
developera3511852023-06-14 14:12:59 +080019946 {
developer2a6abc92023-10-17 17:19:14 +080019947 int enable;
19948 if(argc <= 3)
19949 {
19950 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19951 exit(-1);
19952 }
19953 enable = atoi(argv[3]);
developercc5cbfb2023-06-13 18:29:52 +080019954 wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
19955 printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
developera3511852023-06-14 14:12:59 +080019956 }
developercc5cbfb2023-06-13 18:29:52 +080019957 if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080019958 {
developer2a6abc92023-10-17 17:19:14 +080019959 if(argc <= 5)
19960 {
19961 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19962 exit(-1);
19963 }
developercc5cbfb2023-06-13 18:29:52 +080019964 wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
19965 printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
developera3511852023-06-14 14:12:59 +080019966 }
developer72fb0bb2023-01-11 09:46:29 +080019967
developer6e578302023-06-21 10:11:16 +080019968 if(strstr(argv[1], "wifi_getATMCapable")!=NULL)
19969 {
19970 BOOL b = FALSE;
19971 BOOL *output_bool = &b;
19972 wifi_getATMCapable(output_bool);
19973 printf("ATM capable = %d \n",b);
19974 return 0;
19975 }
19976 if (strncmp(argv[1], "wifi_setATMEnable", strlen(argv[1])) == 0) {
19977 int enable = 0;
19978 if(argc <= 3)
19979 {
19980 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19981 exit(-1);
19982 }
19983 enable = atoi(argv[3]);
19984 wifi_setATMEnable(enable);
19985 return 0;
19986 }
19987 if (strncmp(argv[1], "wifi_getATMEnable", strlen(argv[1])) == 0) {
19988 BOOL b = FALSE;
19989 BOOL *output_bool = &b;
19990 wifi_getATMEnable(output_bool);
19991 printf("ATM enable = %d \n", b);
19992 return 0;
19993 }
19994 if (strncmp(argv[1], "wifi_setApATMAirTimePercent", strlen(argv[1])) == 0) {
19995 unsigned int percent = 0;
19996 if(argc <= 3)
19997 {
19998 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
19999 exit(-1);
20000 }
20001 percent = atoi(argv[3]);
20002 wifi_setApATMAirTimePercent(index, percent);
20003 return 0;
20004 }
20005 if (strncmp(argv[1], "wifi_getApATMAirTimePercent", strlen(argv[1])) == 0) {
20006 unsigned int percent = 0;
20007 unsigned int *output = &percent;
20008
20009 wifi_getApATMAirTimePercent(index, output);
20010 printf("ATM percent = %d \n", percent);
20011 return 0;
20012 }
developer82533be2023-06-28 17:21:01 +080020013 if (strstr(argv[1],"setGF")!=NULL)
20014 {
developer2a6abc92023-10-17 17:19:14 +080020015 BOOL enable;
20016 if(argc <= 3)
20017 {
20018 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
20019 exit(-1);
20020 }
20021 enable = atoi(argv[3]);
developer82533be2023-06-28 17:21:01 +080020022 if((ret=wifi_setRadio11nGreenfieldEnable(index, enable))==RETURN_OK)
20023 printf("wifi_setRadio11nGreenfieldEnable success\n");
20024 else
20025 printf("wifi_setRadio11nGreenfieldEnable Error\n");
20026 }
20027 if (strstr(argv[1],"setVID")!=NULL)
20028 {
developer2a6abc92023-10-17 17:19:14 +080020029 INT vid;
20030 if(argc <= 3)
20031 {
20032 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
20033 exit(-1);
20034 }
20035 vid = atoi(argv[3]);
developer82533be2023-06-28 17:21:01 +080020036 if((ret=wifi_setApVlanID(index, vid))==RETURN_OK)
20037 printf("wifi_setApVlanID success.\n");
20038 else
20039 printf("wifi_setApVlanID Error\n");
developerd14dff12023-06-28 22:47:44 +080020040 }
20041 if (strncmp(argv[1], "wifi_getApATMSta", strlen(argv[1])) == 0) {
20042 UCHAR outbuf[256]={0};
20043
20044 wifi_getApATMSta(index, outbuf, sizeof(outbuf));
20045 printf("sta air time percent is %s \n", outbuf);
20046 return 0;
20047 }
developer8461fe52023-11-07 16:11:44 +080020048 if (strstr(argv[1], "wifi_setRadioMRUEnable") != NULL) {
20049 unsigned char enable;
20050 if(argc <= 3)
20051 {
20052 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
20053 exit(-1);
20054 }
20055 enable = atoi(argv[3]);
20056 if (enable)
20057 wifi_setRadioMRUEnable(index, TRUE);
20058 else
20059 wifi_setRadioMRUEnable(index, FALSE);
20060 printf("%s handle wifi_setRadioMRUEnable\n", __FUNCTION__);
20061 }
20062 if (strstr(argv[1], "wifi_getRadioMRUEnable") != NULL) {
20063 BOOL b = FALSE;
20064 BOOL *output_bool = &b;
20065
20066 wifi_getRadioMRUEnable(index, output_bool);
20067 printf("wifi_getRadioMRUEnable = %d\n", b);
20068 }
developera3511852023-06-14 14:12:59 +080020069 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
20070 return 0;
developer72fb0bb2023-01-11 09:46:29 +080020071}
20072
20073#endif
20074
20075#ifdef WIFI_HAL_VERSION_3
20076
developer32f2a182023-06-27 19:50:41 +080020077INT BitMapToTransmitRates(UINT bitMap, char *BasicRate, unsigned long size)
developer72fb0bb2023-01-11 09:46:29 +080020078{
developera3511852023-06-14 14:12:59 +080020079 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer32f2a182023-06-27 19:50:41 +080020080 if (bitMap & WIFI_BITRATE_1MBPS) {
20081 if ((size - strlen(BasicRate)) <= 2)
20082 return RETURN_ERR;
20083 strncat(BasicRate, "1,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20084 }
20085 if (bitMap & WIFI_BITRATE_2MBPS) {
20086 if ((size - strlen(BasicRate)) <= 2)
20087 return RETURN_ERR;
20088 strncat(BasicRate, "2,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20089 }
20090 if (bitMap & WIFI_BITRATE_5_5MBPS) {
20091 if ((size - strlen(BasicRate)) <= 4)
20092 return RETURN_ERR;
20093 strncat(BasicRate, "5.5,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20094 }
20095 if (bitMap & WIFI_BITRATE_6MBPS) {
20096 if ((size - strlen(BasicRate)) <= 2)
20097 return RETURN_ERR;
20098 strncat(BasicRate, "6,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20099 }
20100 if (bitMap & WIFI_BITRATE_9MBPS) {
20101 if ((size - strlen(BasicRate)) <= 2)
20102 return RETURN_ERR;
20103 strncat(BasicRate, "9,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20104 }
20105 if (bitMap & WIFI_BITRATE_11MBPS) {
20106 if ((size - strlen(BasicRate)) <= 3)
20107 return RETURN_ERR;
20108 strncat(BasicRate, "11,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20109 }
20110 if (bitMap & WIFI_BITRATE_12MBPS) {
20111 if ((size - strlen(BasicRate)) <= 3)
20112 return RETURN_ERR;
20113 strncat(BasicRate, "12,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20114 }
20115 if (bitMap & WIFI_BITRATE_18MBPS) {
20116 if ((size - strlen(BasicRate)) <= 3)
20117 return RETURN_ERR;
20118 strncat(BasicRate, "18,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20119 }
20120 if (bitMap & WIFI_BITRATE_24MBPS) {
20121 if ((size - strlen(BasicRate)) <= 3)
20122 return RETURN_ERR;
20123 strncat(BasicRate, "24,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20124 }
20125 if (bitMap & WIFI_BITRATE_36MBPS) {
20126 if ((size - strlen(BasicRate)) <= 3)
20127 return RETURN_ERR;
20128 strncat(BasicRate, "36,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20129 }
20130 if (bitMap & WIFI_BITRATE_48MBPS) {
20131 if ((size - strlen(BasicRate)) <= 3)
20132 return RETURN_ERR;
20133 strncat(BasicRate, "48,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20134 }
20135 if (bitMap & WIFI_BITRATE_54MBPS) {
20136 if ((size - strlen(BasicRate)) <= 3)
20137 return RETURN_ERR;
20138 strncat(BasicRate, "54,", sizeof(BasicRate) - strlen(BasicRate) - 1);
20139 }
developera3511852023-06-14 14:12:59 +080020140 if (strlen(BasicRate) != 0) // remove last comma
20141 BasicRate[strlen(BasicRate) - 1] = '\0';
20142 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
20143 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080020144}
20145
20146INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
20147{
developera3511852023-06-14 14:12:59 +080020148 UINT BitMap = 0;
20149 char *rate;
developer72fb0bb2023-01-11 09:46:29 +080020150
developera3511852023-06-14 14:12:59 +080020151 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
20152 rate = strtok(BasicRatesList, ",");
20153 while(rate != NULL)
20154 {
20155 if (strcmp(rate, "1") == 0)
20156 BitMap |= WIFI_BITRATE_1MBPS;
20157 else if (strcmp(rate, "2") == 0)
20158 BitMap |= WIFI_BITRATE_2MBPS;
20159 else if (strcmp(rate, "5.5") == 0)
20160 BitMap |= WIFI_BITRATE_5_5MBPS;
20161 else if (strcmp(rate, "6") == 0)
20162 BitMap |= WIFI_BITRATE_6MBPS;
20163 else if (strcmp(rate, "9") == 0)
20164 BitMap |= WIFI_BITRATE_9MBPS;
20165 else if (strcmp(rate, "11") == 0)
20166 BitMap |= WIFI_BITRATE_11MBPS;
20167 else if (strcmp(rate, "12") == 0)
20168 BitMap |= WIFI_BITRATE_12MBPS;
20169 else if (strcmp(rate, "18") == 0)
20170 BitMap |= WIFI_BITRATE_18MBPS;
20171 else if (strcmp(rate, "24") == 0)
20172 BitMap |= WIFI_BITRATE_24MBPS;
20173 else if (strcmp(rate, "36") == 0)
20174 BitMap |= WIFI_BITRATE_36MBPS;
20175 else if (strcmp(rate, "48") == 0)
20176 BitMap |= WIFI_BITRATE_48MBPS;
20177 else if (strcmp(rate, "54") == 0)
20178 BitMap |= WIFI_BITRATE_54MBPS;
20179 rate = strtok(NULL, ",");
20180 }
20181 *basicRateBitMap = BitMap;
20182 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
20183 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080020184}
20185
20186// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
20187INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
20188{
developera3511852023-06-14 14:12:59 +080020189 char buf[128] = {0};
20190 int bandwidth = 20;
20191 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080020192 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developera3511852023-06-14 14:12:59 +080020193 wifi_radio_operationParam_t current_param;
developer82160f02023-08-19 15:30:44 +080020194 int ApIndex;
developer1a454b42023-11-20 18:38:06 +080020195 int ret, bss_num, i;
20196 char ret_buf[MAX_BUF_SIZE] = {0};
developerd52547a2023-12-26 20:01:42 +080020197 BOOL enabled = FALSE;
20198 struct timeval tv_now;
developer1a454b42023-11-20 18:38:06 +080020199
20200 ret = wifi_BandProfileRead(0, index, "BssidNum", ret_buf, sizeof(ret_buf), "1");
20201 if (ret != 0) {
20202 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
20203 return RETURN_ERR;
20204 }
20205 bss_num = atoi(ret_buf);
20206 if (bss_num <= 0) {
20207 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", ret_buf);
20208 return RETURN_ERR;
20209 }
20210 if (bss_num > LOGAN_MAX_NUM_VAP_PER_RADIO) {
20211 wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
20212 bss_num = LOGAN_MAX_NUM_VAP_PER_RADIO;
20213 }
20214 wifi_debug(DEBUG_ERROR, "band %d BssidNum %d\n", index, bss_num);
developer72fb0bb2023-01-11 09:46:29 +080020215
developera3511852023-06-14 14:12:59 +080020216 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080020217
developera3511852023-06-14 14:12:59 +080020218 multiple_set = TRUE;
developerd52547a2023-12-26 20:01:42 +080020219 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
20220 {
20221 wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
20222 return RETURN_ERR;
20223 }
20224 if (enabled == FALSE && operationParam->enable == TRUE) {
20225 wifi_setRadioEnable(index, TRUE);
20226 gettimeofday(&tv_now, NULL);
20227 radio_up_time[index] = tv_now.tv_sec;
20228 } else if (enabled == TRUE && operationParam->enable == FALSE) {
20229 wifi_setRadioEnable(index, FALSE);
20230 return RETURN_OK;
20231 }
developera3511852023-06-14 14:12:59 +080020232 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020233 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingParameters return error.\n");
developer1a454b42023-11-20 18:38:06 +080020234 goto err;
developera3511852023-06-14 14:12:59 +080020235 }
20236 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
20237 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020238 wifi_debug(DEBUG_ERROR, "wifi_setRadioAutoChannelEnable return error.\n");
developer1a454b42023-11-20 18:38:06 +080020239 goto err;
developera3511852023-06-14 14:12:59 +080020240 }
20241 drv_dat_change = TRUE;
20242 }
developerb8b49112023-12-21 14:24:55 +080020243
developera3511852023-06-14 14:12:59 +080020244 if (current_param.channelWidth != operationParam->channelWidth ||
20245 current_param.channel != operationParam->channel ||
20246 current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
20247 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
20248 bandwidth = 20;
20249 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
20250 bandwidth = 40;
20251 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
20252 bandwidth = 80;
20253 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
20254 bandwidth = 160;
developer9e772fb2023-12-04 13:33:42 +080020255 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_320MHZ)
20256 bandwidth = 320;
developer72fb0bb2023-01-11 09:46:29 +080020257
developera3511852023-06-14 14:12:59 +080020258 if (operationParam->autoChannelEnabled) {
20259 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020260 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developer1a454b42023-11-20 18:38:06 +080020261 goto err;
developera3511852023-06-14 14:12:59 +080020262 }
20263 } else {
20264 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020265 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developer1a454b42023-11-20 18:38:06 +080020266 goto err;
developera3511852023-06-14 14:12:59 +080020267 }
20268 }
developera3511852023-06-14 14:12:59 +080020269 }
20270 if (current_param.variant != operationParam->variant) {
20271 // Two different definition bit map, so need to check every bit.
20272 if (operationParam->variant & WIFI_80211_VARIANT_A)
20273 set_mode |= WIFI_MODE_A;
20274 if (operationParam->variant & WIFI_80211_VARIANT_B)
20275 set_mode |= WIFI_MODE_B;
20276 if (operationParam->variant & WIFI_80211_VARIANT_G)
20277 set_mode |= WIFI_MODE_G;
20278 if (operationParam->variant & WIFI_80211_VARIANT_N)
20279 set_mode |= WIFI_MODE_N;
20280 if (operationParam->variant & WIFI_80211_VARIANT_AC)
20281 set_mode |= WIFI_MODE_AC;
20282 if (operationParam->variant & WIFI_80211_VARIANT_AX)
20283 set_mode |= WIFI_MODE_AX;
developer408cde72023-10-19 13:44:02 +080020284 if (operationParam->variant & WIFI_80211_VARIANT_BE)
20285 set_mode |= WIFI_MODE_BE;
developera3511852023-06-14 14:12:59 +080020286 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
20287 memset(buf, 0, sizeof(buf));
developer8461fe52023-11-07 16:11:44 +080020288
20289 if (wifi_setRadioMode(index, NULL, set_mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020290 wifi_debug(DEBUG_ERROR, "wifi_setRadioMode return error.\n");
developer1a454b42023-11-20 18:38:06 +080020291 goto err;
developera3511852023-06-14 14:12:59 +080020292 }
20293 }
developer1a454b42023-11-20 18:38:06 +080020294
developera3511852023-06-14 14:12:59 +080020295 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer1a454b42023-11-20 18:38:06 +080020296 for (i = 0; i < bss_num; i++) {
developerc3556192023-12-06 17:59:09 +080020297 if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
20298 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
20299 continue;
20300 }
developer1a454b42023-11-20 18:38:06 +080020301 if (wifi_setApDTIMInterval(ApIndex, operationParam->dtimPeriod) != RETURN_OK) {
20302 wifi_debug(DEBUG_ERROR, "wifi_setApDTIMInterval return error.\n");
20303 goto err;
20304 }
20305 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080020306 }
20307 }
20308 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer1a454b42023-11-20 18:38:06 +080020309 for (i = 0; i < bss_num; i++) {
developerc3556192023-12-06 17:59:09 +080020310 if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
20311 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
20312 continue;
20313 }
20314
developer1a454b42023-11-20 18:38:06 +080020315 if (wifi_setRadioBeaconPeriod(ApIndex, operationParam->beaconInterval) != RETURN_OK) {
20316 wifi_debug(DEBUG_ERROR, "wifi_setRadioBeaconPeriod return error.\n");
20317 goto err;
20318 }
20319 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080020320 }
20321 }
20322 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer32f2a182023-06-27 19:50:41 +080020323 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf, sizeof(buf));
developer1a454b42023-11-20 18:38:06 +080020324 for (i = 0; i < bss_num; i++) {
developerc3556192023-12-06 17:59:09 +080020325 if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
20326 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
20327 continue;
20328 }
developer1a454b42023-11-20 18:38:06 +080020329 if (wifi_setRadioBasicDataTransmitRates(ApIndex, buf) != RETURN_OK) {
20330 wifi_debug(DEBUG_ERROR, "wifi_setRadioBasicDataTransmitRates return error.\n");
20331 goto err;
20332 }
20333 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080020334 }
20335 }
20336 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer1a454b42023-11-20 18:38:06 +080020337 for (i = 0; i < bss_num; i++) {
developerc3556192023-12-06 17:59:09 +080020338 if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
20339 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
20340 continue;
20341 }
developer1a454b42023-11-20 18:38:06 +080020342 if (wifi_setRadioFragmentationThreshold(ApIndex, operationParam->fragmentationThreshold) != RETURN_OK) {
20343 wifi_debug(DEBUG_ERROR, "wifi_setRadioFragmentationThreshold return error.\n");
20344 goto err;
20345 }
20346 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080020347 }
20348 }
developer1a454b42023-11-20 18:38:06 +080020349
20350 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
20351 for (i = 0; i < bss_num; i++) {
developerc3556192023-12-06 17:59:09 +080020352 if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
20353 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
20354 continue;
20355 }
developer1a454b42023-11-20 18:38:06 +080020356 if (wifi_setApRtsThreshold(ApIndex, operationParam->rtsThreshold) != RETURN_OK) {
20357 wifi_debug(DEBUG_ERROR, "wifi_setApRtsThreshold return error.\n");
20358 goto err;
20359 }
20360 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080020361 }
20362 }
developer1a454b42023-11-20 18:38:06 +080020363
20364 if (current_param.stbcEnable != operationParam->stbcEnable) {
20365 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
20366 wifi_debug(DEBUG_ERROR, "wifi_setRadioSTBCEnable return error.\n");
20367 goto err;
20368 }
developer56fbedb2023-05-30 16:47:05 +080020369 hapd_conf_change = TRUE;
20370 drv_dat_change = TRUE;
developer1a454b42023-11-20 18:38:06 +080020371 }
20372
20373 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080020374 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020375 wifi_debug(DEBUG_ERROR, "wifi_setGuardInterval return error.\n");
developer1a454b42023-11-20 18:38:06 +080020376 goto err;
developera3511852023-06-14 14:12:59 +080020377 }
developer1a454b42023-11-20 18:38:06 +080020378 hapd_conf_change = TRUE;
20379 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080020380 }
20381 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080020382 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080020383 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020384 wifi_debug(DEBUG_ERROR, "wifi_setRadioTransmitPower return error.\n");
developer1a454b42023-11-20 18:38:06 +080020385 goto err;
developera3511852023-06-14 14:12:59 +080020386 }
20387 }
developer1a454b42023-11-20 18:38:06 +080020388
developera3511852023-06-14 14:12:59 +080020389 if (current_param.obssCoex != operationParam->obssCoex) {
developera3511852023-06-14 14:12:59 +080020390 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020391 wifi_debug(DEBUG_ERROR, "wifi_setRadioObssCoexistenceEnable return error.\n");
developer1a454b42023-11-20 18:38:06 +080020392 goto err;
developera3511852023-06-14 14:12:59 +080020393 }
20394 }
developer1a454b42023-11-20 18:38:06 +080020395
developera3511852023-06-14 14:12:59 +080020396 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
20397 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020398 wifi_debug(DEBUG_ERROR, "wifi_setRadio11nGreenfieldEnable return error.\n");
developer1a454b42023-11-20 18:38:06 +080020399 goto err;
developera3511852023-06-14 14:12:59 +080020400 }
20401 }
developer8461fe52023-11-07 16:11:44 +080020402 if (current_param.MRU_enable != operationParam->MRU_enable) {
20403 if (wifi_setRadioMRUEnable(index, operationParam->MRU_enable) != RETURN_OK) {
20404 wifi_debug(DEBUG_ERROR, "wifi_setRadioMRUEnable return error.\n");
developer1a454b42023-11-20 18:38:06 +080020405 goto err;
developer8461fe52023-11-07 16:11:44 +080020406 }
20407 }
developer72fb0bb2023-01-11 09:46:29 +080020408
developera3511852023-06-14 14:12:59 +080020409 /* only down/up interface when dat file has been changed,
20410 * if enable is true, then restart the radio.
developer1a454b42023-11-20 18:38:06 +080020411 */
20412 multiple_set = false;
developera3511852023-06-14 14:12:59 +080020413 if (drv_dat_change == TRUE) {
20414 wifi_setRadioEnable(index, FALSE);
developerd982da92023-11-29 15:37:53 +080020415 if (operationParam->enable == TRUE) {
developera3511852023-06-14 14:12:59 +080020416 wifi_setRadioEnable(index, TRUE);
developerd982da92023-11-29 15:37:53 +080020417 eht_mld_config_init();
20418 mld_info_display();
20419 }
developera3511852023-06-14 14:12:59 +080020420 } else if (hapd_conf_change == TRUE) {
developer82160f02023-08-19 15:30:44 +080020421 for (i = 0; i < bss_num; i++) {
developerc3556192023-12-06 17:59:09 +080020422 if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
20423 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
20424 continue;
20425 }
developer1a454b42023-11-20 18:38:06 +080020426 wifi_quick_reload_ap(ApIndex);
developer82160f02023-08-19 15:30:44 +080020427 }
developera3511852023-06-14 14:12:59 +080020428 }
developer56fbedb2023-05-30 16:47:05 +080020429
developera3511852023-06-14 14:12:59 +080020430 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080020431
developera3511852023-06-14 14:12:59 +080020432 return RETURN_OK;
developer1a454b42023-11-20 18:38:06 +080020433err:
20434 multiple_set = false;
20435 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080020436}
20437
20438INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
20439{
developera3511852023-06-14 14:12:59 +080020440 char band[64] = {0};
20441 char buf[256] = {0};
developerc154deb2023-11-14 13:36:44 +080020442 char dat_file[128] = {0};
developer8078acf2023-08-04 18:52:48 +080020443
developera3511852023-06-14 14:12:59 +080020444 UINT mode = 0;
20445 BOOL enabled = FALSE;
developer863a4a62023-06-06 16:55:59 +080020446 int dtimPeriod;
developer2f79c922023-06-02 17:33:42 +080020447 UINT beaconInterval;
20448 UINT basicDataTransmitRates;
20449 UINT operationalDataTransmitRates;
20450 wifi_guard_interval_t guardInterval;
20451 UINT transmitPower;
developere40952c2023-06-15 18:46:43 +080020452 int res;
developerc14d83a2023-06-29 20:09:42 +080020453 unsigned long tmp;
developer166ae622023-12-21 15:27:09 +080020454 unsigned long channel = 0;
20455 BOOL auto_ch_en = FALSE;
developera47dfe22023-12-21 16:02:31 +080020456 wifi_band band_idx;
developer72fb0bb2023-01-11 09:46:29 +080020457
developera3511852023-06-14 14:12:59 +080020458 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
20459 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080020460
developera3511852023-06-14 14:12:59 +080020461 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
developerc154deb2023-11-14 13:36:44 +080020462 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, index);
20463 if (os_snprintf_error(sizeof(dat_file), res)) {
20464 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
20465 return RETURN_ERR;
20466 }
developera3511852023-06-14 14:12:59 +080020467 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
20468 {
developer75bd10c2023-06-27 11:34:08 +080020469 wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
developera3511852023-06-14 14:12:59 +080020470 return RETURN_ERR;
20471 }
20472 operationParam->enable = enabled;
developer72fb0bb2023-01-11 09:46:29 +080020473
developera3511852023-06-14 14:12:59 +080020474 memset(band, 0, sizeof(band));
20475 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
20476 {
developer75bd10c2023-06-27 11:34:08 +080020477 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingFrequencyBand return error.\n");
developera3511852023-06-14 14:12:59 +080020478 return RETURN_ERR;
20479 }
developer72fb0bb2023-01-11 09:46:29 +080020480
developera3511852023-06-14 14:12:59 +080020481 if (!strcmp(band, "2.4GHz"))
20482 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
20483 else if (!strcmp(band, "5GHz"))
20484 operationParam->band = WIFI_FREQUENCY_5_BAND;
20485 else if (!strcmp(band, "6GHz"))
20486 operationParam->band = WIFI_FREQUENCY_6_BAND;
20487 else
20488 {
developer75bd10c2023-06-27 11:34:08 +080020489 wifi_debug(DEBUG_ERROR, "cannot decode band for radio index %d ('%s')\n", index, band);
developera3511852023-06-14 14:12:59 +080020490 }
developer72fb0bb2023-01-11 09:46:29 +080020491
developer166ae622023-12-21 15:27:09 +080020492 if (wifi_getRadioChannel(index, &channel) != RETURN_OK)
20493 wifi_debug(DEBUG_ERROR, "wifi_getRadioChannel return error.\n");
20494 operationParam->channel = channel;
20495 if (operationParam->channel == 0)
20496 wifi_debug(DEBUG_ERROR, "operationParam->channel is 0\n");
developer5b23cd02023-07-19 20:26:03 +080020497
developer166ae622023-12-21 15:27:09 +080020498 if (wifi_getRadioAutoChannelEnable(index, &auto_ch_en) != RETURN_OK)
20499 wifi_debug(DEBUG_ERROR, "wifi_getRadioAutoChannelEnable return error.\n");
20500 if (auto_ch_en)
20501 operationParam->autoChannelEnabled = TRUE;
20502 else
developera3511852023-06-14 14:12:59 +080020503 operationParam->autoChannelEnabled = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080020504
developera3511852023-06-14 14:12:59 +080020505 memset(buf, 0, sizeof(buf));
20506 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020507 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
developera3511852023-06-14 14:12:59 +080020508 return RETURN_ERR;
20509 }
20510 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
20511 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
20512 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
20513 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
developer9e772fb2023-12-04 13:33:42 +080020514 else if (!strcmp(buf, "320MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_320MHZ;
developera3511852023-06-14 14:12:59 +080020515 else
20516 {
developer75bd10c2023-06-27 11:34:08 +080020517 wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", buf);
developera3511852023-06-14 14:12:59 +080020518 return false;
20519 }
developer72fb0bb2023-01-11 09:46:29 +080020520
developera3511852023-06-14 14:12:59 +080020521 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020522 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080020523 return RETURN_ERR;
20524 }
20525 // Two different definition bit map, so need to check every bit.
20526 if (mode & WIFI_MODE_A)
20527 operationParam->variant |= WIFI_80211_VARIANT_A;
20528 if (mode & WIFI_MODE_B)
20529 operationParam->variant |= WIFI_80211_VARIANT_B;
20530 if (mode & WIFI_MODE_G)
20531 operationParam->variant |= WIFI_80211_VARIANT_G;
20532 if (mode & WIFI_MODE_N)
20533 operationParam->variant |= WIFI_80211_VARIANT_N;
20534 if (mode & WIFI_MODE_AC)
20535 operationParam->variant |= WIFI_80211_VARIANT_AC;
20536 if (mode & WIFI_MODE_AX)
20537 operationParam->variant |= WIFI_80211_VARIANT_AX;
developer9e772fb2023-12-04 13:33:42 +080020538 if (mode & WIFI_MODE_BE)
20539 operationParam->variant |= WIFI_80211_VARIANT_BE;
20540
developera3511852023-06-14 14:12:59 +080020541 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020542 wifi_debug(DEBUG_ERROR, "wifi_getRadioDCSEnable return error.\n");
developera3511852023-06-14 14:12:59 +080020543 return RETURN_ERR;
20544 }
20545 if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020546 wifi_debug(DEBUG_ERROR, "wifi_getApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080020547 return RETURN_ERR;
20548 }
developer2f79c922023-06-02 17:33:42 +080020549 operationParam->dtimPeriod = dtimPeriod;
developera3511852023-06-14 14:12:59 +080020550 if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020551 wifi_debug(DEBUG_ERROR, "wifi_getRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080020552 return RETURN_ERR;
20553 }
developer2f79c922023-06-02 17:33:42 +080020554 operationParam->beaconInterval = beaconInterval;
developer72fb0bb2023-01-11 09:46:29 +080020555
developera3511852023-06-14 14:12:59 +080020556 memset(buf, 0, sizeof(buf));
20557 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020558 wifi_debug(DEBUG_ERROR, "wifi_getRadioSupportedDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080020559 return RETURN_ERR;
20560 }
20561 TransmitRatesToBitMap(buf, &basicDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080020562 operationParam->basicDataTransmitRates = basicDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080020563
developera3511852023-06-14 14:12:59 +080020564 memset(buf, 0, sizeof(buf));
20565 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020566 wifi_debug(DEBUG_ERROR, "wifi_getRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080020567 return RETURN_ERR;
20568 }
20569 TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080020570 operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080020571
developera3511852023-06-14 14:12:59 +080020572 memset(buf, 0, sizeof(buf));
developerc154deb2023-11-14 13:36:44 +080020573 wifi_datfileRead(dat_file, "FragThreshold", buf, sizeof(buf));
developerc14d83a2023-06-29 20:09:42 +080020574 if (hal_strtoul(buf, 10, &tmp) < 0) {
20575 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
20576 }
20577 operationParam->fragmentationThreshold = tmp;
developer72fb0bb2023-01-11 09:46:29 +080020578
developera3511852023-06-14 14:12:59 +080020579 if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020580 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080020581 return RETURN_ERR;
20582 }
developer2f79c922023-06-02 17:33:42 +080020583 operationParam->guardInterval = guardInterval;
20584
developera3511852023-06-14 14:12:59 +080020585 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020586 wifi_debug(DEBUG_ERROR, "wifi_getRadioPercentageTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080020587 return RETURN_ERR;
20588 }
developer2f79c922023-06-02 17:33:42 +080020589 operationParam->transmitPower = transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080020590
developera3511852023-06-14 14:12:59 +080020591 memset(buf, 0, sizeof(buf));
developerc154deb2023-11-14 13:36:44 +080020592 wifi_datfileRead(dat_file, "RTSThreshold", buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080020593 if (strcmp(buf, "-1") == 0) {
20594 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
20595 operationParam->ctsProtection = FALSE;
20596 } else {
developerc14d83a2023-06-29 20:09:42 +080020597 if (hal_strtoul(buf, 10, &tmp) < 0) {
20598 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
20599 }
20600 operationParam->rtsThreshold = tmp;
developera3511852023-06-14 14:12:59 +080020601 operationParam->ctsProtection = TRUE;
20602 }
developer72fb0bb2023-01-11 09:46:29 +080020603
developera3511852023-06-14 14:12:59 +080020604 memset(buf, 0, sizeof(buf));
developerc154deb2023-11-14 13:36:44 +080020605 wifi_datfileRead(dat_file, "HT_BSSCoexistence", buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080020606 if (strcmp(buf, "0") == 0)
20607 operationParam->obssCoex = FALSE;
20608 else
20609 operationParam->obssCoex = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080020610
developera47dfe22023-12-21 16:02:31 +080020611 band_idx = radio_index_to_band(index);
20612 memset(buf, 0, sizeof(buf));
20613 if (band_idx == band_2_4)
20614 wifi_datfileRead(dat_file, "HT_STBC", buf, sizeof(buf));
20615 else
20616 wifi_datfileRead(dat_file, "VHT_STBC", buf, sizeof(buf));
developer8078acf2023-08-04 18:52:48 +080020617
developera47dfe22023-12-21 16:02:31 +080020618 if (strncmp(buf, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +080020619 operationParam->stbcEnable = TRUE;
20620 else
20621 operationParam->stbcEnable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080020622
developera3511852023-06-14 14:12:59 +080020623 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080020624 wifi_debug(DEBUG_ERROR, "wifi_getRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080020625 return RETURN_ERR;
20626 }
developer72fb0bb2023-01-11 09:46:29 +080020627
developer8461fe52023-11-07 16:11:44 +080020628 if (wifi_getRadioMRUEnable(index, &operationParam->MRU_enable) != RETURN_OK) {
20629 wifi_debug(DEBUG_ERROR, "wifi_getRadioMRUEnable return error.\n");
20630 return RETURN_ERR;
20631 }
20632
developera3511852023-06-14 14:12:59 +080020633 // Below value is hardcoded
developer72fb0bb2023-01-11 09:46:29 +080020634
developera3511852023-06-14 14:12:59 +080020635 operationParam->numSecondaryChannels = 0;
20636 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
20637 operationParam->channelSecondary[i] = 0;
20638 }
20639 operationParam->csa_beacon_count = 15;
20640 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
developer72fb0bb2023-01-11 09:46:29 +080020641
developera3511852023-06-14 14:12:59 +080020642 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
20643 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080020644}
20645
developer9635f402023-12-25 19:48:21 +080020646static BOOL is_main_vap_index(int vap_index)
20647{
20648 int radio, main_vap_index;
20649
20650 for (radio = 0; radio < get_runtime_max_radio(); radio++) {
20651 if (array_index_to_vap_index(radio, 0, &main_vap_index) == RETURN_OK) {
20652 if (vap_index == main_vap_index)
20653 return TRUE;
20654 }
20655 }
20656
20657 return FALSE;
20658}
20659
developerc3556192023-12-06 17:59:09 +080020660static int array_index_to_vap_index(UINT radioIndex, int arrayIndex, int *vap_index)
developer72fb0bb2023-01-11 09:46:29 +080020661{
developerc3556192023-12-06 17:59:09 +080020662 if (radioIndex > 2 || arrayIndex < 0 || arrayIndex >= LOGAN_MAX_NUM_VAP_PER_RADIO)
developera3511852023-06-14 14:12:59 +080020663 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080020664
developerc3556192023-12-06 17:59:09 +080020665 if (radioIndex < 2)
20666 *vap_index = arrayIndex * 2 + radioIndex;
20667 else if (radioIndex == 2)
20668 *vap_index = (2 * LOGAN_MAX_NUM_VAP_PER_RADIO) + arrayIndex;
developer72fb0bb2023-01-11 09:46:29 +080020669
developerc3556192023-12-06 17:59:09 +080020670 return RETURN_OK;
20671}
developer96b38512023-02-22 11:17:45 +080020672
developerc3556192023-12-06 17:59:09 +080020673/*
20674 * 2.4G vap index: 0 2 4 6 8 10 12 14 ... (2*bss_idx)
20675 * 5G vap index: 1 3 5 7 9 11 13 15 ... (2*bss_idx + 1)
20676 * 6G vap index: 16 17 18 19 20 21 22 23 ... (2*LOGAN_MAX_NUM_VAP_PER_RADIO + bss_idx)
20677 */
developer96b38512023-02-22 11:17:45 +080020678
developerc3556192023-12-06 17:59:09 +080020679//static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
20680static int vap_index_to_radio_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
20681{
20682 if (vapIndex >= MAX_APS || vapIndex < 0)
developer9ce44382023-06-28 11:09:37 +080020683 return RETURN_ERR;
developerc3556192023-12-06 17:59:09 +080020684
20685 if (vapIndex >= 0 && vapIndex < (2 * LOGAN_MAX_NUM_VAP_PER_RADIO)) {
20686 *radioIndex = vapIndex % 2;
20687 *arrayIndex = vapIndex / 2;
20688 } else if (vapIndex >= (2 * LOGAN_MAX_NUM_VAP_PER_RADIO) && vapIndex < (3 * LOGAN_MAX_NUM_VAP_PER_RADIO)) {
20689 *radioIndex = 2;
20690 *arrayIndex = vapIndex - (2 * LOGAN_MAX_NUM_VAP_PER_RADIO);
developer9ce44382023-06-28 11:09:37 +080020691 }
developer96b38512023-02-22 11:17:45 +080020692
developerc3556192023-12-06 17:59:09 +080020693 return RETURN_OK;
developer96b38512023-02-22 11:17:45 +080020694}
20695
20696
developer72fb0bb2023-01-11 09:46:29 +080020697wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
developera3511852023-06-14 14:12:59 +080020698 if (strncmp(beaconRate, "1Mbps", 5) == 0)
20699 return WIFI_BITRATE_1MBPS;
20700 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
20701 return WIFI_BITRATE_2MBPS;
20702 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
20703 return WIFI_BITRATE_5_5MBPS;
20704 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
20705 return WIFI_BITRATE_6MBPS;
20706 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
20707 return WIFI_BITRATE_9MBPS;
20708 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
20709 return WIFI_BITRATE_11MBPS;
20710 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
20711 return WIFI_BITRATE_12MBPS;
20712 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
20713 return WIFI_BITRATE_18MBPS;
20714 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
20715 return WIFI_BITRATE_24MBPS;
20716 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
20717 return WIFI_BITRATE_36MBPS;
20718 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
20719 return WIFI_BITRATE_48MBPS;
20720 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
20721 return WIFI_BITRATE_54MBPS;
20722 return WIFI_BITRATE_DEFAULT;
developer72fb0bb2023-01-11 09:46:29 +080020723}
20724
developer32f2a182023-06-27 19:50:41 +080020725struct beacon_rate_2_string {
20726 wifi_bitrate_t beacon;
20727 char beacon_str[8];
20728};
20729
20730struct beacon_rate_2_string br2str[12] = {
20731 {WIFI_BITRATE_1MBPS, "1Mbps"},
20732 {WIFI_BITRATE_2MBPS, "2Mbps"},
20733 {WIFI_BITRATE_5_5MBPS, "5.5Mbps"},
20734 {WIFI_BITRATE_6MBPS, "6Mbps"},
20735 {WIFI_BITRATE_9MBPS, "9Mbps"},
20736 {WIFI_BITRATE_11MBPS, "11Mbps"},
20737 {WIFI_BITRATE_12MBPS, "12Mbps"},
20738 {WIFI_BITRATE_18MBPS, "18Mbps"},
20739 {WIFI_BITRATE_24MBPS, "24Mbps"},
20740 {WIFI_BITRATE_36MBPS, "36Mbps"},
20741 {WIFI_BITRATE_48MBPS, "48Mbps"},
20742 {WIFI_BITRATE_54MBPS, "54Mbps"}
20743};
20744
20745INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str, unsigned long str_size)
developer72fb0bb2023-01-11 09:46:29 +080020746{
developer32f2a182023-06-27 19:50:41 +080020747 int i;
20748 unsigned long len;
20749
20750 for (i = 0; i < (sizeof(br2str)/sizeof(br2str[0])); i++) {
20751 if (beacon == br2str[i].beacon) {
20752 len = strlen(br2str[i].beacon_str);
20753 if (len >= str_size)
20754 return RETURN_ERR;
20755 memcpy(beacon_str, br2str[i].beacon_str, len);
20756 beacon_str[len] = '\0';
20757 break;
20758 }
20759 }
developera3511852023-06-14 14:12:59 +080020760 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080020761}
20762
20763INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
20764{
developera3511852023-06-14 14:12:59 +080020765 INT mode = 0;
20766 INT ret = -1;
20767 UINT output = 0;
20768 int i = 0;
20769 int vap_index = 0;
20770 BOOL enabled = FALSE;
developera19a38f2023-11-27 19:30:48 +080020771 char buf[MAX_SSID_NAME_LEN] = {0};
developera3511852023-06-14 14:12:59 +080020772 wifi_vap_security_t security = {0};
developerbb9b20f2023-10-17 18:46:37 +080020773 int res = RETURN_OK;
developer6c6ef372023-11-08 10:59:14 +080020774 wifi_vap_info_t *vap;
20775 wifi_mld_info_t *mld_info;
20776 unsigned char mld_index;
developer72fb0bb2023-01-11 09:46:29 +080020777
developera3511852023-06-14 14:12:59 +080020778 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
20779 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080020780
developerbb9b20f2023-10-17 18:46:37 +080020781 memset((void *)map, 0, sizeof(*map));
developera3511852023-06-14 14:12:59 +080020782 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
20783 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +080020784 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
developera3511852023-06-14 14:12:59 +080020785 return RETURN_ERR;
20786 }
developerfde01262023-05-22 15:15:24 +080020787
developera3511852023-06-14 14:12:59 +080020788 map->num_vaps = atoi(buf);
20789 if (map->num_vaps <= 0) {
developer75bd10c2023-06-27 11:34:08 +080020790 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
developera3511852023-06-14 14:12:59 +080020791 return RETURN_ERR;
20792 }
developerbb9b20f2023-10-17 18:46:37 +080020793 if (map->num_vaps > LOGAN_MAX_NUM_VAP_PER_RADIO) {
20794 wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
20795 map->num_vaps = LOGAN_MAX_NUM_VAP_PER_RADIO;
20796 }
developerfde01262023-05-22 15:15:24 +080020797
developera3511852023-06-14 14:12:59 +080020798 for (i = 0; i < map->num_vaps; i++)
20799 {
20800 map->vap_array[i].radio_index = index;
developer72fb0bb2023-01-11 09:46:29 +080020801
developerc3556192023-12-06 17:59:09 +080020802 if (array_index_to_vap_index(index, i, &vap_index) != RETURN_OK) {
20803 wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
developerbb9b20f2023-10-17 18:46:37 +080020804 continue;
20805 }
developer72fb0bb2023-01-11 09:46:29 +080020806
developera3511852023-06-14 14:12:59 +080020807 map->vap_array[i].vap_index = vap_index;
developer9635f402023-12-25 19:48:21 +080020808 map->vap_array[i].u.bss_info.enabled = getVapEnableConfig(vap_index);
20809
developera3511852023-06-14 14:12:59 +080020810 memset(buf, 0, sizeof(buf));
20811 ret = wifi_getApName(vap_index, buf);
20812 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020813 wifi_debug(DEBUG_ERROR,"wifi_getApName return error\n");
developer9635f402023-12-25 19:48:21 +080020814 } else {
20815 ret = snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
20816 if (os_snprintf_error(sizeof(map->vap_array[i].vap_name), ret)) {
20817 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
20818 }
developere40952c2023-06-15 18:46:43 +080020819 }
developer72fb0bb2023-01-11 09:46:29 +080020820
developera3511852023-06-14 14:12:59 +080020821 memset(buf, 0, sizeof(buf));
20822 ret = wifi_getSSIDName(vap_index, buf);
20823 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020824 wifi_debug(DEBUG_ERROR, "wifi_getSSIDName return error\n");
developer9635f402023-12-25 19:48:21 +080020825 } else {
20826 ret = snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
20827 if (os_snprintf_error(sizeof(map->vap_array[i].u.bss_info.ssid), ret)) {
20828 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
20829 }
developere40952c2023-06-15 18:46:43 +080020830 }
developer72fb0bb2023-01-11 09:46:29 +080020831
developera3511852023-06-14 14:12:59 +080020832 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
20833 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020834 wifi_debug(DEBUG_ERROR,"wifi_getApSsidAdvertisementEnable return error\n");
developer9635f402023-12-25 19:48:21 +080020835 } else
20836 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080020837
developera3511852023-06-14 14:12:59 +080020838 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
20839 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020840 wifi_debug(DEBUG_ERROR, "wifi_getApMaxAssociatedDevices return error\n");
developer9635f402023-12-25 19:48:21 +080020841 } else
20842 map->vap_array[i].u.bss_info.bssMaxSta = output;
developer72fb0bb2023-01-11 09:46:29 +080020843
developera3511852023-06-14 14:12:59 +080020844 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
20845 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020846 wifi_debug(DEBUG_ERROR, "wifi_getBSSTransitionActivation return error\n");
developer9635f402023-12-25 19:48:21 +080020847 } else
20848 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080020849
developera3511852023-06-14 14:12:59 +080020850 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
20851 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020852 wifi_debug(DEBUG_ERROR, "wifi_getNeighborReportActivation return error\n");
developer9635f402023-12-25 19:48:21 +080020853 } else
20854 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080020855
developera3511852023-06-14 14:12:59 +080020856 ret = wifi_getApSecurity(vap_index, &security);
20857 if (ret != RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080020858 wifi_debug(DEBUG_ERROR, "wifi_getApSecurity return error\n");
developer9635f402023-12-25 19:48:21 +080020859 } else
20860 map->vap_array[i].u.bss_info.security = security;
developer72fb0bb2023-01-11 09:46:29 +080020861
developera3511852023-06-14 14:12:59 +080020862 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
20863 if (ret != RETURN_OK) {
developer9635f402023-12-25 19:48:21 +080020864 wifi_debug(DEBUG_ERROR, "wifi_getApMacAddressControlMode return error\n");
20865 } else {
20866 if (mode == 0)
20867 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
20868 else
20869 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
20870 if (mode == 1)
20871 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
20872 else if (mode == 2)
20873 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
developera3511852023-06-14 14:12:59 +080020874 }
developer9635f402023-12-25 19:48:21 +080020875
developera3511852023-06-14 14:12:59 +080020876 ret = wifi_getApWmmEnable(vap_index, &enabled);
20877 if (ret != RETURN_OK) {
developer9635f402023-12-25 19:48:21 +080020878 wifi_debug(DEBUG_ERROR, "wifi_getApWmmEnable return error\n");
20879 } else
20880 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080020881
developera3511852023-06-14 14:12:59 +080020882 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
20883 if (ret != RETURN_OK) {
developer9635f402023-12-25 19:48:21 +080020884 wifi_debug(DEBUG_ERROR, "wifi_getApUAPSDCapability return error\n");
20885 } else
20886 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080020887
developera3511852023-06-14 14:12:59 +080020888 memset(buf, 0, sizeof(buf));
20889 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
20890 if (ret != RETURN_OK) {
developer9635f402023-12-25 19:48:21 +080020891 wifi_debug(DEBUG_ERROR, "wifi_getApBeaconRate return error\n");
20892 } else
20893 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
developer72fb0bb2023-01-11 09:46:29 +080020894
developera3511852023-06-14 14:12:59 +080020895 memset(buf, 0, sizeof(buf));
20896 ret = wifi_getBaseBSSID(vap_index, buf);
20897 if (ret != RETURN_OK) {
developer9635f402023-12-25 19:48:21 +080020898 wifi_debug(DEBUG_ERROR, "wifi_getBaseBSSID return error\n");
20899 } else {
20900 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
20901 wifi_debug(DEBUG_ERROR, "hwaddr_aton2 fail\n");
20902 }
developer5b2f10c2023-05-25 17:02:21 +080020903 }
developera3511852023-06-14 14:12:59 +080020904 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
20905 if (ret != RETURN_OK) {
developerc14d83a2023-06-29 20:09:42 +080020906 wifi_debug(DEBUG_ERROR, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
developer9635f402023-12-25 19:48:21 +080020907 } else
20908 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
developer72fb0bb2023-01-11 09:46:29 +080020909
developer6c6ef372023-11-08 10:59:14 +080020910 ret = wifi_getApIsolationEnable(vap_index, &enabled);
20911 if (ret != RETURN_OK) {
developer9635f402023-12-25 19:48:21 +080020912 wifi_debug(DEBUG_ERROR, "wifi_getApIsolationEnable return error\n");
20913 } else
20914 map->vap_array[i].u.bss_info.isolation = enabled;
developer6c6ef372023-11-08 10:59:14 +080020915 }
20916
20917 for (i = 0; i < map->num_vaps; i++)
20918 {
20919 map->vap_array[i].radio_index = index;
20920 vap = &(map->vap_array[i]);
20921
20922 mld_info = &(vap->u.bss_info.mld_info);
20923 memset(mld_info, 0, sizeof(*mld_info));
20924 memcpy(mld_info->local_addr, map->vap_array[i].u.bss_info.bssid, 6);
20925
20926 mld_index = mld_ap_test_all_mlds(vap->vap_index);
20927 if (mld_index) {
20928 memcpy(mld_info->common_info.mld_addr, mld_config.mld[mld_index].mld_mac, 6);
20929 mld_info->common_info.mld_enable = TRUE;
20930 mld_info->common_info.mld_index = mld_index;
20931 }
20932 wifi_debug(DEBUG_ERROR,
20933 "vap_index[%d], mld_enable=%d, mld_index[%d]\n",
20934 vap->vap_index, mld_info->common_info.mld_enable, mld_info->common_info.mld_index);
developera3511852023-06-14 14:12:59 +080020935 }
20936 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developerbb9b20f2023-10-17 18:46:37 +080020937 return res;
developer72fb0bb2023-01-11 09:46:29 +080020938}
20939
developer47cc27a2023-05-17 23:09:58 +080020940void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080020941{
developera3511852023-06-14 14:12:59 +080020942 char if_name[16] = {0};
developera3511852023-06-14 14:12:59 +080020943 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080020944 int res;
developer72fb0bb2023-01-11 09:46:29 +080020945
developera3511852023-06-14 14:12:59 +080020946 *enable = FALSE;
20947 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
20948 return;
developer72fb0bb2023-01-11 09:46:29 +080020949
developer8078acf2023-08-04 18:52:48 +080020950 res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
20951 if (res) {
20952 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
20953
developere40952c2023-06-15 18:46:43 +080020954 }
developer8078acf2023-08-04 18:52:48 +080020955
developera3511852023-06-14 14:12:59 +080020956 if (strlen(buf) > 0)
20957 *enable = TRUE;
20958 return;
developer72fb0bb2023-01-11 09:46:29 +080020959}
20960
developer56fbedb2023-05-30 16:47:05 +080020961int hostapd_manage_bss(INT apIndex, BOOL enable)
20962{
20963 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080020964 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer8078acf2023-08-04 18:52:48 +080020965
developer56fbedb2023-05-30 16:47:05 +080020966 char buf[MAX_BUF_SIZE] = {0};
20967 BOOL status = FALSE;
developer56fbedb2023-05-30 16:47:05 +080020968 int phyId = 0;
developerc3556192023-12-06 17:59:09 +080020969 int radioIndex, bss_idx;
developere40952c2023-06-15 18:46:43 +080020970 int res;
developer56fbedb2023-05-30 16:47:05 +080020971
20972 wifi_getApEnable(apIndex, &status);
20973
developer56fbedb2023-05-30 16:47:05 +080020974 if (enable == status)
20975 return RETURN_OK;
20976
20977 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
20978 return RETURN_ERR;
20979
20980 if (enable == TRUE) {
developerc3556192023-12-06 17:59:09 +080020981 if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
20982 wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
20983 return RETURN_ERR;
20984 }
developer56fbedb2023-05-30 16:47:05 +080020985 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +080020986 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
20987 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
20988 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
20989 return RETURN_ERR;
20990 }
developer82160f02023-08-19 15:30:44 +080020991
20992 wifi_debug(DEBUG_ERROR, "raw ADD bss_config config_file=%s\n", config_file);
20993
developer8078acf2023-08-04 18:52:48 +080020994 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
20995 if (res) {
20996 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
20997
developere40952c2023-06-15 18:46:43 +080020998 }
developer8078acf2023-08-04 18:52:48 +080020999
developer56fbedb2023-05-30 16:47:05 +080021000 } else {
developerc14d83a2023-06-29 20:09:42 +080021001 wifi_debug(DEBUG_ERROR, "%s %d\n", __func__, __LINE__);
developer82160f02023-08-19 15:30:44 +080021002
21003 wifi_debug(DEBUG_ERROR, "global raw REMOVE %s\n", interface_name);
developer8078acf2023-08-04 18:52:48 +080021004 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
21005 if (res) {
21006 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21007
developere40952c2023-06-15 18:46:43 +080021008 }
developer56fbedb2023-05-30 16:47:05 +080021009 }
developer8078acf2023-08-04 18:52:48 +080021010 res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer56fbedb2023-05-30 16:47:05 +080021011 interface_name, interface_name, enable, VAP_STATUS_FILE);
developer8078acf2023-08-04 18:52:48 +080021012 if (res) {
21013 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21014
developere40952c2023-06-15 18:46:43 +080021015 }
developer56fbedb2023-05-30 16:47:05 +080021016 //Wait for wifi up/down to apply
21017 return RETURN_OK;
21018}
21019
21020int hostapd_raw_add_bss(int apIndex)
21021{
21022 return hostapd_manage_bss(apIndex, TRUE);
21023}
21024
21025int hostapd_raw_remove_bss(int apIndex)
21026{
21027 return hostapd_manage_bss(apIndex, FALSE);
21028}
21029
21030int hostapd_raw_restart_bss(int apIndex)
developer333c1eb2023-05-31 14:59:39 +080021031{
developerdaf24792023-06-06 11:40:04 +080021032 int ret = 0;
21033
21034 ret = hostapd_raw_remove_bss(apIndex);
21035 if(ret != RETURN_OK)
21036 return RETURN_ERR;
21037
21038 ret = hostapd_raw_add_bss(apIndex);
21039 if(ret != RETURN_OK)
21040 return RETURN_ERR;
developerac5919a2023-12-04 18:18:54 +080021041
21042 return RETURN_OK;
21043}
21044
21045static INT getVapBridge(int ap_index, char *bridge_name_buf, int buf_size)
21046{
21047 int res;
21048 char config_file[128] = {0};
21049
21050 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21051 if (os_snprintf_error(sizeof(config_file), res)) {
21052 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21053 return RETURN_ERR;
21054 }
21055 if (wifi_hostapdRead(config_file, "bridge", bridge_name_buf, buf_size) != RETURN_OK) {
21056 wifi_debug(DEBUG_ERROR, "get bridge fail from %s\n", config_file);
21057 return RETURN_ERR;
21058 }
21059
21060 return RETURN_OK;
21061}
21062
21063static INT setVapBridge(int ap_index, char *bridge_name)
21064{
21065 int res;
21066 char config_file[128] = {0};
21067 struct params param = {.name = "bridge"};
21068
21069 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21070 if (os_snprintf_error(sizeof(config_file), res)) {
21071 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21072 return RETURN_ERR;
21073 }
21074 wifi_debug(DEBUG_ERROR, "set bridge to %s in %s\n", bridge_name, config_file);
21075
21076 param.name = "bridge";
21077 param.value = bridge_name;
21078 if (wifi_hostapdWrite(config_file, &param, 1) != RETURN_OK) {
21079 wifi_debug(DEBUG_ERROR, "set bridge fail to %s\n", config_file);
21080 return RETURN_ERR;
21081 }
developerdaf24792023-06-06 11:40:04 +080021082
21083 return RETURN_OK;
developer56fbedb2023-05-30 16:47:05 +080021084}
21085
developer72fb0bb2023-01-11 09:46:29 +080021086INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
21087{
developera3511852023-06-14 14:12:59 +080021088 unsigned int i;
21089 wifi_vap_info_t *vap_info = NULL;
21090 int acl_mode;
21091 int ret = 0;
21092 char buf[256] = {0};
developera3511852023-06-14 14:12:59 +080021093 char config_file[64] = {0};
developer136e4642023-11-29 10:41:32 +080021094 BOOL apEnable;
developera3511852023-06-14 14:12:59 +080021095 int band_idx;
developere40952c2023-06-15 18:46:43 +080021096 int res;
developer6c6ef372023-11-08 10:59:14 +080021097 wifi_mld_common_info_t *mld_info;
21098 unsigned char mld_index;
21099 unsigned char ap_index_array[MAX_APS] = {0};
21100 unsigned char ap_array_num;
21101 char interface_name[IF_NAME_SIZE] = {0};
developerac5919a2023-12-04 18:18:54 +080021102 char bridge_name[WIFI_BRIDGE_NAME_LEN] = {0};
21103 unsigned char hostapd_if_restart;
developer72fb0bb2023-01-11 09:46:29 +080021104
developera3511852023-06-14 14:12:59 +080021105 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer7afe45d2023-12-15 17:45:51 +080021106 printf("Entering %s radio[%d], map->num_vaps = %d\n", __func__, (int)index, map->num_vaps);
developerac5919a2023-12-04 18:18:54 +080021107 for (i = 0; i < map->num_vaps; i++) {
21108 hostapd_if_restart = 0;
developera3511852023-06-14 14:12:59 +080021109 multiple_set = TRUE;
developer136e4642023-11-29 10:41:32 +080021110
developera3511852023-06-14 14:12:59 +080021111 vap_info = &map->vap_array[i];
developer72fb0bb2023-01-11 09:46:29 +080021112
developer9635f402023-12-25 19:48:21 +080021113 setVapEnableConfig(vap_info->vap_index, vap_info->u.bss_info.enabled);
21114
developer08e5ea32023-12-01 10:25:49 +080021115 if (vap_info->u.bss_info.enabled == FALSE) {
developer136e4642023-11-29 10:41:32 +080021116 wifi_getApEnable(vap_info->vap_index, &apEnable);
21117 if (apEnable) {
21118 wifi_setApEnable(vap_info->vap_index, FALSE);
21119 }
developera3511852023-06-14 14:12:59 +080021120 continue;
developer136e4642023-11-29 10:41:32 +080021121 }
21122
21123 if (vap_info->u.bss_info.enabled == TRUE) {
21124 wifi_getApEnable(vap_info->vap_index, &apEnable);
21125 if (!apEnable)
21126 wifi_setApEnable(vap_info->vap_index, TRUE);
21127 }
developer72fb0bb2023-01-11 09:46:29 +080021128
developer7afe45d2023-12-15 17:45:51 +080021129 wifi_debug(DEBUG_ERROR, "\nCreate VAP for vap_info->vap_index=%d\n", vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080021130
developera3511852023-06-14 14:12:59 +080021131 band_idx = radio_index_to_band(index);
developere40952c2023-06-15 18:46:43 +080021132 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
21133 if (os_snprintf_error(sizeof(config_file), res)) {
21134 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer1a454b42023-11-20 18:38:06 +080021135 goto err;
developere40952c2023-06-15 18:46:43 +080021136 }
developer8078acf2023-08-04 18:52:48 +080021137
developerac5919a2023-12-04 18:18:54 +080021138 /*check if hostapd conf file exist or not, if not exist, create an new one*/
21139 if (access(config_file, F_OK) != 0) {
21140 if(band_idx >= 0 && band_idx < sizeof(wifi_band_str)/sizeof(wifi_band_str[0])) {
21141 wifi_debug(DEBUG_ERROR, "\n%s not exist, create an new one\n", config_file);
21142 res = _syscmd_secure(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
21143 if (res) {
21144 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21145 }
21146 }
developer8078acf2023-08-04 18:52:48 +080021147 }
developer72fb0bb2023-01-11 09:46:29 +080021148
developera3511852023-06-14 14:12:59 +080021149 struct params params[3];
21150 params[0].name = "interface";
21151 params[0].value = vap_info->vap_name;
developer1a454b42023-11-20 18:38:06 +080021152 wifi_hostapdWrite(config_file, params, 1);
developer72fb0bb2023-01-11 09:46:29 +080021153
developera3511852023-06-14 14:12:59 +080021154 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
21155 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021156 wifi_debug(DEBUG_ERROR,"wifi_setSSIDName return error\n");
developera3511852023-06-14 14:12:59 +080021157 }
developer72fb0bb2023-01-11 09:46:29 +080021158
developera3511852023-06-14 14:12:59 +080021159 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
21160 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021161 wifi_debug(DEBUG_ERROR, "wifi_setApSsidAdvertisementEnable return error\n");
developera3511852023-06-14 14:12:59 +080021162 }
developer72fb0bb2023-01-11 09:46:29 +080021163
developera3511852023-06-14 14:12:59 +080021164 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
21165 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021166 wifi_debug(DEBUG_ERROR, "wifi_setApMaxAssociatedDevices return error\n");
developera3511852023-06-14 14:12:59 +080021167 }
developer72fb0bb2023-01-11 09:46:29 +080021168
developera3511852023-06-14 14:12:59 +080021169 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
21170 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021171 wifi_debug(DEBUG_ERROR, "wifi_setBSSTransitionActivation return error\n");
developera3511852023-06-14 14:12:59 +080021172 }
developer72fb0bb2023-01-11 09:46:29 +080021173
developera3511852023-06-14 14:12:59 +080021174 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
21175 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021176 wifi_debug(DEBUG_ERROR, "wifi_setNeighborReportActivation return error\n");
developera3511852023-06-14 14:12:59 +080021177 }
developer72fb0bb2023-01-11 09:46:29 +080021178
developera3511852023-06-14 14:12:59 +080021179 if (vap_info->u.bss_info.mac_filter_enable == false){
21180 acl_mode = 0;
21181 }else {
21182 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
21183 acl_mode = 2;
developer8078acf2023-08-04 18:52:48 +080021184 res = _syscmd_secure(buf, sizeof(buf), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
21185 if (res) {
21186 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
developere40952c2023-06-15 18:46:43 +080021187 }
developera3511852023-06-14 14:12:59 +080021188 }else{
21189 acl_mode = 1;
21190 }
21191 }
developer72fb0bb2023-01-11 09:46:29 +080021192
developera3511852023-06-14 14:12:59 +080021193 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
21194 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021195 wifi_debug(DEBUG_ERROR, "wifi_setApWmmUapsdEnable return error\n");
developera3511852023-06-14 14:12:59 +080021196 }
developer72fb0bb2023-01-11 09:46:29 +080021197
developera3511852023-06-14 14:12:59 +080021198 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080021199 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080021200 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
21201 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021202 wifi_debug(DEBUG_ERROR, "wifi_setApBeaconRate return error\n");
developera3511852023-06-14 14:12:59 +080021203 }
developer72fb0bb2023-01-11 09:46:29 +080021204
developera3511852023-06-14 14:12:59 +080021205 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
21206 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021207 wifi_debug(DEBUG_ERROR, "wifi_setRadioIGMPSnoopingEnable\n");
developera3511852023-06-14 14:12:59 +080021208 }
developer72fb0bb2023-01-11 09:46:29 +080021209
developera3511852023-06-14 14:12:59 +080021210 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
21211 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021212 wifi_debug(DEBUG_ERROR, "wifi_setApSecurity return error\n");
developera3511852023-06-14 14:12:59 +080021213 }
developerac5919a2023-12-04 18:18:54 +080021214
21215 if (getVapBridge(vap_info->vap_index, bridge_name, sizeof(bridge_name)) == RETURN_OK) {
developer7afe45d2023-12-15 17:45:51 +080021216 if ((strlen(vap_info->bridge_name) > 0) && (strlen(bridge_name) != strlen(vap_info->bridge_name) ||
developerac5919a2023-12-04 18:18:54 +080021217 (strlen(bridge_name) == strlen(vap_info->bridge_name) &&
developer7afe45d2023-12-15 17:45:51 +080021218 strncmp(bridge_name, vap_info->bridge_name, strlen(bridge_name))))) {
developerac5919a2023-12-04 18:18:54 +080021219 hostapd_if_restart = 1;
21220 setVapBridge(vap_info->vap_index, vap_info->bridge_name);
21221 }
21222 }
21223
developera3511852023-06-14 14:12:59 +080021224 multiple_set = FALSE;
developerac5919a2023-12-04 18:18:54 +080021225 if (hostapd_if_restart)
21226 hostapd_raw_restart_bss(vap_info->vap_index);
21227 else
21228 wifi_quick_reload_ap(vap_info->vap_index);
developera3511852023-06-14 14:12:59 +080021229 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
21230 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
21231 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021232 wifi_debug(DEBUG_ERROR, "wifi_setApMacAddressControlMode return error\n");
developera3511852023-06-14 14:12:59 +080021233 }
developer72fb0bb2023-01-11 09:46:29 +080021234
developer6bfd6462023-08-24 14:28:18 +080021235 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
21236 if (ret != RETURN_OK) {
21237 wifi_debug(DEBUG_ERROR, "wifi_setApWmmEnable return error\n");
developer6bfd6462023-08-24 14:28:18 +080021238 }
21239
developer68aaecb2023-11-03 10:36:23 +080021240 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
21241 if (ret != RETURN_OK) {
21242 wifi_debug(DEBUG_ERROR, "wifi_setApIsolationEnable return error\n");
developer68aaecb2023-11-03 10:36:23 +080021243 }
21244
developera3511852023-06-14 14:12:59 +080021245 // TODO mgmtPowerControl, interworking, wps
21246 }
developer6c6ef372023-11-08 10:59:14 +080021247
21248 /*process mlo operation*/
developerac5919a2023-12-04 18:18:54 +080021249 for (i = 0; i < map->num_vaps; i++) {
developer6c6ef372023-11-08 10:59:14 +080021250 vap_info = &map->vap_array[i];
21251 mld_info = &vap_info->u.bss_info.mld_info.common_info;
21252
21253 wifi_debug(DEBUG_ERROR, "process mlo operation\n");
21254 if (!mld_info->mld_enable) {
developerd982da92023-11-29 15:37:53 +080021255 wifi_debug(DEBUG_ERROR, "disable mlo on vap[%d], vap->enabled=%d\n",
21256 (int)vap_info->vap_index, vap_info->u.bss_info.enabled);
developer6c6ef372023-11-08 10:59:14 +080021257 mld_index = mld_ap_test_all_mlds((int)vap_info->vap_index);
21258 if (mld_index) {
21259 wifi_debug(DEBUG_ERROR, "mlo disabled, remove ap(%d) from mld group(%d)\n",
21260 (int)vap_info->vap_index, (int)mld_index);
developerb340de62023-11-22 20:10:05 +080021261 if (wifi_eht_remove_from_ap_mld(mld_index, vap_info->vap_index) != RETURN_OK) {
developer6c6ef372023-11-08 10:59:14 +080021262 wifi_debug(DEBUG_ERROR, "fail to remove ap(%d) from mld(%d)\n",
21263 (int)vap_info->vap_index, (int)mld_index);
21264 continue;
21265 }
21266
developerd982da92023-11-29 15:37:53 +080021267 if (wifi_GetInterfaceName(vap_info->vap_index, interface_name) == RETURN_OK &&
21268 wifi_getApEnable(vap_info->vap_index, &apEnable) == RETURN_OK) {
21269 /*if ap is enabled, bring it down and up to make it init single link mld*/
21270 if (apEnable) {
21271 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
21272 if (res) {
21273 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21274 }
21275 res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up", interface_name);
21276 if (res) {
21277 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21278 }
developer6c6ef372023-11-08 10:59:14 +080021279 }
21280 }
21281
developerb340de62023-11-22 20:10:05 +080021282 if (wifi_eht_get_ap_from_mld(mld_index, ap_index_array, &ap_array_num) != RETURN_OK) {
developer6c6ef372023-11-08 10:59:14 +080021283 wifi_debug(DEBUG_ERROR,
developerb340de62023-11-22 20:10:05 +080021284 "fail to get all aps from mld(%d).\n", mld_index);
developer6c6ef372023-11-08 10:59:14 +080021285 continue;
21286 }
21287
21288 if (ap_array_num == 0) {
21289 wifi_debug(DEBUG_ERROR,
21290 "there's no affiliated ap in mld(%d), destroy it.\n", mld_index);
21291 wifi_eht_destroy_ap_mld(mld_index);
21292 }
21293 }
21294 } else {
21295 if (mld_info->mld_index == 0 || mld_info->mld_index > MAX_ML_MLD_CNT) {
21296 wifi_debug(DEBUG_ERROR, "invalid mld index %d, ignore it.\n",
21297 (int)mld_info->mld_index);
21298 continue;
21299 }
21300
developerd982da92023-11-29 15:37:53 +080021301 if (!vap_info->u.bss_info.enabled) {
21302 wifi_debug(DEBUG_ERROR, "vap %d is disabled, not do mlo process.\n",
21303 (int)vap_info->vap_index);
21304 continue;
21305 }
21306
developer6c6ef372023-11-08 10:59:14 +080021307 if (!mld_test(mld_info->mld_index)) {
developerb340de62023-11-22 20:10:05 +080021308 if (wifi_eht_create_ap_mld(mld_info->mld_index, mld_info->mld_addr) != RETURN_OK) {
developer6c6ef372023-11-08 10:59:14 +080021309 wifi_debug(DEBUG_ERROR,
21310 "fail to create ap mld(%d)\n", mld_info->mld_index);
21311 continue;
21312 }
21313 } else {
21314 if(mld_ap_test(&(mld_config.mld[mld_info->mld_index]), vap_info->vap_index)) {
21315 wifi_debug(DEBUG_ERROR,
21316 "current vap(%d) is already the affiliated ap of mld(%d)\n",
21317 vap_info->vap_index, mld_info->mld_index);
21318 continue;
21319 }
21320 }
21321 mld_index = mld_ap_test_all_mlds(vap_info->vap_index);
21322
21323 if (mld_index != 0) {
21324 /*transfer*/
21325 wifi_eht_mld_ap_transfer(mld_index, mld_info->mld_index, vap_info->vap_index);
21326
developerb340de62023-11-22 20:10:05 +080021327 if (wifi_eht_get_ap_from_mld(mld_index, ap_index_array, &ap_array_num) != RETURN_OK) {
developer6c6ef372023-11-08 10:59:14 +080021328 wifi_debug(DEBUG_ERROR,
21329 "fail to get all aps from mld(%d), destroy it.\n", mld_index);
21330 continue;
21331 }
21332 if (ap_array_num == 0) {
21333 wifi_debug(DEBUG_ERROR,
21334 "there's no affiliated ap in mld(%d), destroy it.\n", mld_index);
21335 wifi_eht_destroy_ap_mld(mld_index);
21336 }
21337 } else {
21338 /*join*/
21339 wifi_eht_add_to_ap_mld(mld_info->mld_index, vap_info->vap_index);
21340 }
21341 }
21342 }
21343 mld_info_display();
21344 wifi_eht_config_sync2_dat_by_radio(index);
developera3511852023-06-14 14:12:59 +080021345 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
21346 return RETURN_OK;
developer1a454b42023-11-20 18:38:06 +080021347err:
21348 multiple_set = FALSE;
21349 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080021350}
21351
21352int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
21353{
developera3511852023-06-14 14:12:59 +080021354 char *token, *next;
21355 const char s[2] = ",";
21356 int count =0;
developer72fb0bb2023-01-11 09:46:29 +080021357
developera3511852023-06-14 14:12:59 +080021358 /* get the first token */
21359 token = strtok_r(pchannels, s, &next);
developer72fb0bb2023-01-11 09:46:29 +080021360
developera3511852023-06-14 14:12:59 +080021361 /* walk through other tokens */
21362 while( token != NULL && count < MAX_CHANNELS) {
21363 chlistptr->channels_list[count++] = atoi(token);
21364 token = strtok_r(NULL, s, &next);
21365 }
developer72fb0bb2023-01-11 09:46:29 +080021366
developera3511852023-06-14 14:12:59 +080021367 return count;
developer72fb0bb2023-01-11 09:46:29 +080021368}
21369
21370static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
21371{
developera3511852023-06-14 14:12:59 +080021372 INT status;
21373 wifi_channels_list_t *chlistp;
21374 CHAR output_string[64];
21375 CHAR pchannels[128];
21376 CHAR interface_name[16] = {0};
21377 wifi_band band;
developere40952c2023-06-15 18:46:43 +080021378 int res;
developerc3556192023-12-06 17:59:09 +080021379 int main_vap_idx;
developer72fb0bb2023-01-11 09:46:29 +080021380
developera3511852023-06-14 14:12:59 +080021381 if(rcap == NULL)
21382 {
21383 return RETURN_ERR;
21384 }
developer72fb0bb2023-01-11 09:46:29 +080021385
developera3511852023-06-14 14:12:59 +080021386 rcap->numSupportedFreqBand = 1;
developerdfd270b2023-12-12 10:24:30 +080021387 band = radio_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080021388
developera3511852023-06-14 14:12:59 +080021389 if (band == band_2_4)
21390 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
21391 else if (band == band_5)
21392 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
21393 else if (band == band_6)
21394 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
developer72fb0bb2023-01-11 09:46:29 +080021395
developera3511852023-06-14 14:12:59 +080021396 chlistp = &(rcap->channel_list[0]);
21397 memset(pchannels, 0, sizeof(pchannels));
developer72fb0bb2023-01-11 09:46:29 +080021398
developera3511852023-06-14 14:12:59 +080021399 /* possible number of radio channels */
21400 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
21401 {
21402 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
21403 }
21404 /* Number of channels and list*/
21405 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
developer72fb0bb2023-01-11 09:46:29 +080021406
developera3511852023-06-14 14:12:59 +080021407 /* autoChannelSupported */
21408 /* always ON with wifi_getRadioAutoChannelSupported */
21409 rcap->autoChannelSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080021410
developera3511852023-06-14 14:12:59 +080021411 /* DCSSupported */
21412 /* always ON with wifi_getRadioDCSSupported */
21413 rcap->DCSSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080021414
developera3511852023-06-14 14:12:59 +080021415 /* zeroDFSSupported - TBD */
21416 rcap->zeroDFSSupported = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080021417
developera3511852023-06-14 14:12:59 +080021418 /* Supported Country List*/
21419 memset(output_string, 0, sizeof(output_string));
21420 status = wifi_getRadioCountryCode(radioIndex, output_string);
21421 if( status != 0 ) {
21422 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
21423 return RETURN_ERR;
21424 } else {
21425 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
21426 }
21427 if(!strcmp(output_string,"US")){
21428 rcap->countrySupported[0] = wifi_countrycode_US;
21429 rcap->countrySupported[1] = wifi_countrycode_CA;
21430 } else if (!strcmp(output_string,"CA")) {
21431 rcap->countrySupported[0] = wifi_countrycode_CA;
21432 rcap->countrySupported[1] = wifi_countrycode_US;
21433 } else {
21434 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
21435 }
developer72fb0bb2023-01-11 09:46:29 +080021436
developera3511852023-06-14 14:12:59 +080021437 rcap->numcountrySupported = 2;
developer72fb0bb2023-01-11 09:46:29 +080021438
developera3511852023-06-14 14:12:59 +080021439 /* csi */
21440 rcap->csi.maxDevices = 8;
21441 rcap->csi.soudingFrameSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080021442
developerc3556192023-12-06 17:59:09 +080021443 if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
21444 wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
21445 return RETURN_ERR;
21446 }
21447
21448 if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080021449 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
21450 }
developere40952c2023-06-15 18:46:43 +080021451 res = snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
21452 if (os_snprintf_error(sizeof(interface_name), res)) {
21453 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21454 return RETURN_ERR;
21455 }
developer72fb0bb2023-01-11 09:46:29 +080021456
developera3511852023-06-14 14:12:59 +080021457 /* channelWidth - all supported bandwidths */
21458 int i=0;
21459 rcap->channelWidth[i] = 0;
21460 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
21461 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
21462 WIFI_CHANNELBANDWIDTH_40MHZ);
developer72fb0bb2023-01-11 09:46:29 +080021463
developer630fa042023-12-22 15:01:43 +080021464 } else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) {
developera3511852023-06-14 14:12:59 +080021465 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
21466 WIFI_CHANNELBANDWIDTH_40MHZ |
21467 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
developer9e772fb2023-12-04 13:33:42 +080021468 } else if (rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
21469 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
21470 WIFI_CHANNELBANDWIDTH_40MHZ |
21471 WIFI_CHANNELBANDWIDTH_80MHZ |
21472 WIFI_CHANNELBANDWIDTH_160MHZ |
21473 WIFI_CHANNELBANDWIDTH_320MHZ);
developera3511852023-06-14 14:12:59 +080021474 }
developer72fb0bb2023-01-11 09:46:29 +080021475
21476
developera3511852023-06-14 14:12:59 +080021477 /* mode - all supported variants */
21478 // rcap->mode[i] = WIFI_80211_VARIANT_H;
21479 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
developer9e772fb2023-12-04 13:33:42 +080021480 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX | WIFI_80211_VARIANT_BE);
developera3511852023-06-14 14:12:59 +080021481 }
21482 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
developer9e772fb2023-12-04 13:33:42 +080021483 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX | WIFI_80211_VARIANT_BE);
developera3511852023-06-14 14:12:59 +080021484 }
21485 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
developer9e772fb2023-12-04 13:33:42 +080021486 rcap->mode[i] = ( WIFI_80211_VARIANT_AX | WIFI_80211_VARIANT_BE);
developera3511852023-06-14 14:12:59 +080021487 }
21488 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
21489 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
developer72fb0bb2023-01-11 09:46:29 +080021490
developera3511852023-06-14 14:12:59 +080021491 /* supportedBitRate - all supported bitrates */
21492 rcap->supportedBitRate[i] = 0;
21493 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
21494 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
21495 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
21496 }
21497 else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
21498 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
21499 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
21500 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
21501 }
developer72fb0bb2023-01-11 09:46:29 +080021502
21503
developera3511852023-06-14 14:12:59 +080021504 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
21505 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
21506 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
21507 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
21508 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
21509 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
21510 rcap->cipherSupported = 0;
21511 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
developerac5919a2023-12-04 18:18:54 +080021512 rcap->maxNumberVAPs = LOGAN_MAX_NUM_VAP_PER_RADIO;
developer72fb0bb2023-01-11 09:46:29 +080021513
developera3511852023-06-14 14:12:59 +080021514 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021515}
21516
developerac5919a2023-12-04 18:18:54 +080021517
developer72fb0bb2023-01-11 09:46:29 +080021518INT wifi_getHalCapability(wifi_hal_capability_t *cap)
21519{
developerc3556192023-12-06 17:59:09 +080021520 INT status = 0, radioIndex = 0, vap_idx;
developera3511852023-06-14 14:12:59 +080021521 char output[MAX_BUF_SIZE] = {0};
21522 int iter = 0;
21523 unsigned int j = 0;
developer9ce44382023-06-28 11:09:37 +080021524 int max_num_radios = 0;
developera3511852023-06-14 14:12:59 +080021525 wifi_interface_name_idex_map_t *iface_info = NULL;
developer72fb0bb2023-01-11 09:46:29 +080021526
developera3511852023-06-14 14:12:59 +080021527 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021528
developera3511852023-06-14 14:12:59 +080021529 memset(cap, 0, sizeof(wifi_hal_capability_t));
developer72fb0bb2023-01-11 09:46:29 +080021530
developera3511852023-06-14 14:12:59 +080021531 /* version */
21532 cap->version.major = WIFI_HAL_MAJOR_VERSION;
21533 cap->version.minor = WIFI_HAL_MINOR_VERSION;
developer72fb0bb2023-01-11 09:46:29 +080021534
developera3511852023-06-14 14:12:59 +080021535 /* number of radios platform property */
21536 wifi_getMaxRadioNumber(&max_num_radios);
21537 cap->wifi_prop.numRadios = max_num_radios;
developer72fb0bb2023-01-11 09:46:29 +080021538
developera3511852023-06-14 14:12:59 +080021539 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
21540 {
21541 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
21542 if (status != 0) {
21543 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
21544 return RETURN_ERR;
21545 }
developer72fb0bb2023-01-11 09:46:29 +080021546
developera3511852023-06-14 14:12:59 +080021547 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
21548 {
developercd0b70a2023-12-11 11:25:50 +080021549 if (iter >= (get_runtime_max_radio() * MAX_NUM_VAP_PER_RADIO))
developera3511852023-06-14 14:12:59 +080021550 {
21551 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
21552 return RETURN_ERR;
21553 }
21554 iface_info = &cap->wifi_prop.interface_map[iter];
21555 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
21556 iface_info->rdk_radio_index = radioIndex;
developerac5919a2023-12-04 18:18:54 +080021557
developerc3556192023-12-06 17:59:09 +080021558 if (array_index_to_vap_index(radioIndex, j, &vap_idx) != RETURN_OK) {
21559 wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, j %d\n", radioIndex, j);
21560 continue;
21561 }
21562
21563 iface_info->index = vap_idx;
developerac5919a2023-12-04 18:18:54 +080021564
21565 if (wifi_GetInterfaceName(iface_info->index, output))
developera3511852023-06-14 14:12:59 +080021566 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
developerac5919a2023-12-04 18:18:54 +080021567
21568 getVapBridge(iface_info->index, iface_info->bridge_name, sizeof(iface_info->bridge_name));
developera3511852023-06-14 14:12:59 +080021569 // TODO: vlan id
21570 // TODO: primary
developera3511852023-06-14 14:12:59 +080021571 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
developera3511852023-06-14 14:12:59 +080021572 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
developerac5919a2023-12-04 18:18:54 +080021573
21574 iter++;
developera3511852023-06-14 14:12:59 +080021575 }
21576 }
developer72fb0bb2023-01-11 09:46:29 +080021577
developera3511852023-06-14 14:12:59 +080021578 cap->BandSteeringSupported = FALSE;
developerac5919a2023-12-04 18:18:54 +080021579
21580 memcpy(&g_hal_cap, cap, sizeof(g_hal_cap));
21581
developera3511852023-06-14 14:12:59 +080021582 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
21583 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021584}
21585
21586INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
21587{
developera3511852023-06-14 14:12:59 +080021588 struct params h_config={0};
21589 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080021590 int res;
developer72fb0bb2023-01-11 09:46:29 +080021591
developera3511852023-06-14 14:12:59 +080021592 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021593
developera3511852023-06-14 14:12:59 +080021594 h_config.name = "okc";
21595 h_config.value = okc_enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080021596
developere40952c2023-06-15 18:46:43 +080021597 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21598 if (os_snprintf_error(sizeof(config_file), res)) {
21599 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21600 return RETURN_ERR;
21601 }
developera3511852023-06-14 14:12:59 +080021602 wifi_hostapdWrite(config_file, &h_config, 1);
21603 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080021604
developera3511852023-06-14 14:12:59 +080021605 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
21606 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021607}
21608
21609INT wifi_setSAEMFP(int ap_index, BOOL enable)
21610{
developera3511852023-06-14 14:12:59 +080021611 struct params h_config={0};
21612 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080021613 int res;
developer72fb0bb2023-01-11 09:46:29 +080021614
developera3511852023-06-14 14:12:59 +080021615 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021616
developera3511852023-06-14 14:12:59 +080021617 h_config.name = "sae_require_mfp";
21618 h_config.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080021619
developere40952c2023-06-15 18:46:43 +080021620 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21621 if (os_snprintf_error(sizeof(config_file), res)) {
21622 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21623 return RETURN_ERR;
21624 }
developera3511852023-06-14 14:12:59 +080021625 wifi_hostapdWrite(config_file, &h_config, 1);
21626 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080021627
developera3511852023-06-14 14:12:59 +080021628 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
21629 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021630}
21631
21632INT wifi_setSAEpwe(int ap_index, int sae_pwe)
21633{
developera3511852023-06-14 14:12:59 +080021634 struct params h_config={0};
21635 char config_file[64] = {0};
21636 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080021637 int res;
developer72fb0bb2023-01-11 09:46:29 +080021638
developera3511852023-06-14 14:12:59 +080021639 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021640
developera3511852023-06-14 14:12:59 +080021641 h_config.name = "sae_pwe";
developere40952c2023-06-15 18:46:43 +080021642 res = snprintf(buf, sizeof(buf), "%d", sae_pwe);
21643 if (os_snprintf_error(sizeof(buf), res)) {
21644 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21645 return RETURN_ERR;
21646 }
21647
developera3511852023-06-14 14:12:59 +080021648 h_config.value = buf;
developer72fb0bb2023-01-11 09:46:29 +080021649
developere40952c2023-06-15 18:46:43 +080021650 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21651 if (os_snprintf_error(sizeof(config_file), res)) {
21652 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21653 return RETURN_ERR;
21654 }
developera3511852023-06-14 14:12:59 +080021655 wifi_hostapdWrite(config_file, &h_config, 1);
21656 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080021657
developera3511852023-06-14 14:12:59 +080021658 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
21659 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021660}
21661
21662INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
21663{
developera3511852023-06-14 14:12:59 +080021664 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
21665 struct params h_config={0};
21666 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080021667 int res;
developer72fb0bb2023-01-11 09:46:29 +080021668
developera3511852023-06-14 14:12:59 +080021669 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021670
developera3511852023-06-14 14:12:59 +080021671 h_config.name = "wpa_disable_eapol_key_retries";
21672 h_config.value = disable_EAPOL_retries?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080021673
developere40952c2023-06-15 18:46:43 +080021674 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21675 if (os_snprintf_error(sizeof(config_file), res)) {
21676 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21677 return RETURN_ERR;
21678 }
developera3511852023-06-14 14:12:59 +080021679 wifi_hostapdWrite(config_file, &h_config, 1);
21680 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080021681
developera3511852023-06-14 14:12:59 +080021682 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
21683 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021684}
21685
21686INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
21687{
developera3511852023-06-14 14:12:59 +080021688 char buf[128] = {0};
21689 char config_file[128] = {0};
developer8078acf2023-08-04 18:52:48 +080021690
developera3511852023-06-14 14:12:59 +080021691 char password[65] = {0};
21692 char mfp[32] = {0};
21693 char wpa_mode[32] = {0};
21694 BOOL okc_enable = FALSE;
21695 BOOL sae_MFP = FALSE;
21696 BOOL disable_EAPOL_retries = TRUE;
21697 int sae_pwe = 0;
21698 struct params params = {0};
21699 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080021700 int res;
developer72fb0bb2023-01-11 09:46:29 +080021701
developera3511852023-06-14 14:12:59 +080021702 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021703
developer37646972023-06-29 10:58:43 +080021704 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21705 if (os_snprintf_error(sizeof(config_file), res)) {
21706 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21707 return RETURN_ERR;
21708 }
developera3511852023-06-14 14:12:59 +080021709 if (security->mode == wifi_security_mode_none) {
developer9ce44382023-06-28 11:09:37 +080021710 strncpy(wpa_mode, "None",sizeof(wpa_mode) - 1);
21711 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21712 } else if (security->mode == wifi_security_mode_wpa_personal) {
21713 strncpy(wpa_mode, "WPA-Personal",sizeof(wpa_mode) - 1);
21714 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21715 } else if (security->mode == wifi_security_mode_wpa2_personal){
21716 strncpy(wpa_mode, "WPA2-Personal",sizeof(wpa_mode) - 1);
21717 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21718 } else if (security->mode == wifi_security_mode_wpa_wpa2_personal){
21719 strncpy(wpa_mode, "WPA-WPA2-Personal",sizeof(wpa_mode) - 1);
21720 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21721 } else if (security->mode == wifi_security_mode_wpa_enterprise){
21722 strncpy(wpa_mode, "WPA-Enterprise",sizeof(wpa_mode) - 1);
21723 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21724 } else if (security->mode == wifi_security_mode_wpa2_enterprise){
21725 strncpy(wpa_mode, "WPA2-Enterprise",sizeof(wpa_mode) - 1);
21726 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21727 } else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise){
21728 strncpy(wpa_mode, "WPA-WAP2-Enterprise",sizeof(wpa_mode) - 1);
21729 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
21730 } else if (security->mode == wifi_security_mode_wpa3_personal) {
21731 strncpy(wpa_mode, "WPA3-Personal",sizeof(wpa_mode) - 1);
21732 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080021733 okc_enable = TRUE;
21734 sae_MFP = TRUE;
21735 sae_pwe = 2;
21736 disable_EAPOL_retries = FALSE;
21737 } else if (security->mode == wifi_security_mode_wpa3_transition) {
developer9ce44382023-06-28 11:09:37 +080021738 strncpy(wpa_mode, "WPA3-Personal-Transition",sizeof(wpa_mode) - 1);
21739 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080021740 okc_enable = TRUE;
21741 sae_MFP = TRUE;
21742 sae_pwe = 2;
21743 disable_EAPOL_retries = FALSE;
21744 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
developer9ce44382023-06-28 11:09:37 +080021745 strncpy(wpa_mode, "WPA3-Enterprise",sizeof(wpa_mode) - 1);
21746 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080021747 sae_MFP = TRUE;
21748 sae_pwe = 2;
21749 disable_EAPOL_retries = FALSE;
21750 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer9ce44382023-06-28 11:09:37 +080021751 strncpy(wpa_mode, "OWE",sizeof(wpa_mode) - 1);
21752 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080021753 sae_MFP = TRUE;
21754 sae_pwe = 2;
21755 disable_EAPOL_retries = FALSE;
21756 }
developer72fb0bb2023-01-11 09:46:29 +080021757
developera3511852023-06-14 14:12:59 +080021758 band = wifi_index_to_band(ap_index);
21759 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
developerc14d83a2023-06-29 20:09:42 +080021760 wifi_debug(DEBUG_ERROR, "%s: 6G band must set with wpa3.\n", __func__);
developera3511852023-06-14 14:12:59 +080021761 return RETURN_ERR;
21762 }
developer72fb0bb2023-01-11 09:46:29 +080021763
developera3511852023-06-14 14:12:59 +080021764 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
21765 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
21766 wifi_setSAEMFP(ap_index, sae_MFP);
21767 wifi_setSAEpwe(ap_index, sae_pwe);
21768 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
developer72fb0bb2023-01-11 09:46:29 +080021769
developera3511852023-06-14 14:12:59 +080021770 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
developer2b772ec2023-12-07 19:04:58 +080021771 if (security->u.key.type == wifi_security_key_type_psk || security->u.key.type == wifi_security_key_type_pass
21772 || security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
developera3511852023-06-14 14:12:59 +080021773 int key_len = strlen(security->u.key.key);
21774 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
21775 if (key_len == 64) { // set wpa_psk
21776 strncpy(password, security->u.key.key, 64); // 64 characters
21777 password[64] = '\0';
21778 wifi_setApSecurityPreSharedKey(ap_index, password);
developer8078acf2023-08-04 18:52:48 +080021779 res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
21780 if (res) {
21781 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21782
developere40952c2023-06-15 18:46:43 +080021783 }
developera3511852023-06-14 14:12:59 +080021784 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
21785 strncpy(password, security->u.key.key, 63);
21786 password[63] = '\0';
21787 wifi_setApSecurityKeyPassphrase(ap_index, password);
developer8078acf2023-08-04 18:52:48 +080021788 res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
21789 if (res) {
21790 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21791
developer9ce44382023-06-28 11:09:37 +080021792 }
developera3511852023-06-14 14:12:59 +080021793 } else
21794 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080021795
developera3511852023-06-14 14:12:59 +080021796 }
21797 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
21798 params.name = "sae_password";
21799 params.value = security->u.key.key;
21800 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021801 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developera3511852023-06-14 14:12:59 +080021802 } else { // remove sae_password
developer8078acf2023-08-04 18:52:48 +080021803 res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
21804 if (res) {
21805 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
21806
developere40952c2023-06-15 18:46:43 +080021807 }
developera3511852023-06-14 14:12:59 +080021808 }
21809 }
developer72fb0bb2023-01-11 09:46:29 +080021810
developera3511852023-06-14 14:12:59 +080021811 if (security->mode != wifi_security_mode_none) {
21812 memset(&params, 0, sizeof(params));
21813 params.name = "wpa_pairwise";
21814 if (security->encr == wifi_encryption_tkip)
21815 params.value = "TKIP";
21816 else if (security->encr == wifi_encryption_aes)
21817 params.value = "CCMP";
21818 else if (security->encr == wifi_encryption_aes_tkip)
21819 params.value = "TKIP CCMP";
21820 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021821 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developer2b772ec2023-12-07 19:04:58 +080021822
21823 /* rsn_pairwise need to be updated too */
21824 params.name = "rsn_pairwise";
21825 wifi_hostapdWrite(config_file, &params, 1);
21826 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developera3511852023-06-14 14:12:59 +080021827 }
developer72fb0bb2023-01-11 09:46:29 +080021828
developer9ce44382023-06-28 11:09:37 +080021829 if (security->mfp == wifi_mfp_cfg_disabled){
21830 strncpy(mfp,"Disabled",sizeof(mfp)-1);
21831 mfp[sizeof(mfp)-1] = '\0';
21832 } else if (security->mfp == wifi_mfp_cfg_optional){
21833 strncpy(mfp,"Optional",sizeof(mfp)-1);
21834 mfp[sizeof(mfp)-1] = '\0';
21835 } else if (security->mfp == wifi_mfp_cfg_required){
21836 strncpy(mfp,"Required",sizeof(mfp)-1);
21837 mfp[sizeof(mfp)-1] = '\0';
21838 }
developera3511852023-06-14 14:12:59 +080021839 wifi_setApSecurityMFPConfig(ap_index, mfp);
developer72fb0bb2023-01-11 09:46:29 +080021840
developera3511852023-06-14 14:12:59 +080021841 memset(&params, 0, sizeof(params));
21842 params.name = "transition_disable";
21843 if (security->wpa3_transition_disable == TRUE)
21844 params.value = "0x01";
21845 else
21846 params.value = "0x00";
21847 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021848 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080021849
developera3511852023-06-14 14:12:59 +080021850 memset(&params, 0, sizeof(params));
21851 params.name = "wpa_group_rekey";
developere40952c2023-06-15 18:46:43 +080021852 res = snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
21853 if (os_snprintf_error(sizeof(buf), res)) {
21854 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21855 return RETURN_ERR;
21856 }
developera3511852023-06-14 14:12:59 +080021857 params.value = buf;
21858 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021859 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080021860
developera3511852023-06-14 14:12:59 +080021861 memset(&params, 0, sizeof(params));
21862 params.name = "wpa_strict_rekey";
21863 params.value = security->strict_rekey?"1":"0";
21864 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021865 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080021866
developera3511852023-06-14 14:12:59 +080021867 memset(&params, 0, sizeof(params));
21868 params.name = "wpa_pairwise_update_count";
21869 if (security->eapol_key_retries == 0)
21870 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developere40952c2023-06-15 18:46:43 +080021871 res = snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
21872 if (os_snprintf_error(sizeof(buf), res)) {
21873 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21874 return RETURN_ERR;
21875 }
developera3511852023-06-14 14:12:59 +080021876 params.value = buf;
21877 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021878 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080021879
developera3511852023-06-14 14:12:59 +080021880 memset(&params, 0, sizeof(params));
21881 params.name = "disable_pmksa_caching";
21882 params.value = security->disable_pmksa_caching?"1":"0";
21883 wifi_hostapdWrite(config_file, &params, 1);
developer1a454b42023-11-20 18:38:06 +080021884 wifi_hostapdProcessUpdate(ap_index, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080021885
developera3511852023-06-14 14:12:59 +080021886 if (multiple_set == FALSE) {
21887 wifi_setApEnable(ap_index, FALSE);
21888 wifi_setApEnable(ap_index, TRUE);
21889 }
developer72fb0bb2023-01-11 09:46:29 +080021890
developera3511852023-06-14 14:12:59 +080021891 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080021892
developera3511852023-06-14 14:12:59 +080021893 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080021894}
21895
21896INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
21897{
developera3511852023-06-14 14:12:59 +080021898 char buf[256] = {0};
21899 char config_file[128] = {0};
developer86035662023-06-28 19:21:12 +080021900 long int disable = 0;
21901 long int tmp;
developera3511852023-06-14 14:12:59 +080021902 bool set_sae = FALSE;
developere75ba632023-06-29 16:03:33 +080021903 int res;
developer7afe45d2023-12-15 17:45:51 +080021904 wifi_encryption_method_t wpa_pairwise = 0, rsn_pairwise = 0;
developer72fb0bb2023-01-11 09:46:29 +080021905
developera3511852023-06-14 14:12:59 +080021906 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere75ba632023-06-29 16:03:33 +080021907 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
21908 if (os_snprintf_error(sizeof(config_file), res)) {
21909 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
21910 return RETURN_ERR;
21911 }
developera3511852023-06-14 14:12:59 +080021912 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
21913 security->mode = wifi_security_mode_none;
21914 if (strlen(buf) != 0) {
21915 if (!strcmp(buf, "WPA-Personal"))
21916 security->mode = wifi_security_mode_wpa_personal;
21917 else if (!strcmp(buf, "WPA2-Personal"))
21918 security->mode = wifi_security_mode_wpa2_personal;
21919 else if (!strcmp(buf, "WPA-WPA2-Personal"))
21920 security->mode = wifi_security_mode_wpa_wpa2_personal;
21921 else if (!strcmp(buf, "WPA-Enterprise"))
21922 security->mode = wifi_security_mode_wpa_enterprise;
21923 else if (!strcmp(buf, "WPA2-Enterprise"))
21924 security->mode = wifi_security_mode_wpa2_enterprise;
21925 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
21926 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
21927 else if (!strcmp(buf, "WPA3-Personal"))
21928 security->mode = wifi_security_mode_wpa3_personal;
21929 else if (!strcmp(buf, "WPA3-Personal-Transition"))
21930 security->mode = wifi_security_mode_wpa3_transition;
21931 else if (!strcmp(buf, "WPA3-Enterprise"))
21932 security->mode = wifi_security_mode_wpa3_enterprise;
21933 else if (!strcmp(buf, "OWE"))
21934 security->mode = wifi_security_mode_enhanced_open;
21935 }
developer72fb0bb2023-01-11 09:46:29 +080021936
developera3511852023-06-14 14:12:59 +080021937 if (security->mode == wifi_security_mode_none)
21938 security->encr = wifi_encryption_none;
21939 else {
developer7afe45d2023-12-15 17:45:51 +080021940 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
21941 if (strlen(buf) > 0) {
21942 if (strcmp(buf, "TKIP") == 0)
21943 wpa_pairwise = wifi_encryption_tkip;
21944 else if (strcmp(buf, "CCMP") == 0)
21945 wpa_pairwise = wifi_encryption_aes;
21946 else
21947 wpa_pairwise = wifi_encryption_aes_tkip;
21948 }
21949
21950 wifi_hostapdRead(config_file,"rsn_pairwise",buf,sizeof(buf));
21951 if (strlen(buf) > 0) {
21952 if (strcmp(buf, "TKIP") == 0)
21953 rsn_pairwise = wifi_encryption_tkip;
21954 else if (strcmp(buf, "CCMP") == 0)
21955 rsn_pairwise = wifi_encryption_aes;
21956 else
21957 rsn_pairwise = wifi_encryption_aes_tkip;
21958 }
21959
21960 security->encr = wpa_pairwise | rsn_pairwise;
developera3511852023-06-14 14:12:59 +080021961 }
developer72fb0bb2023-01-11 09:46:29 +080021962
developera3511852023-06-14 14:12:59 +080021963 if (security->mode != wifi_security_mode_none) {
21964 memset(buf, 0, sizeof(buf));
21965 // wpa3 can use one or both configs as password, so we check sae_password first.
21966 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
21967 if (strlen(buf) != 0) {
21968 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
21969 security->u.key.type = wifi_security_key_type_sae;
21970 set_sae = TRUE;
21971 strncpy(security->u.key.key, buf, sizeof(buf));
21972 }
21973 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
21974 if (strlen(buf) != 0){
21975 if (set_sae == TRUE)
21976 security->u.key.type = wifi_security_key_type_psk_sae;
21977 else if (strlen(buf) == 64)
21978 security->u.key.type = wifi_security_key_type_psk;
21979 else
21980 security->u.key.type = wifi_security_key_type_pass;
21981 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
21982 }
21983 security->u.key.key[255] = '\0';
21984 }
developer72fb0bb2023-01-11 09:46:29 +080021985
developera3511852023-06-14 14:12:59 +080021986 memset(buf, 0, sizeof(buf));
21987 wifi_getApSecurityMFPConfig(ap_index, buf);
21988 if (strcmp(buf, "Disabled") == 0)
21989 security->mfp = wifi_mfp_cfg_disabled;
21990 else if (strcmp(buf, "Optional") == 0)
21991 security->mfp = wifi_mfp_cfg_optional;
21992 else if (strcmp(buf, "Required") == 0)
21993 security->mfp = wifi_mfp_cfg_required;
developer72fb0bb2023-01-11 09:46:29 +080021994
developera3511852023-06-14 14:12:59 +080021995 memset(buf, 0, sizeof(buf));
21996 security->wpa3_transition_disable = FALSE;
21997 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
developer3de255a2023-06-29 10:35:45 +080021998 if (strlen(buf) == 0)
21999 disable = 0;
22000 else {
22001 if (hal_strtol(buf, 16, &disable) < 0) {
22002 wifi_debug(DEBUG_ERROR, "strtol fail\n");
22003 return RETURN_ERR;
22004 }
developer86035662023-06-28 19:21:12 +080022005 }
developera3511852023-06-14 14:12:59 +080022006 if (disable != 0)
22007 security->wpa3_transition_disable = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080022008
developera3511852023-06-14 14:12:59 +080022009 memset(buf, 0, sizeof(buf));
22010 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
22011 if (strlen(buf) == 0)
22012 security->rekey_interval = 86400;
developer86035662023-06-28 19:21:12 +080022013 else {
22014 if (hal_strtol(buf, 10, &tmp) < 0) {
22015 wifi_debug(DEBUG_ERROR, "strtol fail\n");
22016 return RETURN_ERR;
22017 }
22018 security->rekey_interval = tmp;
22019 }
developer72fb0bb2023-01-11 09:46:29 +080022020
developera3511852023-06-14 14:12:59 +080022021 memset(buf, 0, sizeof(buf));
22022 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
22023 if (strlen(buf) == 0)
22024 security->strict_rekey = 1;
developer86035662023-06-28 19:21:12 +080022025 else {
22026 if (hal_strtol(buf, 10, &tmp) < 0) {
22027 wifi_debug(DEBUG_ERROR, "strtol fail\n");
22028 return RETURN_ERR;
22029 }
22030 security->strict_rekey = tmp;
22031 }
developer72fb0bb2023-01-11 09:46:29 +080022032
developera3511852023-06-14 14:12:59 +080022033 memset(buf, 0, sizeof(buf));
22034 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
22035 if (strlen(buf) == 0)
22036 security->eapol_key_retries = 4;
developer86035662023-06-28 19:21:12 +080022037 else {
22038 if (hal_strtol(buf, 10, &tmp) < 0) {
22039 wifi_debug(DEBUG_ERROR, "strtol fail\n");
22040 return RETURN_ERR;
22041 }
22042 security->eapol_key_retries = tmp;
22043 }
developer72fb0bb2023-01-11 09:46:29 +080022044
developera3511852023-06-14 14:12:59 +080022045 memset(buf, 0, sizeof(buf));
22046 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
22047 if (strlen(buf) == 0)
22048 security->disable_pmksa_caching = FALSE;
developer86035662023-06-28 19:21:12 +080022049 else {
22050 if (hal_strtol(buf, 10, &(tmp)) < 0) {
22051 wifi_debug(DEBUG_ERROR, "strtol fail\n");
22052 return RETURN_ERR;
22053 }
22054 security->disable_pmksa_caching = tmp ? TRUE : FALSE;
22055 }
developera3511852023-06-14 14:12:59 +080022056 /* TODO
22057 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
22058 */
22059 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
22060 security->eap_identity_req_timeout = 0;
22061 security->eap_identity_req_retries = 0;
22062 security->eap_req_timeout = 0;
22063 security->eap_req_retries = 0;
22064 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
22065 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022066}
22067
22068#endif /* WIFI_HAL_VERSION_3 */
22069
22070#ifdef WIFI_HAL_VERSION_3_PHASE2
22071INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
22072{
developera3511852023-06-14 14:12:59 +080022073 char interface_name[16] = {0};
developer8078acf2023-08-04 18:52:48 +080022074
developera3511852023-06-14 14:12:59 +080022075 char buf[128] = {0};
22076 char *mac_addr = NULL;
22077 BOOL status = FALSE;
22078 size_t len = 0;
developer8078acf2023-08-04 18:52:48 +080022079 int res;
developer72fb0bb2023-01-11 09:46:29 +080022080
developera3511852023-06-14 14:12:59 +080022081 if(ap_index > MAX_APS)
22082 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080022083
developera3511852023-06-14 14:12:59 +080022084 *output_numDevices = 0;
22085 wifi_getApEnable(ap_index, &status);
22086 if (status == FALSE)
22087 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022088
developera3511852023-06-14 14:12:59 +080022089 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
22090 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080022091
22092 _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s list_sta", interface_name);
22093 if (res) {
22094 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
22095 }
developer72fb0bb2023-01-11 09:46:29 +080022096
developera3511852023-06-14 14:12:59 +080022097 mac_addr = strtok(buf, "\n");
22098 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
22099 *output_numDevices = i + 1;
developerc14d83a2023-06-29 20:09:42 +080022100 wifi_debug(DEBUG_ERROR,, "mac_addr: %s\n", mac_addr);
developera3511852023-06-14 14:12:59 +080022101 addr_ptr = output_deviceMacAddressArray[i];
22102 mac_addr_aton(addr_ptr, mac_addr);
22103 mac_addr = strtok(NULL, "\n");
22104 }
developer72fb0bb2023-01-11 09:46:29 +080022105
developera3511852023-06-14 14:12:59 +080022106 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022107}
22108#else
22109INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
22110{
developera3511852023-06-14 14:12:59 +080022111 char interface_name[16] = {0};
developer8078acf2023-08-04 18:52:48 +080022112
developera3511852023-06-14 14:12:59 +080022113 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +080022114 int res;
developer72fb0bb2023-01-11 09:46:29 +080022115
developera3511852023-06-14 14:12:59 +080022116 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
22117 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080022118
developera3511852023-06-14 14:12:59 +080022119 output_buf[0] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080022120
developera3511852023-06-14 14:12:59 +080022121 wifi_getApEnable(ap_index,&status);
22122 if (!status)
22123 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022124
developera3511852023-06-14 14:12:59 +080022125 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
22126 return RETURN_ERR;
developer8078acf2023-08-04 18:52:48 +080022127 res = _syscmd_secure(output_buf, output_buf_size, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
22128 if (res) {
22129 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
22130
developer75bd10c2023-06-27 11:34:08 +080022131 }
developer5b23cd02023-07-19 20:26:03 +080022132
developer8078acf2023-08-04 18:52:48 +080022133
developer69b61b02023-03-07 17:17:44 +080022134
developera3511852023-06-14 14:12:59 +080022135 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022136}
22137#endif
22138
22139INT wifi_getProxyArp(INT apIndex, BOOL *enable)
22140{
developera3511852023-06-14 14:12:59 +080022141 char output[16]={'\0'};
22142 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080022143 int res;
developer72fb0bb2023-01-11 09:46:29 +080022144
developera3511852023-06-14 14:12:59 +080022145 if (!enable)
22146 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080022147
developer75bd10c2023-06-27 11:34:08 +080022148 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
22149 if (os_snprintf_error(sizeof(config_file), res)) {
22150 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
22151 return RETURN_ERR;
22152 }
developera3511852023-06-14 14:12:59 +080022153 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080022154
developera3511852023-06-14 14:12:59 +080022155 if (strlen(output) == 0)
22156 *enable = FALSE;
22157 else if (strncmp(output, "1", 1) == 0)
22158 *enable = TRUE;
22159 else
22160 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080022161
developera3511852023-06-14 14:12:59 +080022162 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
22163 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022164}
22165
22166INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
22167{
developercd0b70a2023-12-11 11:25:50 +080022168 if (NULL == output_enable || radioIndex >= get_runtime_max_radio())
developera3511852023-06-14 14:12:59 +080022169 return RETURN_ERR;
22170 *output_enable=TRUE;
22171 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022172}
22173
22174INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
22175{
developera3511852023-06-14 14:12:59 +080022176 char cmd[128] = {0};
22177 char buf[128] = {0};
22178 char line[128] = {0};
22179 FILE *f = NULL;
developerc3556192023-12-06 17:59:09 +080022180 int index = 0, bss_idx;
developera3511852023-06-14 14:12:59 +080022181 int exp = 0;
22182 int mantissa = 0;
22183 int duration = 0;
22184 int radio_index = 0;
developera3511852023-06-14 14:12:59 +080022185 uint twt_wake_interval = 0;
22186 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +080022187 int res;
developerc14d83a2023-06-29 20:09:42 +080022188 unsigned long tmp_u, tmp_l;
developer75bd10c2023-06-27 11:34:08 +080022189
developera3511852023-06-14 14:12:59 +080022190 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080022191
developerc3556192023-12-06 17:59:09 +080022192 if (vap_index_to_radio_array_index(ap_index, &radio_index, &bss_idx)!= RETURN_OK) {
22193 wifi_debug(DEBUG_ERROR, "invalid ap_index[%d]\n", ap_index);
developer9ce44382023-06-28 11:09:37 +080022194 return RETURN_ERR;
22195 }
developera3511852023-06-14 14:12:59 +080022196 phyId = radio_index_to_phy(radio_index);
developer75bd10c2023-06-27 11:34:08 +080022197
developer8078acf2023-08-04 18:52:48 +080022198 res = _syscmd_secure(buf, sizeof(buf),"cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
22199 if (res) {
22200 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
22201
developer75bd10c2023-06-27 11:34:08 +080022202 }
developer8078acf2023-08-04 18:52:48 +080022203
developerc14d83a2023-06-29 20:09:42 +080022204 if (hal_strtoul(buf, 10, &tmp_u) < 0) {
22205 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080022206 }
22207 *numSessionReturned = tmp_u - 1;
developer5b23cd02023-07-19 20:26:03 +080022208
developera3511852023-06-14 14:12:59 +080022209 if (*numSessionReturned > maxNumberSessions)
22210 *numSessionReturned = maxNumberSessions;
22211 else if (*numSessionReturned < 1) {
22212 *numSessionReturned = 0;
22213 return RETURN_OK;
22214 }
developer72fb0bb2023-01-11 09:46:29 +080022215
developer75bd10c2023-06-27 11:34:08 +080022216 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
22217 if (os_snprintf_error(sizeof(cmd), res)) {
22218 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
22219 return RETURN_ERR;
22220 }
developer8078acf2023-08-04 18:52:48 +080022221 f = v_secure_popen("r", "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
22222 if (f == NULL) {
22223 wifi_dbg_printf("%s: v_secure_popen %s error\n", __func__, cmd);
developera3511852023-06-14 14:12:59 +080022224 return RETURN_ERR;
22225 }
developer72fb0bb2023-01-11 09:46:29 +080022226
developera3511852023-06-14 14:12:59 +080022227 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
22228 while((fgets(line, sizeof(line), f)) != NULL) {
22229 char *tmp = NULL;
developer9ce44382023-06-28 11:09:37 +080022230 size_t len = strlen(line);
22231 strncpy(buf, line,len);
22232 buf[len] = '\0';
developera3511852023-06-14 14:12:59 +080022233 tmp = strtok(buf, " ");
developerd14dff12023-06-28 22:47:44 +080022234 if (tmp == NULL)
22235 break;
developer5b23cd02023-07-19 20:26:03 +080022236
developerc14d83a2023-06-29 20:09:42 +080022237 if (hal_strtoul(tmp, 10, &tmp_u) < 0) {
22238 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
22239 }
22240 twtSessions[index].numDevicesInSession = tmp_u;
developera3511852023-06-14 14:12:59 +080022241 tmp = strtok(NULL, " ");
developerd14dff12023-06-28 22:47:44 +080022242 if (tmp == NULL)
22243 break;
developer5b23cd02023-07-19 20:26:03 +080022244
developerc14d83a2023-06-29 20:09:42 +080022245 if (hal_strtoul(tmp, 10, &tmp_u) < 0) {
22246 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
22247 }
22248 twtSessions[index].twtParameters.operation.flowID = tmp_u;
developera3511852023-06-14 14:12:59 +080022249 tmp = strtok(NULL, " ");
22250 if (strstr(tmp, "t")) {
22251 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
22252 }
22253 if (strstr(tmp, "a")) {
22254 twtSessions[index].twtParameters.operation.announced = TRUE;
22255 }
22256 tmp = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080022257 if (tmp == NULL)
22258 continue;
developer5b23cd02023-07-19 20:26:03 +080022259
developerc14d83a2023-06-29 20:09:42 +080022260 if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
22261 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
22262 }
22263 exp = tmp_l;
developer5b23cd02023-07-19 20:26:03 +080022264
developera3511852023-06-14 14:12:59 +080022265 tmp = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080022266 if (tmp == NULL)
22267 continue;
developerc14d83a2023-06-29 20:09:42 +080022268 if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
22269 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080022270 }
22271 mantissa = tmp_l;
developer5b23cd02023-07-19 20:26:03 +080022272
developera3511852023-06-14 14:12:59 +080022273 tmp = strtok(NULL, " ");
developerc14d83a2023-06-29 20:09:42 +080022274
22275 if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
22276 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
developerc14d83a2023-06-29 20:09:42 +080022277 }
22278 duration = tmp_l;
developer72fb0bb2023-01-11 09:46:29 +080022279
developera3511852023-06-14 14:12:59 +080022280 // only implicit supported
22281 twtSessions[index].twtParameters.operation.implicit = TRUE;
22282 // only individual agreement supported
22283 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
developer72fb0bb2023-01-11 09:46:29 +080022284
developera3511852023-06-14 14:12:59 +080022285 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
22286 twt_wake_interval = mantissa * (1 << exp);
22287 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
22288 // Overflow handling
22289 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
22290 } else {
22291 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
22292 }
22293 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
22294 index++;
22295 }
developer72fb0bb2023-01-11 09:46:29 +080022296
developer8078acf2023-08-04 18:52:48 +080022297 v_secure_pclose(f);
developera3511852023-06-14 14:12:59 +080022298 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
22299 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080022300}
developercc5cbfb2023-06-13 18:29:52 +080022301
22302INT wifi_enableGreylistAccessControl(BOOL enable)
22303{
22304 char inf_name[IFNAMSIZ] = {0};
22305 int if_idx, ret = 0;
22306 struct nl_msg *msg = NULL;
22307 struct nlattr * msg_data = NULL;
22308 struct mtk_nl80211_param param;
22309 struct unl unl_ins;
22310 unsigned short apIndex = 0;
22311
22312 for (apIndex = 0; apIndex < MAX_APS; apIndex++) {
22313 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
22314 continue;
22315
22316 if_idx = if_nametoindex(inf_name);
22317 if (!if_idx) {
22318 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
22319 continue;
22320 }
22321
22322 /*init mtk nl80211 vendor cmd*/
22323 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
22324 param.if_type = NL80211_ATTR_IFINDEX;
22325 param.if_idx = if_idx;
22326 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
22327 if (ret) {
22328 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
22329 return RETURN_ERR;
22330 }
22331
22332 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, enable == FALSE ? 0 : 1)) {
22333 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
22334 nlmsg_free(msg);
22335 mtk_nl80211_deint(&unl_ins);
22336 continue;
22337 }
22338
22339 /*send mtk nl80211 vendor msg*/
22340 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
22341 if (ret) {
22342 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
22343 mtk_nl80211_deint(&unl_ins);
22344 continue;
22345 }
22346 /*deinit mtk nl80211 vendor msg*/
22347 mtk_nl80211_deint(&unl_ins);
22348 wifi_debug(DEBUG_NOTICE, " %s cmd success.\n", inf_name);
22349 }
22350
22351 return RETURN_OK;
22352}
developerda25c112023-11-21 15:35:26 +080022353
22354// Output string is Disabled, Requested, Failed or Success. max 32 characters
22355INT wifi_getApWpsLastConnectionStatus(INT apIndex, CHAR *output_string)
22356{
22357 char interface_name[IF_NAME_SIZE] = {0};
22358 char buf[MAX_BUF_SIZE] = {0};
22359 int res;
22360
22361 if ((!output_string) || (apIndex < 0) || (apIndex >= MAX_APS))
22362 return RETURN_ERR;
22363
22364 if ((apIndex < 0) && (apIndex >= MAX_APS))
22365 return RETURN_ERR;
22366
22367 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
22368 return RETURN_ERR;
22369
22370 if (strlen(interface_name) == 0)
22371 return RETURN_ERR;
22372
22373 res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s wps_get_status", interface_name);
22374 if (res) {
22375 wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
22376 return RETURN_ERR;
22377 }
22378
22379 if (strstr(buf, "PBC Status: Active")) {
22380 res = snprintf(output_string, 32, "%s", "Requested");
22381 } else if(strstr(buf, "PBC Status: Disabled")) {
developer0f5b79f2023-12-14 17:44:28 +080022382 res = snprintf(output_string, 32, "%s", "Success");
developerda25c112023-11-21 15:35:26 +080022383 } else
22384 res = snprintf(output_string, 32, "%s", "Failed");
22385
22386 if (os_snprintf_error(32, res)) {
22387 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
22388 return RETURN_ERR;
22389 }
22390
22391 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
22392 return RETURN_OK;
22393}
22394