blob: ffc7a95af34a4f96905dab87d20a040351d55e3d [file] [log] [blame]
developer72fb0bb2023-01-11 09:46:29 +08001/*
2 * If not stated otherwise in this file or this component's LICENSE file the
3 * following copyright and licenses apply:
4 *
5 * Copyright 2019 RDK Management
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18*/
19
20/*
21* Material from the TR181 data model is Copyright (c) 2010-2017, Broadband Forum
22* Licensed under the BSD-3 license
23*/
24
25/*
26* This file includes material that is Copyright (c) 2020, Plume Design Inc.
27* Licensed under the BSD-3 license
28*/
29
30/* Code in rxStatsInfo_callback and other callbacks is credited as follows:
developera3511852023-06-14 14:12:59 +080031Copyright (c) 2007, 2008 Johannes Berg
32Copyright (c) 2007 Andy Lutomirski
33Copyright (c) 2007 Mike Kershaw
34Copyright (c) 2008-2009 Luis R. Rodriguez
developer72fb0bb2023-01-11 09:46:29 +080035Licensed under the ISC license
36*/
37#define MTK_IMPL
38#define HAL_NETLINK_IMPL
39#define _GNU_SOURCE /* needed for strcasestr */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44#include <string.h>
45#include <fcntl.h>
46#include <stdbool.h>
47#include "wifi_hal.h"
48
49#ifdef HAL_NETLINK_IMPL
50#include <errno.h>
51#include <netlink/attr.h>
52#include <netlink/netlink.h>
53#include <netlink/genl/genl.h>
54#include <netlink/genl/family.h>
55#include <netlink/genl/ctrl.h>
56#include <linux/nl80211.h>
developer8dd72532023-05-17 19:58:35 +080057#include <net/if.h>
58#include <unl.h>
59#include "mtk_vendor_nl80211.h"
developer72fb0bb2023-01-11 09:46:29 +080060#endif
61
62#include <ev.h>
63#include <wpa_ctrl.h>
64#include <errno.h>
65#include <time.h>
developercc5cbfb2023-06-13 18:29:52 +080066
67#include <sys/socket.h>
68#include <sys/ioctl.h>
69#include <arpa/inet.h>
70#include <linux/if.h>
71#include <linux/if_bridge.h>
72#include <linux/sockios.h>
developer86035662023-06-28 19:21:12 +080073#include <errno.h>
74#include <limits.h>
developercc5cbfb2023-06-13 18:29:52 +080075
developer72fb0bb2023-01-11 09:46:29 +080076#define MAC_ALEN 6
77
78#define MAX_BUF_SIZE 256
79#define MAX_CMD_SIZE 256
developerb149d9d2023-06-06 16:14:22 +080080#define MAX_SUB_CMD_SIZE 200
81
developer72fb0bb2023-01-11 09:46:29 +080082#define IF_NAME_SIZE 16
83#define CONFIG_PREFIX "/nvram/hostapd"
84#define ACL_PREFIX "/nvram/hostapd-acl"
85#define DENY_PREFIX "/nvram/hostapd-deny"
86//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
87#define SOCK_PREFIX "/var/run/hostapd/wifi"
88#define VAP_STATUS_FILE "/nvram/vap-status"
89#define ESSID_FILE "/tmp/essid"
90#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
91#define CHANNEL_STATS_FILE "/tmp/channel_stats"
92#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
93#define VLAN_FILE "/nvram/hostapd.vlan"
94#define PSK_FILE "/nvram/hostapd"
95#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080096#define POWER_PERCENTAGE "/tmp/POWER"
97#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
98/*LOGAN_DAT_FILE: may be different on customer's platform.*/
99#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +0800100#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +0800101
developer72fb0bb2023-01-11 09:46:29 +0800102#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +0800103#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +0800104
developer72fb0bb2023-01-11 09:46:29 +0800105#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +0800106#define BASE_PHY_INDEX 1
107#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +0800108
109/*
110 MAX_APS - Number of all AP available in system
111 2x Home AP
112 2x Backhaul AP
113 2x Guest AP
114 2x Secure Onboard AP
115 2x Service AP
116
117*/
118
119
120#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800121
122#define PREFIX_WIFI2G "ra"
123#define PREFIX_WIFI5G "rai"
124#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800125
developer47cc27a2023-05-17 23:09:58 +0800126#define PREFIX_SSID_2G "RDKB_2G"
127#define PREFIX_SSID_5G "RDKB_5G"
128#define PREFIX_SSID_6G "RDKB_6G"
129
developer72fb0bb2023-01-11 09:46:29 +0800130#ifndef RADIO_PREFIX
131#define RADIO_PREFIX "wlan"
132#endif
133
134#define MAX_ASSOCIATED_STA_NUM 2007
135
136//Uncomment to enable debug logs
137//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800138enum {
139 DEBUG_OFF = 0,
140 DEBUG_ERROR = 1,
141 DEBUG_WARN = 2,
142 DEBUG_NOTICE = 3,
143 DEBUG_INFO = 4
144};
145int wifi_debug_level = DEBUG_NOTICE;
146#define wifi_debug(level, fmt, args...) \
147{ \
148 if (level <= wifi_debug_level) \
149 { \
developer2edaf012023-05-24 14:24:53 +0800150 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800151 } \
152}
developer72fb0bb2023-01-11 09:46:29 +0800153
154#ifdef WIFI_DEBUG
155#define wifi_dbg_printf printf
156#define WIFI_ENTRY_EXIT_DEBUG printf
157#else
developer2f79c922023-06-02 17:33:42 +0800158#define wifi_dbg_printf(format, args...)
159#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
developer72fb0bb2023-01-11 09:46:29 +0800160#endif
161
162#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
163#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
164#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
165#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
166#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
167#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
168#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
169#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
170#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
171#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
172
173#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
174
175#define BW_FNAME "/nvram/bw_file.txt"
176
177#define PS_MAX_TID 16
178
developer96b38512023-02-22 11:17:45 +0800179#define MAX_CARD_INDEX 3
180
developer72fb0bb2023-01-11 09:46:29 +0800181static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
developera3511852023-06-14 14:12:59 +0800182 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
183 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
184 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
185 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
186 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
187 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
188 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
189 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
190 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
191 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
192 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
193 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
194 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
195 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
196 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
197 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
developer72fb0bb2023-01-11 09:46:29 +0800198};
199
200typedef unsigned long long u64;
201
202/* Enum to define WiFi Bands */
203typedef enum
204{
developera3511852023-06-14 14:12:59 +0800205 band_invalid = -1,
206 band_2_4 = 0,
207 band_5 = 1,
208 band_6 = 2,
developer72fb0bb2023-01-11 09:46:29 +0800209} wifi_band;
210
developer17038e62023-03-02 14:43:43 +0800211char* wifi_band_str[] = {
developera3511852023-06-14 14:12:59 +0800212 "2G",
213 "5G",
214 "6G",
developer17038e62023-03-02 14:43:43 +0800215};
216
developer72fb0bb2023-01-11 09:46:29 +0800217typedef enum {
developera3511852023-06-14 14:12:59 +0800218 WIFI_MODE_A = 0x01,
219 WIFI_MODE_B = 0x02,
220 WIFI_MODE_G = 0x04,
221 WIFI_MODE_N = 0x08,
222 WIFI_MODE_AC = 0x10,
223 WIFI_MODE_AX = 0x20,
224 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800225} wifi_ieee80211_Mode;
226
developer2f79c922023-06-02 17:33:42 +0800227typedef enum {
developera3511852023-06-14 14:12:59 +0800228 HT_BW_20,
229 HT_BW_40,
developer2f79c922023-06-02 17:33:42 +0800230} ht_config_bw;
developerd1824452023-05-18 12:30:04 +0800231
developer2f79c922023-06-02 17:33:42 +0800232typedef enum {
developera3511852023-06-14 14:12:59 +0800233 VHT_BW_2040,
234 VHT_BW_80,
235 VHT_BW_160,
236 VHT_BW_8080,
developer2f79c922023-06-02 17:33:42 +0800237} vht_config_bw;
developerd1824452023-05-18 12:30:04 +0800238
developer2f79c922023-06-02 17:33:42 +0800239typedef enum {
developera3511852023-06-14 14:12:59 +0800240 EHT_BW_20,
241 EHT_BW_40,
242 EHT_BW_80,
243 EHT_BW_160,
244 EHT_BW_320,
developer2f79c922023-06-02 17:33:42 +0800245} eht_config_bw;
developerd1824452023-05-18 12:30:04 +0800246
developer72fb0bb2023-01-11 09:46:29 +0800247#ifdef WIFI_HAL_VERSION_3
248
249// Return number of elements in array
250#ifndef ARRAY_SIZE
developera3511852023-06-14 14:12:59 +0800251#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
developer72fb0bb2023-01-11 09:46:29 +0800252#endif /* ARRAY_SIZE */
253
254#ifndef ARRAY_AND_SIZE
developera3511852023-06-14 14:12:59 +0800255#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
developer72fb0bb2023-01-11 09:46:29 +0800256#endif /* ARRAY_AND_SIZE */
257
developera3511852023-06-14 14:12:59 +0800258#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
developer72fb0bb2023-01-11 09:46:29 +0800259
260typedef struct {
developera3511852023-06-14 14:12:59 +0800261 int32_t value;
262 int32_t param;
263 intptr_t key;
264 intptr_t data;
developer72fb0bb2023-01-11 09:46:29 +0800265} wifi_secur_list;
266
developer0155a502023-06-19 20:33:57 +0800267typedef struct GNU_PACKED _wdev_extended_ap_metrics {
268 unsigned int uc_tx;
269 unsigned int uc_rx;
270 unsigned int mc_tx;
271 unsigned int mc_rx;
272 unsigned int bc_tx;
273 unsigned int bc_rx;
274} wdev_extended_ap_metric;
275
276typedef struct GNU_PACKED _wdev_ap_metric {
277 unsigned char bssid[6];
278 unsigned char cu;
279 unsigned char ESPI_AC[4][3];
280 wdev_extended_ap_metric ext_ap_metric;
281} wdev_ap_metric;
282
283
developer72fb0bb2023-01-11 09:46:29 +0800284static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
285static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
developera3511852023-06-14 14:12:59 +0800286wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
287wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
288char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
developer72fb0bb2023-01-11 09:46:29 +0800289static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developer47cc27a2023-05-17 23:09:58 +0800290static void wifi_PrepareDefaultHostapdConfigs(void);
291static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800292static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800293static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer2f79c922023-06-02 17:33:42 +0800294int hostapd_raw_add_bss(int apIndex);
295int hostapd_raw_remove_bss(int apIndex);
developer86035662023-06-28 19:21:12 +0800296static inline int hal_strtol(char *src, int base, long int *out)
297{
298 long int res = 0;
299 char *end_ptr = NULL;
300
301 errno = 0;
302 res = strtol(src, &end_ptr, base);
303
304 if ((errno == ERANGE && (res == LONG_MIN || res == LONG_MAX))
305 || (errno != 0 && res == 0) || *end_ptr != '\0' || src == end_ptr )
306 return -1;
307 else
308 *out = res;
309
310 return 0;
311}
312
313static inline int hal_strtoul(char *src, int base, unsigned long *out)
314{
315 unsigned long res = 0;
316 char *end_ptr = NULL;
317
318 errno = 0;
319 res = strtoul(src, &end_ptr, base);
320
321 if ((errno == ERANGE && res == ULONG_MAX)
322 || (errno != 0 && res == 0) || *end_ptr != '\0' || src == end_ptr )
323 return -1;
324 else
325 *out = res;
326
327 return 0;
328}
developer47cc27a2023-05-17 23:09:58 +0800329
developercc5cbfb2023-06-13 18:29:52 +0800330static inline int os_snprintf_error(size_t size, int res)
331{
332 return res < 0 || (unsigned int) res >= size;
333}
334
developer49b17232023-05-19 16:35:19 +0800335/*type define the nl80211 call back func*/
336typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
337
338/**
339*struct mtk_nl80211_param
340* init mtk nl80211 using parameters
341* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
342* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
343* @if_idx: the index should match the interface or wiphy.
344* Note: NA
345**/
346struct mtk_nl80211_param {
347 unsigned int sub_cmd;
348 int if_type;
349 int if_idx;
350};
351
352/**
developer121a8e72023-05-22 09:19:39 +0800353*struct mtk_nl80211_cb_data
354* init mtk nl80211 call back parameters
355* @out_buf: store the mtk vendor output msg for wifi hal buffer.
356* @out_len: the output buffer length.
357* Note: NA
358**/
359struct mtk_nl80211_cb_data {
360 char * out_buf;
361 unsigned int out_len;
362};
363
364/**
developer49b17232023-05-19 16:35:19 +0800365*mtk_nl80211_init
366* init mtk nl80211 netlink and init the vendor msg common part.
367* @nl: netlink, just init it.
368* @msg: netlink message will alloc it.
369* the msg send success/fails is not free by app
370* only the nla_put etc api fails should use nlmsg_free.
371* @msg_data: vendor data msg attr pointer.
372* @param: init using interface and sub_cmd parameter.
373*
374*init the netlink context and mtk netlink vendor msg.
375*
376*return:
377* 0: success
378* other: fail
379**/
380
381int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
382 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
383 /*sanity check here*/
384 if (!nl || !param) {
385 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800386 "[%s][%d]:nl(%p) or param(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800387 __func__, __LINE__, nl, param);
388 return -1;
389 }
390 /*if_type check*/
391 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
392 (void)fprintf(stderr,
393 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
394 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
395 return -1;
396 }
397 /*init the nl*/
398 if (unl_genl_init(nl, "nl80211") < 0) {
399 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
400 __func__, __LINE__);
401 return -1;
402 }
403 /*init the msg*/
404 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
405
406 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
developera3511852023-06-14 14:12:59 +0800407 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
408 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
developer49b17232023-05-19 16:35:19 +0800409 (void)fprintf(stderr,
410 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
411 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
412 goto err;
413 }
414
415 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
416 if (!*msg_data) {
417 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
418 __func__, __LINE__);
419 goto err;
420 }
421
422 return 0;
423err:
developer49b17232023-05-19 16:35:19 +0800424 nlmsg_free(*msg);
425 unl_free(nl);
426 return -1;
427}
428
429/**
430*mtk_nl80211_send
431* set the vendor cmd call back and sent the vendor msg.
432* @nl: netlink.
433* @msg: netlink message.
434* @msg_data: vendor data msg attr pointer.
435* @handler: if the msg have call back shoud add the call back func
436* the event msg will handle by the call back func(exp:get cmd)
437* other set it as NULL(exp:set cmd).
438* @arg:call back func arg parameter.
439*add end of the netlink msg, set the call back and send msg
440*
441*return:
442* 0: success
443* other: fail
444**/
445int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
446 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
447 int ret = 0;
448 /*sanity check*/
449 if (!nl || !msg || !msg_data) {
450 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800451 "[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800452 __func__, __LINE__, nl, msg, msg_data);
453 return -1;
454 }
455 /*end the msg attr of vendor data*/
456 nla_nest_end(msg, msg_data);
457 /*send the msg and set call back */
458 ret = unl_genl_request(nl, msg, handler, arg);
459 if (ret)
460 (void)fprintf(stderr, "send nl80211 cmd fails\n");
461 return ret;
462}
463
464/**
465*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800466* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800467* @nl: netlink.
468*
developer2edaf012023-05-24 14:24:53 +0800469*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800470*
471*return:
472* 0: success
473**/
474
475int mtk_nl80211_deint(struct unl *nl) {
476 unl_free(nl);
477 return 0;
478}
479
developer72fb0bb2023-01-11 09:46:29 +0800480wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
481{
developera3511852023-06-14 14:12:59 +0800482 wifi_secur_list *item;
483 int i;
developer72fb0bb2023-01-11 09:46:29 +0800484
developera3511852023-06-14 14:12:59 +0800485 for (item = list,i = 0;i < list_sz; item++, i++) {
486 if ((int)(item->key) == key) {
487 return item;
488 }
489 }
developer72fb0bb2023-01-11 09:46:29 +0800490
developera3511852023-06-14 14:12:59 +0800491 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800492}
493
494char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
495{
developera3511852023-06-14 14:12:59 +0800496 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
developer72fb0bb2023-01-11 09:46:29 +0800497
developera3511852023-06-14 14:12:59 +0800498 if (!item) {
499 return "";
500 }
developer72fb0bb2023-01-11 09:46:29 +0800501
developera3511852023-06-14 14:12:59 +0800502 return (char *)(item->data);
developer72fb0bb2023-01-11 09:46:29 +0800503}
504
505wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
506{
developera3511852023-06-14 14:12:59 +0800507 wifi_secur_list *item;
508 int i;
developer72fb0bb2023-01-11 09:46:29 +0800509
developera3511852023-06-14 14:12:59 +0800510 for (item = list,i = 0;i < list_sz; item++, i++) {
511 if (strcmp((char *)(item->data), str) == 0) {
512 return item;
513 }
514 }
developer72fb0bb2023-01-11 09:46:29 +0800515
developera3511852023-06-14 14:12:59 +0800516 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800517}
518#endif /* WIFI_HAL_VERSION_3 */
519
developer96b38512023-02-22 11:17:45 +0800520
521static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800522char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
523char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
524#define MAX_SSID_LEN 64
525char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800526int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800527
528static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
529static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
530
developer96b38512023-02-22 11:17:45 +0800531
532static int
533get_value(const char *conf_file, const char *param, char *value, int len)
534{
developera3511852023-06-14 14:12:59 +0800535 FILE *fp;
536 int ret = -1;
537 int param_len = strlen(param);
538 int buf_len;
developer86035662023-06-28 19:21:12 +0800539 char buf[256] = {0};
developer96b38512023-02-22 11:17:45 +0800540
developera3511852023-06-14 14:12:59 +0800541 fp = fopen(conf_file, "r");
542 if (!fp) {
543 return -1;
544 }
developer96b38512023-02-22 11:17:45 +0800545
developera3511852023-06-14 14:12:59 +0800546 while (fgets(buf, sizeof(buf), fp)) {
547 buf_len = strlen(buf);
developer86035662023-06-28 19:21:12 +0800548 if (buf_len == 0) {
549 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
550 fclose(fp);
551 return RETURN_ERR;
552 }
developera3511852023-06-14 14:12:59 +0800553 if (buf[buf_len - 1] == '\n') {
554 buf_len--;
555 buf[buf_len] = '\0';
556 }
557 if ((buf_len > param_len) &&
558 (strncmp(buf, param, param_len) == 0) &&
559 (buf[param_len] == '=')) {
developer96b38512023-02-22 11:17:45 +0800560
developera3511852023-06-14 14:12:59 +0800561 if (buf_len == (param_len + 1)) {
562 value[0] = '\0';
563 ret = 0;
564 } else {
565 ret = snprintf(value, len, "%s", buf + (param_len + 1));
developer75bd10c2023-06-27 11:34:08 +0800566 if (os_snprintf_error(len, ret)) {
567 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
568 }
developera3511852023-06-14 14:12:59 +0800569 }
570 fclose(fp);
571 return ret;
572 }
573 }
574 fclose(fp);
575 return -1;
developer96b38512023-02-22 11:17:45 +0800576}
577
578static int
579get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
580{
developera3511852023-06-14 14:12:59 +0800581 char buf[256];
582 int ret;
583 char *save_ptr = NULL;
584 char *tok = NULL;
developer96b38512023-02-22 11:17:45 +0800585
developera3511852023-06-14 14:12:59 +0800586 ret = get_value(conf_file, param, buf, sizeof(buf));
587 if (ret < 0)
588 return ret;
developer96b38512023-02-22 11:17:45 +0800589
developera3511852023-06-14 14:12:59 +0800590 tok = strtok_r(buf, ";", &save_ptr);
591 do {
592 if (idx == 0 || tok == NULL)
593 break;
594 else
595 idx--;
developer96b38512023-02-22 11:17:45 +0800596
developera3511852023-06-14 14:12:59 +0800597 tok = strtok_r(NULL, ";", &save_ptr);
598 } while (tok != NULL);
developer96b38512023-02-22 11:17:45 +0800599
developera3511852023-06-14 14:12:59 +0800600 if (tok) {
601 ret = snprintf(value, len, "%s", tok);
developer75bd10c2023-06-27 11:34:08 +0800602 if (os_snprintf_error(len, ret)) {
603 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
604 return -1;
605 }
developera3511852023-06-14 14:12:59 +0800606 } else {
607 ret = 0;
608 value[0] = '\0';
609 }
developer96b38512023-02-22 11:17:45 +0800610
developera3511852023-06-14 14:12:59 +0800611 return ret;
developer96b38512023-02-22 11:17:45 +0800612}
613
614
developer72fb0bb2023-01-11 09:46:29 +0800615#ifdef HAL_NETLINK_IMPL
616typedef struct {
developera3511852023-06-14 14:12:59 +0800617 int id;
618 struct nl_sock* socket;
619 struct nl_cb* cb;
developer72fb0bb2023-01-11 09:46:29 +0800620} Netlink;
621
622static int mac_addr_aton(unsigned char *mac_addr, char *arg)
623{
developera3511852023-06-14 14:12:59 +0800624 unsigned char mac_addr_int[6]={};
developer75bd10c2023-06-27 11:34:08 +0800625 unsigned int recv;
626
627 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);
628
629 if (recv != 6) {
630 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
631 return -1;
632 }
developera3511852023-06-14 14:12:59 +0800633 mac_addr[0] = mac_addr_int[0];
634 mac_addr[1] = mac_addr_int[1];
635 mac_addr[2] = mac_addr_int[2];
636 mac_addr[3] = mac_addr_int[3];
637 mac_addr[4] = mac_addr_int[4];
638 mac_addr[5] = mac_addr_int[5];
639 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800640}
641
642static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
643{
developera3511852023-06-14 14:12:59 +0800644 unsigned int mac_addr_int[6]={};
developere40952c2023-06-15 18:46:43 +0800645 int res;
646
developera3511852023-06-14 14:12:59 +0800647 mac_addr_int[0] = arg[0];
648 mac_addr_int[1] = arg[1];
649 mac_addr_int[2] = arg[2];
650 mac_addr_int[3] = arg[3];
651 mac_addr_int[4] = arg[4];
652 mac_addr_int[5] = arg[5];
developere40952c2023-06-15 18:46:43 +0800653 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]);
654 if (os_snprintf_error(20, res)) {
655 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
656 }
developera3511852023-06-14 14:12:59 +0800657 return;
developer72fb0bb2023-01-11 09:46:29 +0800658}
659
660static int ieee80211_frequency_to_channel(int freq)
661{
developera3511852023-06-14 14:12:59 +0800662 /* see 802.11-2007 17.3.8.3.2 and Annex J */
663 if (freq == 2484)
664 return 14;
665 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
666 else if (freq == 5935)
667 return 2;
668 else if (freq < 2484)
669 return (freq - 2407) / 5;
670 else if (freq >= 4910 && freq <= 4980)
671 return (freq - 4000) / 5;
672 else if (freq < 5950)
673 return (freq - 5000) / 5;
674 else if (freq <= 45000) /* DMG band lower limit */
675 /* see 802.11ax D6.1 27.3.23.2 */
676 return (freq - 5950) / 5;
677 else if (freq >= 58320 && freq <= 70200)
678 return (freq - 56160) / 2160;
679 else
680 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800681}
682
683static int initSock80211(Netlink* nl) {
developera3511852023-06-14 14:12:59 +0800684 nl->socket = nl_socket_alloc();
685 if (!nl->socket) {
developer75bd10c2023-06-27 11:34:08 +0800686 wifi_debug(DEBUG_ERROR, "Failing to allocate the sock\n");
developera3511852023-06-14 14:12:59 +0800687 return -ENOMEM;
688 }
developer72fb0bb2023-01-11 09:46:29 +0800689
developera3511852023-06-14 14:12:59 +0800690 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
developer72fb0bb2023-01-11 09:46:29 +0800691
developera3511852023-06-14 14:12:59 +0800692 if (genl_connect(nl->socket)) {
developer75bd10c2023-06-27 11:34:08 +0800693 wifi_debug(DEBUG_ERROR, "Failed to connect\n");
developera3511852023-06-14 14:12:59 +0800694 nl_close(nl->socket);
695 nl_socket_free(nl->socket);
696 return -ENOLINK;
697 }
developer72fb0bb2023-01-11 09:46:29 +0800698
developera3511852023-06-14 14:12:59 +0800699 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
700 if (nl->id< 0) {
developer75bd10c2023-06-27 11:34:08 +0800701 wifi_debug(DEBUG_ERROR, "interface not found.\n");
developera3511852023-06-14 14:12:59 +0800702 nl_close(nl->socket);
703 nl_socket_free(nl->socket);
704 return -ENOENT;
705 }
developer72fb0bb2023-01-11 09:46:29 +0800706
developera3511852023-06-14 14:12:59 +0800707 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
708 if ((!nl->cb)) {
developer75bd10c2023-06-27 11:34:08 +0800709 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink callback.\n");
developera3511852023-06-14 14:12:59 +0800710 nl_close(nl->socket);
711 nl_socket_free(nl->socket);
712 return ENOMEM;
713 }
developer72fb0bb2023-01-11 09:46:29 +0800714
developera3511852023-06-14 14:12:59 +0800715 return nl->id;
developer72fb0bb2023-01-11 09:46:29 +0800716}
717
718static int nlfree(Netlink *nl)
719{
developera3511852023-06-14 14:12:59 +0800720 nl_cb_put(nl->cb);
721 nl_close(nl->socket);
722 nl_socket_free(nl->socket);
723 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800724}
725
726static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
developera3511852023-06-14 14:12:59 +0800727 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
728 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
729 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
developer72fb0bb2023-01-11 09:46:29 +0800730};
731
732static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
733};
734
735static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
736};
737
738typedef struct _wifi_channelStats_loc {
developera3511852023-06-14 14:12:59 +0800739 INT array_size;
740 INT ch_number;
741 BOOL ch_in_pool;
742 INT ch_noise;
743 BOOL ch_radar_noise;
744 INT ch_max_80211_rssi;
745 INT ch_non_80211_noise;
746 INT ch_utilization;
747 ULLONG ch_utilization_total;
748 ULLONG ch_utilization_busy;
749 ULLONG ch_utilization_busy_tx;
750 ULLONG ch_utilization_busy_rx;
751 ULLONG ch_utilization_busy_self;
752 ULLONG ch_utilization_busy_ext;
developer72fb0bb2023-01-11 09:46:29 +0800753} wifi_channelStats_t_loc;
754
755typedef struct wifi_device_info {
developera3511852023-06-14 14:12:59 +0800756 INT wifi_devIndex;
757 UCHAR wifi_devMacAddress[6];
758 CHAR wifi_devIPAddress[64];
759 BOOL wifi_devAssociatedDeviceAuthentiationState;
760 INT wifi_devSignalStrength;
761 INT wifi_devTxRate;
762 INT wifi_devRxRate;
developer72fb0bb2023-01-11 09:46:29 +0800763} wifi_device_info_t;
764
765#endif
766
767//For 5g Alias Interfaces
developer72fb0bb2023-01-11 09:46:29 +0800768static BOOL Radio_flag = TRUE;
769//wifi_setApBeaconRate(1, beaconRate);
770
771BOOL multiple_set = FALSE;
772
773struct params
774{
developera3511852023-06-14 14:12:59 +0800775 char * name;
776 char * value;
developer72fb0bb2023-01-11 09:46:29 +0800777};
778
779static int _syscmd(char *cmd, char *retBuf, int retBufSize)
780{
developera3511852023-06-14 14:12:59 +0800781 FILE *f;
782 char *ptr = retBuf;
783 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
developer72fb0bb2023-01-11 09:46:29 +0800784
developera3511852023-06-14 14:12:59 +0800785 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
786 if((f = popen(cmd, "r")) == NULL) {
developer75bd10c2023-06-27 11:34:08 +0800787 wifi_debug(DEBUG_ERROR, "\npopen %s error\n", cmd);
developera3511852023-06-14 14:12:59 +0800788 return RETURN_ERR;
789 }
developer72fb0bb2023-01-11 09:46:29 +0800790
developera3511852023-06-14 14:12:59 +0800791 while(!feof(f))
792 {
793 *ptr = 0;
794 if(bufSize>=128) {
795 bufbytes=128;
796 } else {
797 bufbytes=bufSize-1;
798 }
developer72fb0bb2023-01-11 09:46:29 +0800799
developera3511852023-06-14 14:12:59 +0800800 fgets(ptr,bufbytes,f);
801 readbytes=strlen(ptr);
developer72fb0bb2023-01-11 09:46:29 +0800802
developera3511852023-06-14 14:12:59 +0800803 if(!readbytes)
804 break;
developer72fb0bb2023-01-11 09:46:29 +0800805
developera3511852023-06-14 14:12:59 +0800806 bufSize-=readbytes;
807 ptr += readbytes;
808 }
809 cmd_ret = pclose(f);
810 retBuf[retBufSize-1]=0;
811 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800812
developera3511852023-06-14 14:12:59 +0800813 return cmd_ret >> 8;
developer72fb0bb2023-01-11 09:46:29 +0800814}
815
816INT radio_index_to_phy(int radioIndex)
817{
developera3511852023-06-14 14:12:59 +0800818 /* TODO */
819 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800820}
821
822INT wifi_getMaxRadioNumber(INT *max_radio_num)
823{
developera3511852023-06-14 14:12:59 +0800824 char cmd[64] = {0};
825 char buf[4] = {0};
developere40952c2023-06-15 18:46:43 +0800826 int res;
developera3511852023-06-14 14:12:59 +0800827 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800828
developere40952c2023-06-15 18:46:43 +0800829 res = snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
830 if (os_snprintf_error(sizeof(cmd), res)) {
831 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
832 return RETURN_ERR;
833 }
developera3511852023-06-14 14:12:59 +0800834 _syscmd(cmd, buf, sizeof(buf));
835 *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +0800836
developera3511852023-06-14 14:12:59 +0800837 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800838
developera3511852023-06-14 14:12:59 +0800839 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +0800840}
841
developer17038e62023-03-02 14:43:43 +0800842wifi_band radio_index_to_band(int radioIndex)
843{
developera3511852023-06-14 14:12:59 +0800844 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800845}
846
developer72fb0bb2023-01-11 09:46:29 +0800847wifi_band wifi_index_to_band(int apIndex)
848{
developera3511852023-06-14 14:12:59 +0800849 char cmd[128] = {0};
850 char buf[64] = {0};
851 int nl80211_band = 0;
852 int i = 0;
853 int phyIndex = 0;
854 int radioIndex = 0;
855 int max_radio_num = 0;
856 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +0800857 int res;
developer72fb0bb2023-01-11 09:46:29 +0800858
developera3511852023-06-14 14:12:59 +0800859 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800860
developera3511852023-06-14 14:12:59 +0800861 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +0800862 if(max_radio_num == 0){
863 return RETURN_ERR;
864 }
developera3511852023-06-14 14:12:59 +0800865 radioIndex = apIndex % max_radio_num;
866 phyIndex = radio_index_to_phy(radioIndex);
867 while(i < 10){
developere40952c2023-06-15 18:46:43 +0800868 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
869 if (os_snprintf_error(sizeof(cmd), res)) {
870 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
871 }
developera3511852023-06-14 14:12:59 +0800872 _syscmd(cmd, buf, sizeof(buf));
873 nl80211_band = strtol(buf, NULL, 10);
874 if (nl80211_band == 1)
875 band = band_2_4;
876 else if (nl80211_band == 2)
877 band = band_5;
878 else if (nl80211_band == 4) // band == 3 is 60GHz
879 band = band_6;
developer72fb0bb2023-01-11 09:46:29 +0800880
developera3511852023-06-14 14:12:59 +0800881 if(band != band_invalid)
882 break;
developer69b61b02023-03-07 17:17:44 +0800883
developera3511852023-06-14 14:12:59 +0800884 i++;
885 sleep(1);
886 }
developer72fb0bb2023-01-11 09:46:29 +0800887
developera3511852023-06-14 14:12:59 +0800888 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
889 return band;
developer72fb0bb2023-01-11 09:46:29 +0800890}
891
892static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
893{
developer7e4a2a62023-04-06 19:56:03 +0800894 char cmd[MAX_CMD_SIZE] = {0};
895 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800896 int res = 0;
developer72fb0bb2023-01-11 09:46:29 +0800897
developere40952c2023-06-15 18:46:43 +0800898 res = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developer7e4a2a62023-04-06 19:56:03 +0800899 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800900
developere40952c2023-06-15 18:46:43 +0800901 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
902 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
903 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +0800904 }
developerb758dfd2023-06-21 17:32:07 +0800905
developere40952c2023-06-15 18:46:43 +0800906 res = _syscmd(cmd, buf, sizeof(buf));
907 if ((res != 0) && (strlen(buf) == 0)) {
developer7e4a2a62023-04-06 19:56:03 +0800908 printf("%s: _syscmd error!", __func__);
909 return -1;
910 }
911
developere40952c2023-06-15 18:46:43 +0800912 res = snprintf(output, output_size, "%s", buf);
913 if (os_snprintf_error(output_size, res)) {
914 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
915 return RETURN_ERR;
916 }
developer7e4a2a62023-04-06 19:56:03 +0800917
918 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800919}
920
921static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
922{
developera3511852023-06-14 14:12:59 +0800923 char cmd[MAX_CMD_SIZE] = {0};
924 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800925 int res;
developer72fb0bb2023-01-11 09:46:29 +0800926
developera3511852023-06-14 14:12:59 +0800927 for (int i = 0; i < item_count; i++) {
928 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
929 if (strlen(buf) == 0) /*no such item, insert it*/
developere40952c2023-06-15 18:46:43 +0800930 res = snprintf(cmd, sizeof(cmd), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file);
developera3511852023-06-14 14:12:59 +0800931 else /*find the item, update it*/
developere40952c2023-06-15 18:46:43 +0800932 res = snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file);
developera1255e42023-05-13 17:45:02 +0800933
developere40952c2023-06-15 18:46:43 +0800934 if (os_snprintf_error(sizeof(cmd), res)) {
935 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
936 return RETURN_ERR;
937 }
developera3511852023-06-14 14:12:59 +0800938 if(_syscmd(cmd, buf, sizeof(buf)))
939 return -1;
940 }
developer72fb0bb2023-01-11 09:46:29 +0800941
developera3511852023-06-14 14:12:59 +0800942 return 0;
developera1255e42023-05-13 17:45:02 +0800943}
developerfde01262023-05-22 15:15:24 +0800944
developera1255e42023-05-13 17:45:02 +0800945static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
946{
developera3511852023-06-14 14:12:59 +0800947 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800948 int res = 0;
developera3511852023-06-14 14:12:59 +0800949 int len;
developerfde01262023-05-22 15:15:24 +0800950
developere40952c2023-06-15 18:46:43 +0800951 res = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
952 if (os_snprintf_error(sizeof(cmd), res)) {
953 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
954 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800955 }
developerfde01262023-05-22 15:15:24 +0800956
developere40952c2023-06-15 18:46:43 +0800957
958 res = _syscmd(cmd, output, output_size);
959 if ((res != 0) && (strlen(output) == 0)) {
developera3511852023-06-14 14:12:59 +0800960 printf("%s: _syscmd error!", __func__);
961 return -1;
962 }
developera1255e42023-05-13 17:45:02 +0800963
developera3511852023-06-14 14:12:59 +0800964 len = strlen(output);
965 if ((len > 0) && (output[len - 1] == '\n')) {
966 output[len - 1] = '\0';
967 }
developerfde01262023-05-22 15:15:24 +0800968
developera3511852023-06-14 14:12:59 +0800969 return 0;
developerfde01262023-05-22 15:15:24 +0800970}
developera1255e42023-05-13 17:45:02 +0800971
developera1255e42023-05-13 17:45:02 +0800972static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
973{
developere40952c2023-06-15 18:46:43 +0800974 int res;
developera3511852023-06-14 14:12:59 +0800975 char cmd[MAX_CMD_SIZE] = {0};
976 char buf[MAX_BUF_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800977
developera3511852023-06-14 14:12:59 +0800978 for (int i = 0; i < item_count; i++) {
developere40952c2023-06-15 18:46:43 +0800979 res = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
980 if (os_snprintf_error(sizeof(cmd), res)) {
981 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
982 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800983 }
developera1255e42023-05-13 17:45:02 +0800984
developera3511852023-06-14 14:12:59 +0800985 if(_syscmd(cmd, buf, sizeof(buf)))
986 return -1;
987 }
developera1255e42023-05-13 17:45:02 +0800988
developera3511852023-06-14 14:12:59 +0800989 return 0;
developera1255e42023-05-13 17:45:02 +0800990}
991
developerfde01262023-05-22 15:15:24 +0800992static int wifi_l1ProfileRead(char *param, char *output, int output_size)
993{
developera3511852023-06-14 14:12:59 +0800994 int ret;
developerfde01262023-05-22 15:15:24 +0800995
developera3511852023-06-14 14:12:59 +0800996 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
997 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +0800998 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +0800999 return RETURN_ERR;
1000 }
developerfde01262023-05-22 15:15:24 +08001001
developera3511852023-06-14 14:12:59 +08001002 ret = wifi_datfileRead(l1profile, param, output, output_size);
1003 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001004 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, l1profile, ret);
developera3511852023-06-14 14:12:59 +08001005 return RETURN_ERR;
1006 }
developerfde01262023-05-22 15:15:24 +08001007
developera3511852023-06-14 14:12:59 +08001008 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1009 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001010}
1011
1012static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
1013{
developera3511852023-06-14 14:12:59 +08001014 char option[64];
1015 char card_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001016 int res;
developerfde01262023-05-22 15:15:24 +08001017
developera3511852023-06-14 14:12:59 +08001018 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerfde01262023-05-22 15:15:24 +08001019
developera3511852023-06-14 14:12:59 +08001020 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001021 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001022 return RETURN_ERR;
1023 }
developerfde01262023-05-22 15:15:24 +08001024
developere40952c2023-06-15 18:46:43 +08001025 res = snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
1026 if (os_snprintf_error(sizeof(option), res)) {
1027 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +08001028 return RETURN_ERR;
1029 }
developere40952c2023-06-15 18:46:43 +08001030 res = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
1031 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001032 wifi_debug(DEBUG_ERROR, "wifi_l1ProfileRead %s failed, ret:%d", option, res);
developere40952c2023-06-15 18:46:43 +08001033 return RETURN_ERR;
1034 }
developerfde01262023-05-22 15:15:24 +08001035
developere40952c2023-06-15 18:46:43 +08001036 res = wifi_datfileRead(card_profile_path, param, output, output_size);
1037 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001038 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, card_profile_path, res);
developera3511852023-06-14 14:12:59 +08001039 return RETURN_ERR;
1040 }
developerfde01262023-05-22 15:15:24 +08001041
developera3511852023-06-14 14:12:59 +08001042 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1043 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001044}
1045
1046static int wifi_BandProfileRead(int card_idx,
developera3511852023-06-14 14:12:59 +08001047 int radio_idx,
1048 char *param,
1049 char *output,
1050 int output_size,
1051 char *default_value)
developerfde01262023-05-22 15:15:24 +08001052{
developera3511852023-06-14 14:12:59 +08001053 char option[64];
1054 char band_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001055 int ret, res;
developerfde01262023-05-22 15:15:24 +08001056
developera3511852023-06-14 14:12:59 +08001057 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1058 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001059 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001060 return RETURN_ERR;
1061 }
developerfde01262023-05-22 15:15:24 +08001062
developere40952c2023-06-15 18:46:43 +08001063 res = snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1064 if (os_snprintf_error(sizeof(option), res)) {
1065 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1066 return RETURN_ERR;
1067 }
developera3511852023-06-14 14:12:59 +08001068 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1069 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001070 wifi_debug(DEBUG_ERROR, "wifi_CardProfileRead %s failed, ret:%d", option, ret);
developera3511852023-06-14 14:12:59 +08001071 return RETURN_ERR;
1072 }
developerfde01262023-05-22 15:15:24 +08001073
developera3511852023-06-14 14:12:59 +08001074 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1075 if (ret != 0) {
1076 if (default_value) {
developere40952c2023-06-15 18:46:43 +08001077 res = snprintf(output, output_size, "%s", default_value);
1078 if (os_snprintf_error(output_size, res)) {
1079 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1080 return RETURN_ERR;
1081 }
developera3511852023-06-14 14:12:59 +08001082 } else {
1083 output[0] = '\0';
1084 }
1085 }
developerfde01262023-05-22 15:15:24 +08001086
developera3511852023-06-14 14:12:59 +08001087 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1088 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001089}
1090
developer72fb0bb2023-01-11 09:46:29 +08001091//For Getting Current Interface Name from corresponding hostapd configuration
1092static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1093{
developera3511852023-06-14 14:12:59 +08001094 char config_file[128] = {0};
developere40952c2023-06-15 18:46:43 +08001095 int res;
developer72fb0bb2023-01-11 09:46:29 +08001096
developera3511852023-06-14 14:12:59 +08001097 if (interface_name == NULL)
1098 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001099
developera3511852023-06-14 14:12:59 +08001100 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001101
developere40952c2023-06-15 18:46:43 +08001102 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1103 if (os_snprintf_error(sizeof(config_file), res)) {
1104 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1105 return RETURN_ERR;
1106 }
developera3511852023-06-14 14:12:59 +08001107 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1108 if (strlen(interface_name) == 0)
1109 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001110
developera3511852023-06-14 14:12:59 +08001111 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1112 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001113}
1114
developera1255e42023-05-13 17:45:02 +08001115static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1116{
developera3511852023-06-14 14:12:59 +08001117 char interface_name[IF_NAME_SIZE] = {0};
1118 char cmd[MAX_BUF_SIZE]={'\0'};
1119 char buf[MAX_CMD_SIZE]={'\0'};
1120 UCHAR channel = 0;
developere40952c2023-06-15 18:46:43 +08001121 int res;
developera1255e42023-05-13 17:45:02 +08001122
developera3511852023-06-14 14:12:59 +08001123 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1124 return RETURN_ERR;
1125 /*interface name to channel number*/
developere40952c2023-06-15 18:46:43 +08001126 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1127 if (os_snprintf_error(sizeof(cmd), res)) {
1128 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1129 return RETURN_ERR;
1130 }
1131
developera3511852023-06-14 14:12:59 +08001132 _syscmd(cmd, buf, sizeof(buf));
1133 channel = atoi(buf);
1134 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
developera1255e42023-05-13 17:45:02 +08001135 /*count dev number with the same channel*/
developere40952c2023-06-15 18:46:43 +08001136 res = snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1137 if (os_snprintf_error(sizeof(cmd), res)) {
1138 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1139 return RETURN_ERR;
1140 }
1141
developera3511852023-06-14 14:12:59 +08001142 _syscmd(cmd, buf, sizeof(buf));
1143 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1144 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1145 return RETURN_OK;
developera1255e42023-05-13 17:45:02 +08001146}
developer72fb0bb2023-01-11 09:46:29 +08001147
1148static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1149{
developera3511852023-06-14 14:12:59 +08001150 char interface_name[16] = {0};
1151 if (multiple_set == TRUE)
1152 return RETURN_OK;
1153 char cmd[MAX_CMD_SIZE]="", output[32]="";
1154 FILE *fp;
developere40952c2023-06-15 18:46:43 +08001155 int i, res;
developera3511852023-06-14 14:12:59 +08001156 //NOTE RELOAD should be done in ApplySSIDSettings
1157 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1158 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001159
1160 for (i=0; i<item_count; i++, list++) {
1161 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
1162 if (os_snprintf_error(sizeof(cmd), res)) {
1163 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1164 return RETURN_ERR;
1165 }
1166 if ((fp = popen(cmd, "r"))==NULL) {
developera3511852023-06-14 14:12:59 +08001167 perror("popen failed");
1168 return -1;
1169 }
developere40952c2023-06-15 18:46:43 +08001170 if (!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) {
1171 pclose(fp);
developera3511852023-06-14 14:12:59 +08001172 perror("fgets failed");
1173 return -1;
1174 }
developere40952c2023-06-15 18:46:43 +08001175 pclose(fp);
developera3511852023-06-14 14:12:59 +08001176 }
1177 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001178}
1179
developer7e4a2a62023-04-06 19:56:03 +08001180static int wifi_quick_reload_ap(int apIndex)
1181{
1182 char interface_name[IF_NAME_SIZE] = {0};
1183 char cmd[MAX_CMD_SIZE] = {0};
1184 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001185 int res;
developer7e4a2a62023-04-06 19:56:03 +08001186
1187 if (multiple_set == TRUE)
1188 return RETURN_OK;
1189
1190 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1191 return RETURN_ERR;
1192
developere40952c2023-06-15 18:46:43 +08001193 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1194 if (os_snprintf_error(sizeof(cmd), res)) {
1195 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1196 return RETURN_ERR;
1197 }
developer7e4a2a62023-04-06 19:56:03 +08001198 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1199 return RETURN_ERR;
1200
1201 return RETURN_OK;
1202}
1203
developer72fb0bb2023-01-11 09:46:29 +08001204static int wifi_reloadAp(int apIndex)
1205{
developera3511852023-06-14 14:12:59 +08001206 char interface_name[16] = {0};
developer22e0c672023-06-07 15:25:37 +08001207 int res;
1208
developera3511852023-06-14 14:12:59 +08001209 if (multiple_set == TRUE)
1210 return RETURN_OK;
1211 char cmd[MAX_CMD_SIZE]="";
1212 char buf[MAX_BUF_SIZE]="";
developer72fb0bb2023-01-11 09:46:29 +08001213
developera3511852023-06-14 14:12:59 +08001214 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1215 return RETURN_ERR;
1216 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
developer22e0c672023-06-07 15:25:37 +08001217 if (os_snprintf_error(sizeof(cmd), res)) {
1218 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1219 return RETURN_ERR;
1220 }
developera3511852023-06-14 14:12:59 +08001221 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1222 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001223
developera3511852023-06-14 14:12:59 +08001224 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001225 if (os_snprintf_error(sizeof(cmd), res)) {
1226 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1227 return RETURN_ERR;
1228 }
developera3511852023-06-14 14:12:59 +08001229 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1230 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001231
developera3511852023-06-14 14:12:59 +08001232 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001233 if (os_snprintf_error(sizeof(cmd), res)) {
1234 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1235 return RETURN_ERR;
1236 }
developera3511852023-06-14 14:12:59 +08001237 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1238 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001239
developera3511852023-06-14 14:12:59 +08001240 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001241}
1242
1243INT File_Reading(CHAR *file, char *Value)
1244{
developera3511852023-06-14 14:12:59 +08001245 FILE *fp = NULL;
1246 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1247 int count = 0;
developer72fb0bb2023-01-11 09:46:29 +08001248
developera3511852023-06-14 14:12:59 +08001249 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1250 fp = popen(file,"r");
1251 if(fp == NULL)
1252 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001253
developera3511852023-06-14 14:12:59 +08001254 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1255 {
1256 for(count=0;buf[count]!='\n';count++)
1257 copy_buf[count]=buf[count];
1258 copy_buf[count]='\0';
1259 }
1260 strcpy(Value,copy_buf);
1261 pclose(fp);
1262 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001263
developera3511852023-06-14 14:12:59 +08001264 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001265}
1266
1267void wifi_RestartHostapd_2G()
1268{
developera3511852023-06-14 14:12:59 +08001269 int Public2GApIndex = 4;
developer72fb0bb2023-01-11 09:46:29 +08001270
developera3511852023-06-14 14:12:59 +08001271 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1272 wifi_setApEnable(Public2GApIndex, FALSE);
1273 wifi_setApEnable(Public2GApIndex, TRUE);
1274 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001275}
1276
1277void wifi_RestartHostapd_5G()
1278{
developera3511852023-06-14 14:12:59 +08001279 int Public5GApIndex = 5;
developer72fb0bb2023-01-11 09:46:29 +08001280
developera3511852023-06-14 14:12:59 +08001281 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1282 wifi_setApEnable(Public5GApIndex, FALSE);
1283 wifi_setApEnable(Public5GApIndex, TRUE);
1284 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001285}
1286
1287void wifi_RestartPrivateWifi_2G()
1288{
developera3511852023-06-14 14:12:59 +08001289 int PrivateApIndex = 0;
developer72fb0bb2023-01-11 09:46:29 +08001290
developera3511852023-06-14 14:12:59 +08001291 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1292 wifi_setApEnable(PrivateApIndex, FALSE);
1293 wifi_setApEnable(PrivateApIndex, TRUE);
1294 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001295}
1296
1297void wifi_RestartPrivateWifi_5G()
1298{
developera3511852023-06-14 14:12:59 +08001299 int Private5GApIndex = 1;
developer72fb0bb2023-01-11 09:46:29 +08001300
developera3511852023-06-14 14:12:59 +08001301 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1302 wifi_setApEnable(Private5GApIndex, FALSE);
1303 wifi_setApEnable(Private5GApIndex, TRUE);
1304 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001305}
1306
1307static int writeBandWidth(int radioIndex,char *bw_value)
1308{
developera3511852023-06-14 14:12:59 +08001309 char buf[MAX_BUF_SIZE];
1310 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08001311 int res;
developer72fb0bb2023-01-11 09:46:29 +08001312
developere40952c2023-06-15 18:46:43 +08001313 res = snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1314 if (os_snprintf_error(sizeof(cmd), res)) {
1315 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1316 return RETURN_ERR;
1317 }
1318
1319 if (_syscmd(cmd, buf, sizeof(buf))) {
1320 res = snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1321 if (os_snprintf_error(sizeof(cmd), res)) {
1322 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1323 return RETURN_ERR;
1324 }
developera3511852023-06-14 14:12:59 +08001325 _syscmd(cmd, buf, sizeof(buf));
1326 return RETURN_OK;
1327 }
developer72fb0bb2023-01-11 09:46:29 +08001328
developer75bd10c2023-06-27 11:34:08 +08001329 res = snprintf(cmd, sizeof(cmd), "sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1330 if (os_snprintf_error(sizeof(cmd), res)) {
1331 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1332 return RETURN_ERR;
1333 }
developera3511852023-06-14 14:12:59 +08001334 _syscmd(cmd,buf,sizeof(buf));
1335 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001336}
1337
1338// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1339INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1340{
developera3511852023-06-14 14:12:59 +08001341 struct params params={'\0'};
1342 char config_file[MAX_BUF_SIZE] = {0};
1343 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08001344 int res;
developer72fb0bb2023-01-11 09:46:29 +08001345
developera3511852023-06-14 14:12:59 +08001346 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1347 // Copy the numeric value
1348 if (strlen (beaconRate) >= 5) {
1349 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1350 buf[strlen(beaconRate) - 4] = '\0';
developer9ce44382023-06-28 11:09:37 +08001351 } else if (strlen(beaconRate) > 0){
1352 strncpy(buf, beaconRate,sizeof(buf) - 1);
1353 buf[sizeof(buf) - 1] = '\0';
1354 } else
developera3511852023-06-14 14:12:59 +08001355 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001356
developera3511852023-06-14 14:12:59 +08001357 params.name = "beacon_rate";
1358 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1359 if (strncmp(buf, "5.5", 3) == 0) {
developere40952c2023-06-15 18:46:43 +08001360 res = snprintf(buf, sizeof(buf), "55");
1361 if (os_snprintf_error(sizeof(buf), res)) {
1362 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1363 return RETURN_ERR;
1364 }
developera3511852023-06-14 14:12:59 +08001365 params.value = buf;
1366 } else {
developer32f2a182023-06-27 19:50:41 +08001367 if (strlen(buf) >= (MAX_BUF_SIZE - 1)) {
1368 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
1369 return RETURN_ERR;
1370 }
1371 strncat(buf, "0", sizeof(buf) - strlen(buf) - 1);
developera3511852023-06-14 14:12:59 +08001372 params.value = buf;
1373 }
developer72fb0bb2023-01-11 09:46:29 +08001374
developer32f2a182023-06-27 19:50:41 +08001375 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
1376 if (os_snprintf_error(sizeof(config_file), res)) {
1377 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1378 return RETURN_ERR;
1379 }
1380
developera3511852023-06-14 14:12:59 +08001381 wifi_hostapdWrite(config_file, &params, 1);
1382 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1383 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001384
developera3511852023-06-14 14:12:59 +08001385 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001386}
1387
1388INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1389{
developera3511852023-06-14 14:12:59 +08001390 char config_file[128] = {'\0'};
1391 char temp_output[MAX_BUF_SIZE] = {'\0'};
1392 char buf[128] = {'\0'};
1393 char cmd[128] = {'\0'};
1394 int rate = 0;
developere40952c2023-06-15 18:46:43 +08001395 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08001396
developera3511852023-06-14 14:12:59 +08001397 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1398 if (NULL == beaconRate)
1399 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001400
developer75bd10c2023-06-27 11:34:08 +08001401 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
1402 if (os_snprintf_error(sizeof(config_file), res)) {
1403 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1404 return RETURN_ERR;
1405 }
developera3511852023-06-14 14:12:59 +08001406 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1407 phyId = radio_index_to_phy(radioIndex);
1408 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1409 if(strlen(buf) > 0) {
1410 if (strncmp(buf, "55", 2) == 0)
developere40952c2023-06-15 18:46:43 +08001411 res = snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
developera3511852023-06-14 14:12:59 +08001412 else {
1413 rate = strtol(buf, NULL, 10)/10;
developere40952c2023-06-15 18:46:43 +08001414 res = snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
developera3511852023-06-14 14:12:59 +08001415 }
developer75bd10c2023-06-27 11:34:08 +08001416 if (os_snprintf_error(sizeof(temp_output), res)) {
1417 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1418 return RETURN_ERR;
1419 }
developera3511852023-06-14 14:12:59 +08001420 } else {
1421 // config not set, so we would use lowest rate as default
developer75bd10c2023-06-27 11:34:08 +08001422 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1423 if (os_snprintf_error(sizeof(cmd), res)) {
1424 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1425 return RETURN_ERR;
1426 }
developera3511852023-06-14 14:12:59 +08001427 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08001428 res = snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
developer75bd10c2023-06-27 11:34:08 +08001429 if (os_snprintf_error(sizeof(temp_output), res)) {
1430 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1431 return RETURN_ERR;
1432 }
developera3511852023-06-14 14:12:59 +08001433 }
developer75bd10c2023-06-27 11:34:08 +08001434
developera3511852023-06-14 14:12:59 +08001435 strncpy(beaconRate, temp_output, strlen(temp_output));
1436 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001437
developera3511852023-06-14 14:12:59 +08001438 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001439}
1440
1441INT wifi_setLED(INT radioIndex, BOOL enable)
1442{
1443 return 0;
1444}
1445INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
1446{
1447 return RETURN_OK;
1448}
1449/**********************************************************************************
1450 *
developer69b61b02023-03-07 17:17:44 +08001451 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001452 *
1453**********************************************************************************/
1454//---------------------------------------------------------------------------------------------------
1455//Wifi system api
1456//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 +08001457INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001458{
developere40952c2023-06-15 18:46:43 +08001459 int res;
1460
developera3511852023-06-14 14:12:59 +08001461 if(!output_string)
1462 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001463 res = snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1464 if (os_snprintf_error(64, res)) {
1465 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1466 return RETURN_ERR;
1467 }
developer72fb0bb2023-01-11 09:46:29 +08001468
developera3511852023-06-14 14:12:59 +08001469 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001470}
1471
1472
1473/* wifi_factoryReset() function */
1474/**
developer69b61b02023-03-07 17:17:44 +08001475* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001476* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1477*
1478* @param None
1479*
1480* @return The status of the operation.
1481* @retval RETURN_OK if successful.
1482* @retval RETURN_ERR if any error is detected
1483*
1484* @execution Synchronous
1485* @sideeffect None
1486*
1487* @note This function must not suspend and must not invoke any blocking system
1488* calls. It should probably just send a message to a driver event handler task.
1489*
1490*/
1491INT wifi_factoryReset()
1492{
developer47cc27a2023-05-17 23:09:58 +08001493 char cmd[MAX_CMD_SIZE] = {0};
1494 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001495 int res;
developer72fb0bb2023-01-11 09:46:29 +08001496
developer47cc27a2023-05-17 23:09:58 +08001497 /*delete running hostapd conf files*/
1498 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
developere40952c2023-06-15 18:46:43 +08001499 res = snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1500 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1501 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1502 return RETURN_ERR;
1503 }
1504
developer47cc27a2023-05-17 23:09:58 +08001505 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001506
developer47cc27a2023-05-17 23:09:58 +08001507 wifi_PrepareDefaultHostapdConfigs();
1508 wifi_psk_file_reset();
1509
1510 memset(cmd, 0, MAX_CMD_SIZE);
1511 memset(buf, 0, MAX_BUF_SIZE);
1512
developere40952c2023-06-15 18:46:43 +08001513 res = snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1514 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1515 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1516 return RETURN_ERR;
1517 }
1518
developer47cc27a2023-05-17 23:09:58 +08001519 _syscmd(cmd, buf, sizeof(buf));
1520
1521 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001522}
1523
1524/* wifi_factoryResetRadios() function */
1525/**
1526* @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.
1527*
1528* @param None
1529* @return The status of the operation
1530* @retval RETURN_OK if successful
1531* @retval RETURN_ERR if any error is detected
1532*
1533* @execution Synchronous
1534*
1535* @sideeffect None
1536*
1537* @note This function must not suspend and must not invoke any blocking system
1538* calls. It should probably just send a message to a driver event handler task.
1539*
1540*/
1541INT wifi_factoryResetRadios()
1542{
developera3511852023-06-14 14:12:59 +08001543 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1544 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001545
developera3511852023-06-14 14:12:59 +08001546 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001547}
1548
developerfead3972023-05-25 20:15:02 +08001549ULONG get_radio_reset_cnt(int radioIndex)
1550{
1551 char cmd[MAX_CMD_SIZE] = {0};
1552 char buf[MAX_BUF_SIZE] = {0};
1553 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001554 int res;
developerfead3972023-05-25 20:15:02 +08001555
developere40952c2023-06-15 18:46:43 +08001556 res = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developerfead3972023-05-25 20:15:02 +08001557 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001558 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1559 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1560 return RETURN_ERR;
1561 }
1562
developerfead3972023-05-25 20:15:02 +08001563 _syscmd(cmd, buf, sizeof(buf));
1564
1565 if (strlen(buf) == 0)
1566 return 0;
1567 else {
1568 reset_count = atol(buf);
1569 return reset_count;
1570 }
1571}
1572void update_radio_reset_cnt(int radioIndex)
1573{
1574 char cmd[MAX_CMD_SIZE] = {0};
1575 char buf[MAX_BUF_SIZE] = {0};
1576 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001577 int res;
developerfead3972023-05-25 20:15:02 +08001578
developere40952c2023-06-15 18:46:43 +08001579 res = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
developerfead3972023-05-25 20:15:02 +08001580 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001581 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1582 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1583 return;
1584 }
1585
developerfead3972023-05-25 20:15:02 +08001586 _syscmd(cmd, buf, sizeof(buf));
1587
1588 if (strlen(buf) == 0)
developere40952c2023-06-15 18:46:43 +08001589 res = snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
developerfead3972023-05-25 20:15:02 +08001590 else {
1591 reset_count = atol(buf);
1592 reset_count++;
developere40952c2023-06-15 18:46:43 +08001593 res = snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
1594 }
1595 if (os_snprintf_error(sizeof(cmd), res)) {
1596 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1597 return;
developerfead3972023-05-25 20:15:02 +08001598 }
1599 _syscmd(cmd, buf, sizeof(buf));
1600}
developer72fb0bb2023-01-11 09:46:29 +08001601
1602/* wifi_factoryResetRadio() function */
1603/**
1604* @description Restore selected radio parameters without touching access point parameters
1605*
1606* @param radioIndex - Index of Wi-Fi Radio channel
1607*
1608* @return The status of the operation.
1609* @retval RETURN_OK if successful.
1610* @retval RETURN_ERR if any error is detected
1611*
1612* @execution Synchronous.
1613* @sideeffect None.
1614*
1615* @note This function must not suspend and must not invoke any blocking system
1616* calls. It should probably just send a message to a driver event handler task.
1617*
1618*/
1619INT wifi_factoryResetRadio(int radioIndex) //RDKB
1620{
developer47cc27a2023-05-17 23:09:58 +08001621 char cmd[MAX_CMD_SIZE] = {0};
1622 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001623 int res;
developer72fb0bb2023-01-11 09:46:29 +08001624
developer47cc27a2023-05-17 23:09:58 +08001625 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001626
developerb2977562023-05-24 17:54:12 +08001627 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001628
developerb2977562023-05-24 17:54:12 +08001629 /*reset gi setting*/
developere40952c2023-06-15 18:46:43 +08001630 res = snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
1631 if (os_snprintf_error(sizeof(cmd), res)) {
1632 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1633 return RETURN_ERR;
1634 }
1635
developer47cc27a2023-05-17 23:09:58 +08001636 _syscmd(cmd, buf, sizeof(buf));
1637
developerb2977562023-05-24 17:54:12 +08001638 /*TBD: check mbss issue*/
1639 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08001640 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08001641
developer47cc27a2023-05-17 23:09:58 +08001642 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1643 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001644}
1645
1646/* wifi_initRadio() function */
1647/**
1648* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001649* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001650* different hardware implementations may have different initilization requirements.
1651* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1652*
1653* @return The status of the operation.
1654* @retval RETURN_OK if successful.
1655* @retval RETURN_ERR if any error is detected
1656*
1657* @execution Synchronous.
1658* @sideeffect None.
1659*
1660* @note This function must not suspend and must not invoke any blocking system
1661* calls. It should probably just send a message to a driver event handler task.
1662*
1663*/
1664INT wifi_initRadio(INT radioIndex)
1665{
developera3511852023-06-14 14:12:59 +08001666 //TODO: Initializes the wifi subsystem (for specified radio)
1667 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001668}
1669
developer17038e62023-03-02 14:43:43 +08001670static void
1671wifi_ParseProfile(void)
1672{
developere40952c2023-06-15 18:46:43 +08001673 int i, res;
developera3511852023-06-14 14:12:59 +08001674 int max_radio_num = 0;
1675 int card_idx;
1676 int band_idx;
1677 int phy_idx = 0;
1678 int wireless_mode = 0;
1679 char buf[MAX_BUF_SIZE] = {0};
1680 char chip_name[12];
1681 char card_profile[MAX_BUF_SIZE] = {0};
1682 char band_profile[MAX_BUF_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001683
developera3511852023-06-14 14:12:59 +08001684 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001685
developera3511852023-06-14 14:12:59 +08001686 memset(main_prefix, 0, sizeof(main_prefix));
1687 memset(ext_prefix, 0, sizeof(ext_prefix));
1688 memset(default_ssid, 0, sizeof(default_ssid));
1689 for (i = 0; i < MAX_NUM_RADIOS; i++)
1690 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001691
developera3511852023-06-14 14:12:59 +08001692 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1693 /* LOG */
developer17038e62023-03-02 14:43:43 +08001694 return;
developera3511852023-06-14 14:12:59 +08001695 }
developer17038e62023-03-02 14:43:43 +08001696
developera3511852023-06-14 14:12:59 +08001697 for (card_idx = 0; card_idx < 3; card_idx++) {
developere40952c2023-06-15 18:46:43 +08001698 res = snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1699 if (os_snprintf_error(sizeof(buf), res)) {
1700 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1701 return;
1702 }
developera3511852023-06-14 14:12:59 +08001703 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1704 break;
1705 }
developere40952c2023-06-15 18:46:43 +08001706 res = snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1707 if (os_snprintf_error(sizeof(buf), res)) {
1708 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1709 return;
1710 }
developera3511852023-06-14 14:12:59 +08001711 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1712 break;
1713 }
1714 for (band_idx = 0; band_idx < 3; band_idx++) {
developere40952c2023-06-15 18:46:43 +08001715 res = snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1716 if (os_snprintf_error(sizeof(buf), res)) {
1717 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1718 return;
1719 }
developera3511852023-06-14 14:12:59 +08001720 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1721 /* LOG */
1722 break;
1723 }
developer17038e62023-03-02 14:43:43 +08001724
developere40952c2023-06-15 18:46:43 +08001725 res = snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1726 if (os_snprintf_error(sizeof(buf), res)) {
1727 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1728 return;
1729 }
developera3511852023-06-14 14:12:59 +08001730 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1731 /* LOG */
1732 }
developer17038e62023-03-02 14:43:43 +08001733
developere40952c2023-06-15 18:46:43 +08001734 res = snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1735 if (os_snprintf_error(sizeof(buf), res)) {
1736 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1737 return;
1738 }
developera3511852023-06-14 14:12:59 +08001739 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1740 /* LOG */
1741 }
developer17038e62023-03-02 14:43:43 +08001742
developera3511852023-06-14 14:12:59 +08001743 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1744 /* LOG */
1745 }
1746 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1747 /* LOG */
1748 }
developer745f0bd2023-03-06 14:32:53 +08001749
developera3511852023-06-14 14:12:59 +08001750 wireless_mode = atoi(buf);
1751 switch (wireless_mode) {
1752 case 22:
1753 case 16:
1754 case 6:
1755 case 4:
1756 case 1:
1757 radio_band[phy_idx] = band_2_4;
1758 break;
1759 case 23:
1760 case 17:
1761 case 14:
1762 case 11:
1763 case 2:
1764 radio_band[phy_idx] = band_5;
1765 break;
1766 case 24:
1767 case 18:
1768 radio_band[phy_idx] = band_6;
1769 break;
1770 }
1771 phy_idx++;
1772 }
1773 }
developer17038e62023-03-02 14:43:43 +08001774
developera3511852023-06-14 14:12:59 +08001775 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001776}
1777
1778static void
1779wifi_PrepareDefaultHostapdConfigs(void)
1780{
developere40952c2023-06-15 18:46:43 +08001781 int radio_idx, res;
developer0132ed92023-03-21 13:48:53 +08001782 int bss_idx;
1783 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001784 char buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001785 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer0132ed92023-03-21 13:48:53 +08001786 char ssid[MAX_BUF_SIZE] = {0};
1787 char interface[32] = {0};
1788 char ret_buf[MAX_BUF_SIZE] = {0};
1789 char psk_file[64] = {0};
1790 struct params params[3];
developer17038e62023-03-02 14:43:43 +08001791
developer0132ed92023-03-21 13:48:53 +08001792 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1793 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001794
developer0132ed92023-03-21 13:48:53 +08001795 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001796 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001797
developere40952c2023-06-15 18:46:43 +08001798 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1799 if (os_snprintf_error(sizeof(config_file), res)) {
1800 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1801 return;
1802 }
1803 res = snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
1804 if (os_snprintf_error(sizeof(buf), res)) {
1805 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1806 return;
1807 }
developer47cc27a2023-05-17 23:09:58 +08001808 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001809
developer47cc27a2023-05-17 23:09:58 +08001810 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08001811 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1812 if (os_snprintf_error(sizeof(ssid), res)) {
1813 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1814 return;
1815 }
1816 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1817 if (os_snprintf_error(sizeof(interface), res)) {
1818 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1819 return;
1820 }
developer47cc27a2023-05-17 23:09:58 +08001821 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08001822 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1823 if (os_snprintf_error(sizeof(ssid), res)) {
1824 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1825 return;
1826 }
1827 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1828 if (os_snprintf_error(sizeof(interface), res)) {
1829 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1830 return;
1831 }
developer47cc27a2023-05-17 23:09:58 +08001832 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08001833 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1834 if (os_snprintf_error(sizeof(ssid), res)) {
1835 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1836 return;
1837 }
1838 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1839 if (os_snprintf_error(sizeof(interface), res)) {
1840 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1841 return;
1842 }
developer47cc27a2023-05-17 23:09:58 +08001843 }
developer17038e62023-03-02 14:43:43 +08001844
developer47cc27a2023-05-17 23:09:58 +08001845 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08001846 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
1847 if (os_snprintf_error(sizeof(psk_file), res)) {
1848 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1849 return;
1850 }
developer17038e62023-03-02 14:43:43 +08001851
developer47cc27a2023-05-17 23:09:58 +08001852 params[0].name = "ssid";
1853 params[0].value = ssid;
1854 params[1].name = "interface";
1855 params[1].value = interface;
1856 params[2].name = "wpa_psk_file";
1857 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001858
developer47cc27a2023-05-17 23:09:58 +08001859 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001860 }
1861 }
1862 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001863}
1864
1865static void
developer17038e62023-03-02 14:43:43 +08001866wifi_BringDownInterfacesForRadio(int radio_idx)
1867{
developera3511852023-06-14 14:12:59 +08001868 char cmd[MAX_BUF_SIZE] = {0};
1869 char ret_buf[MAX_BUF_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08001870 int res;
developerb758dfd2023-06-21 17:32:07 +08001871
developera3511852023-06-14 14:12:59 +08001872 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001873
developere40952c2023-06-15 18:46:43 +08001874 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1875 if (os_snprintf_error(sizeof(cmd), res)) {
1876 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1877 return;
1878 }
developer8a3bbbf2023-03-15 17:47:23 +08001879 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1880
developera3511852023-06-14 14:12:59 +08001881 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001882}
1883
1884
1885static void
1886wifi_BringDownInterfaces(void)
1887{
developera3511852023-06-14 14:12:59 +08001888 int radio_idx;
1889 int band_idx;
developer17038e62023-03-02 14:43:43 +08001890
developera3511852023-06-14 14:12:59 +08001891 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1892 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1893 band_idx = radio_index_to_band(radio_idx);
1894 if (band_idx < 0) {
1895 break;
1896 }
1897 wifi_BringDownInterfacesForRadio(radio_idx);
1898 }
1899 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001900}
1901
developerb2977562023-05-24 17:54:12 +08001902static void wifi_dat_file_reset_by_radio(char radio_idx)
1903{
developerb149d9d2023-06-06 16:14:22 +08001904 char cmd[MAX_CMD_SIZE * 2] = {0};
developerb2977562023-05-24 17:54:12 +08001905 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001906 char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
1907 char dat_file[MAX_SUB_CMD_SIZE]= {0};
developere40952c2023-06-15 18:46:43 +08001908 int res;
developerb2977562023-05-24 17:54:12 +08001909
developere40952c2023-06-15 18:46:43 +08001910 res = snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1911 if (os_snprintf_error(sizeof(rom_dat_file), res)) {
1912 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1913 return;
1914 }
1915 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
1916 if (os_snprintf_error(sizeof(dat_file), res)) {
1917 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1918 return;
1919 }
1920 res = snprintf(cmd, (MAX_CMD_SIZE * 2), "cp -rf %s %s", rom_dat_file, dat_file);
1921 if (os_snprintf_error((MAX_CMD_SIZE * 2), res)) {
1922 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1923 return;
1924 }
developerb2977562023-05-24 17:54:12 +08001925 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1926
1927}
1928
developer47cc27a2023-05-17 23:09:58 +08001929static void wifi_psk_file_reset()
1930{
1931 char cmd[MAX_CMD_SIZE] = {0};
1932 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001933 char psk_file[MAX_SUB_CMD_SIZE]= {0};
developer47cc27a2023-05-17 23:09:58 +08001934 char vap_idx = 0;
developere40952c2023-06-15 18:46:43 +08001935 int res;
developer47cc27a2023-05-17 23:09:58 +08001936
1937 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
developere40952c2023-06-15 18:46:43 +08001938 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1939 if (os_snprintf_error(sizeof(psk_file), res)) {
1940 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1941 return;
1942 }
developer47cc27a2023-05-17 23:09:58 +08001943
1944 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001945 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1946 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1947 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1948 return;
1949 }
developer47cc27a2023-05-17 23:09:58 +08001950 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1951 } else {
developere40952c2023-06-15 18:46:43 +08001952 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1953 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1954 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1955 return;
1956 }
1957
developer47cc27a2023-05-17 23:09:58 +08001958 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1959 }
1960 }
developerb2977562023-05-24 17:54:12 +08001961}
1962
developer8a3bbbf2023-03-15 17:47:23 +08001963static void wifi_vap_status_reset()
1964{
developera3511852023-06-14 14:12:59 +08001965 char cmd[MAX_CMD_SIZE] = {0};
1966 char ret_buf[MAX_BUF_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08001967 int radio_idx = 0;
developer8a3bbbf2023-03-15 17:47:23 +08001968 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08001969 int res;
developer8666b312023-03-24 14:05:31 +08001970
developer8a3bbbf2023-03-15 17:47:23 +08001971 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001972 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
1973 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1974 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1975 return;
1976 }
developer8a3bbbf2023-03-15 17:47:23 +08001977 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1978 } else {
developere40952c2023-06-15 18:46:43 +08001979 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
1980 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1981 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1982 return;
1983 }
developer8a3bbbf2023-03-15 17:47:23 +08001984 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1985 }
1986
1987 memset(cmd, 0, MAX_CMD_SIZE);
1988 memset(ret_buf, 0, MAX_BUF_SIZE);
1989
1990 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
developera3511852023-06-14 14:12:59 +08001991 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developere40952c2023-06-15 18:46:43 +08001992 res = snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
1993 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1994 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1995 return;
1996 }
developer8a3bbbf2023-03-15 17:47:23 +08001997 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1998 }
1999
developerfead3972023-05-25 20:15:02 +08002000}
2001
2002static void wifi_radio_reset_count_reset()
2003{
developera3511852023-06-14 14:12:59 +08002004 char cmd[MAX_CMD_SIZE] = {0};
2005 char ret_buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002006 int res;
developerfead3972023-05-25 20:15:02 +08002007
2008 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08002009 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE);
2010 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2011 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2012 return;
2013 }
developerfead3972023-05-25 20:15:02 +08002014 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2015 } else {
developere40952c2023-06-15 18:46:43 +08002016 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE);
2017 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2018 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2019 return;
2020 }
developerfead3972023-05-25 20:15:02 +08002021 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2022 }
developer8a3bbbf2023-03-15 17:47:23 +08002023}
developer17038e62023-03-02 14:43:43 +08002024
developer72fb0bb2023-01-11 09:46:29 +08002025// Initializes the wifi subsystem (all radios)
developera3511852023-06-14 14:12:59 +08002026INT wifi_init() //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002027{
developera3511852023-06-14 14:12:59 +08002028 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercc9a4f32023-05-30 17:40:02 +08002029 static int CallOnce = 1;
developera3511852023-06-14 14:12:59 +08002030 //Not intitializing macfilter for Turris-Omnia Platform for now
2031 //macfilter_init();
2032 if (CallOnce) {
developercc9a4f32023-05-30 17:40:02 +08002033 wifi_ParseProfile();
2034 wifi_PrepareDefaultHostapdConfigs();
2035 wifi_psk_file_reset();
2036 //system("/usr/sbin/iw reg set US");
2037 system("systemctl start hostapd.service");
2038 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002039
developercc9a4f32023-05-30 17:40:02 +08002040 wifi_vap_status_reset();
2041 wifi_radio_reset_count_reset();
2042 CallOnce = 0;
developera3511852023-06-14 14:12:59 +08002043 }
developer96b38512023-02-22 11:17:45 +08002044
developera3511852023-06-14 14:12:59 +08002045 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002046
developera3511852023-06-14 14:12:59 +08002047 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002048}
2049
2050/* wifi_reset() function */
2051/**
2052* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08002053* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08002054* different hardware implementations may have different requirements.
2055* Parameters : None
2056*
2057* @return The status of the operation.
2058* @retval RETURN_OK if successful.
2059* @retval RETURN_ERR if any error is detected
2060*
2061* @execution Synchronous.
2062* @sideeffect None.
2063*
2064* @note This function must not suspend and must not invoke any blocking system
2065* calls. It should probably just send a message to a driver event handler task.
2066*
2067*/
2068INT wifi_reset()
2069{
developer17038e62023-03-02 14:43:43 +08002070
developera3511852023-06-14 14:12:59 +08002071 wifi_BringDownInterfaces();
2072 sleep(2);
developer17038e62023-03-02 14:43:43 +08002073
developera3511852023-06-14 14:12:59 +08002074 //TODO: resets the wifi subsystem, deletes all APs
2075 system("systemctl stop hostapd.service");
2076 sleep(2);
developer17038e62023-03-02 14:43:43 +08002077
developera3511852023-06-14 14:12:59 +08002078 system("systemctl start hostapd.service");
2079 sleep(5);
developer17038e62023-03-02 14:43:43 +08002080
developera3511852023-06-14 14:12:59 +08002081 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08002082 wifi_psk_file_reset();
developera3511852023-06-14 14:12:59 +08002083 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002084
2085 wifi_vap_status_reset();
2086
developera3511852023-06-14 14:12:59 +08002087 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002088}
2089
2090/* wifi_down() function */
2091/**
2092* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08002093* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08002094* different hardware implementations may have different requirements.
2095*
2096* @param None
2097*
2098* @return The status of the operation
2099* @retval RETURN_OK if successful
2100* @retval RETURN_ERR if any error is detected
2101*
2102* @execution Synchronous
2103* @sideeffect None
2104*
2105* @note This function must not suspend and must not invoke any blocking system
2106* calls. It should probably just send a message to a driver event handler task.
2107*
2108*/
2109INT wifi_down()
2110{
developera3511852023-06-14 14:12:59 +08002111 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
2112 int max_num_radios = 0;
developerb2977562023-05-24 17:54:12 +08002113 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08002114
developerb2977562023-05-24 17:54:12 +08002115 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
2116 wifi_setRadioEnable(radioIndex, FALSE);
2117
developera3511852023-06-14 14:12:59 +08002118 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002119}
2120
2121
2122/* wifi_createInitialConfigFiles() function */
2123/**
2124* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08002125* and content of these files are implementation dependent. This function call is
2126* used to trigger this task if necessary. Some implementations may not need this
2127* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08002128* do nothing and return RETURN_OK.
2129*
2130* @param None
2131*
2132* @return The status of the operation
2133* @retval RETURN_OK if successful
2134* @retval RETURN_ERR if any error is detected
2135*
2136* @execution Synchronous
2137* @sideeffect None
2138*
2139* @note This function must not suspend and must not invoke any blocking system
2140* calls. It should probably just send a message to a driver event handler task.
2141*
2142*/
2143INT wifi_createInitialConfigFiles()
2144{
developera3511852023-06-14 14:12:59 +08002145 //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)
2146 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002147}
2148
developer7e4a2a62023-04-06 19:56:03 +08002149/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08002150INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
2151{
developera3511852023-06-14 14:12:59 +08002152 int ret;
developer72fb0bb2023-01-11 09:46:29 +08002153
developera3511852023-06-14 14:12:59 +08002154 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002155
developera3511852023-06-14 14:12:59 +08002156 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
2157 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08002158 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead CountryCode failed\n");
developera3511852023-06-14 14:12:59 +08002159 return RETURN_ERR;
2160 }
developer7e4a2a62023-04-06 19:56:03 +08002161
developera3511852023-06-14 14:12:59 +08002162 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002163
developera3511852023-06-14 14:12:59 +08002164 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002165}
2166
2167INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
2168{
developer7e4a2a62023-04-06 19:56:03 +08002169 /*Set wifi config. Wait for wifi reset to apply*/
developer7e4a2a62023-04-06 19:56:03 +08002170 struct params params;
2171 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002172 int ret = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002173
developer7e4a2a62023-04-06 19:56:03 +08002174 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002175
developer7e4a2a62023-04-06 19:56:03 +08002176 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
2177 printf("%s: input para error!!!\n", __func__);
2178 return RETURN_ERR;
2179 }
developer72fb0bb2023-01-11 09:46:29 +08002180
developerc79e9172023-06-06 19:48:03 +08002181 if (!strlen(CountryCode)) {
2182 memcpy(CountryCode, "US", strlen("US")); /*default set the code to US*/
2183 CountryCode[2] = '\0';
2184 }
developer72fb0bb2023-01-11 09:46:29 +08002185
developer7e4a2a62023-04-06 19:56:03 +08002186 params.name = "country_code";
2187 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08002188
developere40952c2023-06-15 18:46:43 +08002189 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2190 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
2191 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2192 return RETURN_ERR;
2193 }
developer7e4a2a62023-04-06 19:56:03 +08002194 ret = wifi_hostapdWrite(config_file, &params, 1);
2195
2196 if (ret) {
2197 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
2198 __func__, ret);
2199 }
2200
2201 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2202
2203 if (ret) {
2204 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
2205 __func__, ret);
2206 }
2207
2208 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2209
2210 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002211}
2212
2213INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
2214{
developera3511852023-06-14 14:12:59 +08002215 char interface_name[16] = {0};
2216 char channel_util_file[64] = {0};
2217 char cmd[128] = {0};
2218 char buf[128] = {0};
2219 char *line = NULL;
2220 char *param = NULL, *value = NULL;
developere40952c2023-06-15 18:46:43 +08002221 int read = 0, res;
developera3511852023-06-14 14:12:59 +08002222 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
developer86035662023-06-28 19:21:12 +08002223 unsigned long preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
developera3511852023-06-14 14:12:59 +08002224 size_t len = 0;
2225 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08002226
developera3511852023-06-14 14:12:59 +08002227 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002228
developera3511852023-06-14 14:12:59 +08002229 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2230 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002231 res = snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
2232 if (os_snprintf_error(sizeof(cmd), res)) {
2233 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2234 return RETURN_ERR;
2235 }
2236
developera3511852023-06-14 14:12:59 +08002237 _syscmd(cmd, buf, sizeof(buf));
2238 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08002239
developera3511852023-06-14 14:12:59 +08002240 memset(cmd, 0, sizeof(cmd));
2241 memset(buf, 0, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08002242 res = snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
2243 if (os_snprintf_error(sizeof(cmd), res)) {
2244 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2245 return RETURN_ERR;
2246 }
developera3511852023-06-14 14:12:59 +08002247 if ((f = popen(cmd, "r")) == NULL) {
2248 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
2249 return RETURN_ERR;
2250 }
developer72fb0bb2023-01-11 09:46:29 +08002251
developera3511852023-06-14 14:12:59 +08002252 read = getline(&line, &len, f);
2253 while (read != -1) {
2254 param = strtok(line, ":\t");
2255 value = strtok(NULL, " ");
2256 if(strstr(param, "frequency") != NULL) {
2257 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
2258 }
2259 if(strstr(param, "noise") != NULL) {
2260 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
2261 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
2262 }
2263 if(strstr(param, "channel active time") != NULL) {
2264 ActiveTime = strtol(value, NULL, 10);
2265 }
2266 if(strstr(param, "channel busy time") != NULL) {
2267 BusyTime = strtol(value, NULL, 10);
2268 }
2269 if(strstr(param, "channel transmit time") != NULL) {
2270 TransmitTime = strtol(value, NULL, 10);
2271 }
2272 read = getline(&line, &len, f);
2273 }
2274 pclose(f);
developer72fb0bb2023-01-11 09:46:29 +08002275
developera3511852023-06-14 14:12:59 +08002276 // The file should store the last active, busy and transmit time
developere40952c2023-06-15 18:46:43 +08002277 res = snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2278 if (os_snprintf_error(sizeof(channel_util_file), res)) {
2279 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2280 return RETURN_ERR;
2281 }
2282
developera3511852023-06-14 14:12:59 +08002283 f = fopen(channel_util_file, "r");
2284 if (f != NULL) {
2285 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002286 if (hal_strtoul(line, 10, &preActiveTime) < 0) {
2287 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2288 fclose(f);
2289 return RETURN_ERR;
2290 }
developera3511852023-06-14 14:12:59 +08002291 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002292 if (hal_strtoul(line, 10, &preBusyTime) < 0) {
2293 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2294 fclose(f);
2295 return RETURN_ERR;
2296 }
developera3511852023-06-14 14:12:59 +08002297 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002298 if (hal_strtoul(line, 10, &preTransmitTime) < 0) {
2299 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2300 fclose(f);
2301 return RETURN_ERR;
2302 }
developera3511852023-06-14 14:12:59 +08002303 fclose(f);
2304 }
developer72fb0bb2023-01-11 09:46:29 +08002305
developera3511852023-06-14 14:12:59 +08002306 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2307 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
developer72fb0bb2023-01-11 09:46:29 +08002308
developera3511852023-06-14 14:12:59 +08002309 f = fopen(channel_util_file, "w");
2310 if (f != NULL) {
developer86035662023-06-28 19:21:12 +08002311 if (fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime) < 0) {
2312 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
2313 }
2314 if (fclose(f) != 0) {
2315 wifi_debug(DEBUG_ERROR, "fclose fail\n");
2316 }
developera3511852023-06-14 14:12:59 +08002317 }
2318 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2319 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002320}
2321
2322/**********************************************************************************
2323 *
2324 * Wifi radio level function prototypes
2325 *
2326**********************************************************************************/
2327
2328//Get the total number of radios in this wifi subsystem
2329INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2330{
developera3511852023-06-14 14:12:59 +08002331 if (NULL == output)
2332 return RETURN_ERR;
2333 *output = MAX_NUM_RADIOS;
developer72fb0bb2023-01-11 09:46:29 +08002334
developera3511852023-06-14 14:12:59 +08002335 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002336}
2337
developer69b61b02023-03-07 17:17:44 +08002338//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002339INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2340{
developera3511852023-06-14 14:12:59 +08002341 if (NULL == output)
2342 return RETURN_ERR;
2343 *output = MAX_APS;
developer72fb0bb2023-01-11 09:46:29 +08002344
developera3511852023-06-14 14:12:59 +08002345 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002346}
2347
2348//Get the Radio enable config parameter
developera3511852023-06-14 14:12:59 +08002349INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002350{
developer56fbedb2023-05-30 16:47:05 +08002351 char interface_name[16] = {0};
2352 char buf[128] = {0}, cmd[128] = {0};
2353 int apIndex;
2354 int max_radio_num = 0;
developer75bd10c2023-06-27 11:34:08 +08002355 int res;
developer3a85ab82023-05-25 11:59:38 +08002356
developer56fbedb2023-05-30 16:47:05 +08002357 if (NULL == output_bool)
2358 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002359
developer56fbedb2023-05-30 16:47:05 +08002360 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08002361
developer56fbedb2023-05-30 16:47:05 +08002362 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002363
developer56fbedb2023-05-30 16:47:05 +08002364 if (radioIndex >= max_radio_num)
2365 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002366
developer56fbedb2023-05-30 16:47:05 +08002367 /* loop all interface in radio, if any is enable, reture true, else return false */
2368 for(apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num)
2369 {
2370 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2371 continue;
2372 memset(cmd, 0, sizeof(cmd));
developer75bd10c2023-06-27 11:34:08 +08002373 res = snprintf(cmd, sizeof(cmd), "ifconfig %s 2> /dev/null | grep UP", interface_name);
2374 if (os_snprintf_error(sizeof(cmd), res)) {
2375 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2376 return RETURN_ERR;
2377 }
developer56fbedb2023-05-30 16:47:05 +08002378 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? FALSE : TRUE;
2379 if (*output_bool == TRUE)
2380 break;
2381 }
2382
2383 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002384}
2385
developere82c0ca2023-05-10 16:25:35 +08002386typedef long time_t;
2387static time_t radio_up_time[MAX_NUM_RADIOS];
2388
developer72fb0bb2023-01-11 09:46:29 +08002389INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2390{
developera3511852023-06-14 14:12:59 +08002391 char interface_name[16] = {0};
2392 char cmd[MAX_CMD_SIZE] = {0};
2393 char buf[MAX_BUF_SIZE] = {0};
2394 int apIndex;
2395 int max_radio_num = 0;
developere40952c2023-06-15 18:46:43 +08002396 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002397
developera3511852023-06-14 14:12:59 +08002398 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002399
developera3511852023-06-14 14:12:59 +08002400 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002401
developera3511852023-06-14 14:12:59 +08002402 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002403
developera3511852023-06-14 14:12:59 +08002404 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002405
2406 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2407 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002408
2409 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
2410 if (os_snprintf_error(sizeof(cmd), res)) {
2411 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2412 return RETURN_ERR;
2413 }
developer47cc27a2023-05-17 23:09:58 +08002414
developer8a3bbbf2023-03-15 17:47:23 +08002415 _syscmd(cmd, buf, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +08002416 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08002417 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
2418 if (os_snprintf_error(sizeof(cmd), res)) {
2419 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2420 return RETURN_ERR;
2421 }
developer56fbedb2023-05-30 16:47:05 +08002422 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002423 if(strncmp(buf, "OK", 2))
developer75bd10c2023-06-27 11:34:08 +08002424 wifi_debug(DEBUG_ERROR, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002425 } else {
developere82c0ca2023-05-10 16:25:35 +08002426 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developera3511852023-06-14 14:12:59 +08002427 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2428 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002429
developer8a3bbbf2023-03-15 17:47:23 +08002430 memset(cmd, 0, MAX_CMD_SIZE);
2431 memset(buf, 0, MAX_BUF_SIZE);
2432
developere40952c2023-06-15 18:46:43 +08002433 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2434 if (os_snprintf_error(sizeof(cmd), res)) {
2435 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2436 return RETURN_ERR;
2437 }
developera3511852023-06-14 14:12:59 +08002438 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002439
developera3511852023-06-14 14:12:59 +08002440 if(*buf == '1') {
developere40952c2023-06-15 18:46:43 +08002441 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
2442 if (os_snprintf_error(sizeof(cmd), res)) {
2443 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2444 return RETURN_ERR;
2445 }
developer56fbedb2023-05-30 16:47:05 +08002446 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002447
2448 memset(cmd, 0, MAX_CMD_SIZE);
2449 memset(buf, 0, MAX_BUF_SIZE);
2450
developere40952c2023-06-15 18:46:43 +08002451 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
developera3511852023-06-14 14:12:59 +08002452 phyId, apIndex);
developere40952c2023-06-15 18:46:43 +08002453 if (os_snprintf_error(sizeof(cmd), res)) {
2454 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2455 return RETURN_ERR;
2456 }
developera3511852023-06-14 14:12:59 +08002457 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002458
developera3511852023-06-14 14:12:59 +08002459 }
2460 }
developere82c0ca2023-05-10 16:25:35 +08002461 time(&radio_up_time[radioIndex]);
developera3511852023-06-14 14:12:59 +08002462 }
developer72fb0bb2023-01-11 09:46:29 +08002463
developera3511852023-06-14 14:12:59 +08002464 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2465 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002466}
2467
2468//Get the Radio enable status
2469INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2470{
developera3511852023-06-14 14:12:59 +08002471 if (NULL == output_bool)
2472 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002473
developera3511852023-06-14 14:12:59 +08002474 return wifi_getRadioEnable(radioIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08002475}
2476
2477//Get the Radio Interface name from platform, eg "wlan0"
2478INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2479{
developera3511852023-06-14 14:12:59 +08002480 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2481 return RETURN_ERR;
2482 return wifi_GetInterfaceName(radioIndex, output_string);
developer72fb0bb2023-01-11 09:46:29 +08002483}
2484
developer6e578302023-06-21 10:11:16 +08002485int mtk_get_vow_info_callback(struct nl_msg *msg, void *data)
2486{
2487 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2488 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX + 1];
2489 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2490 int err = 0;
2491 struct vow_info *vow_info = NULL;
2492 struct mtk_nl80211_cb_data *cb_data = data;
2493
2494 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2495 genlmsg_attrlen(gnlh, 0), NULL);
2496 if (err < 0) {
2497 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
2498 return err;
2499 }
2500
2501 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2502 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX,
2503 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2504 if (err < 0){
2505 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX fails\n");
2506 return err;
2507 }
2508
2509 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]) {
2510 vow_info = (struct vow_info *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]);
2511 memmove(cb_data->out_buf, vow_info, sizeof(struct vow_info));
2512 }
2513 }
2514
2515 return 0;
2516}
2517
2518INT mtk_wifi_set_air_time_management(
2519 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
2520 char* data, INT len, void *output)
2521{
2522 char inf_name[IF_NAME_SIZE] = {0};
2523 unsigned int if_idx = 0;
2524 int ret = -1;
2525 struct unl unl_ins;
2526 struct nl_msg *msg = NULL;
2527 struct nlattr * msg_data = NULL;
2528 struct mtk_nl80211_param param;
2529
2530 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
2531 return RETURN_ERR;
2532 if_idx = if_nametoindex(inf_name);
2533 if (!if_idx) {
2534 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
2535 return RETURN_ERR;
2536 }
2537 /*init mtk nl80211 vendor cmd*/
2538 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_VOW;
2539 param.if_type = NL80211_ATTR_IFINDEX;
2540 param.if_idx = if_idx;
2541
2542 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
2543 if (ret) {
2544 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
2545 return RETURN_ERR;
2546 }
2547 /*add mtk vendor cmd data*/
2548 if (nla_put(msg, vendor_data_attr, len, data)) {
2549 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
2550 nlmsg_free(msg);
2551 goto err;
2552 }
2553
2554 /*send mtk nl80211 vendor msg*/
2555 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
2556 if (ret) {
2557 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
2558 goto err;
2559 }
2560 /*deinit mtk nl80211 vendor msg*/
2561 mtk_nl80211_deint(&unl_ins);
2562 wifi_debug(DEBUG_INFO, "send cmd success.\n");
2563
2564 return RETURN_OK;
2565err:
2566 mtk_nl80211_deint(&unl_ins);
2567 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
2568 return RETURN_ERR;
2569}
2570
2571//Get the ATM(Air Time Management) Capable.
2572INT wifi_getATMCapable(BOOL *output_bool)
2573{
2574 if (NULL == output_bool)
2575 return RETURN_ERR;
2576 *output_bool = TRUE;
2577
2578 return RETURN_OK;
2579}
2580
2581INT wifi_setATMEnable(BOOL enable)
2582{
2583 int max_radio_num = 0;
2584 int radio_idx = 0;
2585 char dat_file[MAX_BUF_SIZE] = {0};
2586 int res;
2587 struct params params[2];
2588
2589 wifi_getMaxRadioNumber(&max_radio_num);
2590 for (radio_idx = 0; radio_idx < max_radio_num; radio_idx++) {
2591 if (mtk_wifi_set_air_time_management
2592 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO,
2593 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
2594 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
2595 return RETURN_ERR;
2596 }
2597
2598 if (mtk_wifi_set_air_time_management
2599 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_BW_EN_INFO,
2600 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
2601 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
2602 return RETURN_ERR;
2603 }
2604
2605 params[0].name = "VOW_Airtime_Fairness_En";
2606 params[0].value = enable ? "1" : "0";
2607 params[1].name = "VOW_BW_Ctrl";
2608 params[1].value = enable ? "1" : "0";
2609
2610 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
2611 if (os_snprintf_error(sizeof(dat_file), res)) {
2612 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2613 return RETURN_ERR;
2614 }
2615 wifi_datfileWrite(dat_file, params, 2);
2616 }
2617
2618 return RETURN_OK;
2619}
2620
2621INT wifi_getATMEnable(BOOL *output_enable)
2622{
2623 int max_radio_num = 0;
2624 int radio_idx = 0;
2625 struct vow_info vow_info;
2626 struct vow_info get_vow_info;
2627 struct mtk_nl80211_cb_data cb_data;
2628
2629 if (output_enable == NULL)
2630 return RETURN_ERR;
2631
2632 wifi_getMaxRadioNumber(&max_radio_num);
2633
2634 *output_enable = FALSE;
2635
2636 memset(&vow_info, 0, sizeof(struct vow_info));
2637
2638 cb_data.out_buf = (char *)&vow_info;
2639 cb_data.out_len = sizeof(struct vow_info);
2640
2641 for (radio_idx = 0; radio_idx < max_radio_num; radio_idx++) {
2642 if (mtk_wifi_set_air_time_management
2643 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2644 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2645 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2646 return RETURN_ERR;
2647 }
2648
2649 if (vow_info.atf_en == TRUE || vow_info.bw_en == TRUE) {
2650 *output_enable = TRUE;
2651 break;
2652 }
2653 }
2654
2655 return RETURN_OK;
2656}
2657
2658UINT apidx_to_group(INT apIndex)
2659{
2660 int max_radio_num = 0;
2661 unsigned int group = 0;
2662
2663 wifi_getMaxRadioNumber(&max_radio_num);
2664 group = apIndex / max_radio_num + 5 * (apIndex % max_radio_num);
2665
2666 return group;
2667}
2668
2669INT wifi_setApATMAirTimePercent(INT apIndex, UINT ap_AirTimePercent)
2670{
2671 struct vow_group_en_param atc_en_param;
2672 struct vow_ratio_param radio_param;
2673 unsigned int group = 0;
2674 //BOOL ATM_enable = FALSE;
2675
2676 if (ap_AirTimePercent < 5 || ap_AirTimePercent > 100) {
2677 wifi_debug(DEBUG_ERROR, "invalid ait time percent!\n");
2678 return RETURN_ERR;
2679 }
2680
2681 /* mt7990 support 15 group now*/
2682 group = apidx_to_group(apIndex);
2683
2684 if (group > 15) {
2685 wifi_debug(DEBUG_ERROR, "invalid group!\n");
2686 return RETURN_ERR;
2687 }
2688
2689 atc_en_param.group = group;
2690 atc_en_param.en = 1;
2691 if (mtk_wifi_set_air_time_management
2692 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO,
2693 NULL, (char *)&atc_en_param, sizeof(struct vow_group_en_param), NULL)!= RETURN_OK) {
2694 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO cmd fails\n");
2695 return RETURN_ERR;
2696 }
2697
2698 radio_param.group = group;
2699 radio_param.ratio = ap_AirTimePercent;
2700 if (mtk_wifi_set_air_time_management
2701 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO,
2702 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
2703 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO cmd fails\n");
2704 return RETURN_ERR;
2705 }
2706
2707 if (mtk_wifi_set_air_time_management
2708 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO,
2709 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
2710 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO cmd fails\n");
2711 return RETURN_ERR;
2712 }
2713
2714 return RETURN_OK;
2715}
2716
2717INT wifi_getApATMAirTimePercent(INT apIndex, UINT *output_ap_AirTimePercent)
2718{
2719 unsigned int group = 0;
2720 struct vow_info get_vow_info, vow_info;
2721 struct mtk_nl80211_cb_data cb_data;
2722
2723 if (output_ap_AirTimePercent == NULL)
2724 return RETURN_ERR;
2725
2726 group = apidx_to_group(apIndex);
2727 if (group > 15) {
2728 wifi_debug(DEBUG_ERROR, "invalid group!\n");
2729 return RETURN_ERR;
2730 }
2731
2732 memset(&vow_info, 0, sizeof(struct vow_info));
2733 memset(&get_vow_info, 0, sizeof(struct vow_info));
2734
2735 cb_data.out_buf = (char *)&vow_info;
2736 cb_data.out_len = sizeof(struct vow_info);
2737
2738 get_vow_info.group = group;
2739
2740 if (mtk_wifi_set_air_time_management
2741 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2742 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2743 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2744 return RETURN_ERR;
2745 }
2746
2747 *output_ap_AirTimePercent = vow_info.ratio;
2748
2749 return RETURN_ERR;
2750}
2751
developer9ce44382023-06-28 11:09:37 +08002752
developer72fb0bb2023-01-11 09:46:29 +08002753//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2754//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.
2755INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2756{
developera3511852023-06-14 14:12:59 +08002757 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2758 // For max bit rate, we should always choose the best MCS
2759 char mode[64] = {0};
2760 char channel_bandwidth_str[64] = {0};
2761 UINT mode_map = 0;
2762 UINT num_subcarrier = 0;
2763 UINT code_bits = 0;
2764 float code_rate = 0; // use max code rate
2765 int NSS = 0;
2766 UINT Symbol_duration = 0;
2767 UINT GI_duration = 0;
2768 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2769 BOOL enable = FALSE;
2770 float bit_rate = 0;
developere40952c2023-06-15 18:46:43 +08002771 int ant_bitmap = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002772
developera3511852023-06-14 14:12:59 +08002773 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2774 if (NULL == output_string)
2775 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002776
developera3511852023-06-14 14:12:59 +08002777 wifi_getRadioEnable(radioIndex, &enable);
2778 if (enable == FALSE) {
developere40952c2023-06-15 18:46:43 +08002779 res = snprintf(output_string, 64, "0 Mb/s");
2780 if (os_snprintf_error(64, res)) {
2781 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2782 return RETURN_ERR;
2783 }
developera3511852023-06-14 14:12:59 +08002784 return RETURN_OK;
2785 }
developer72fb0bb2023-01-11 09:46:29 +08002786
developera3511852023-06-14 14:12:59 +08002787 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08002788 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +08002789 return RETURN_ERR;
2790 }
developer72fb0bb2023-01-11 09:46:29 +08002791
developera3511852023-06-14 14:12:59 +08002792 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08002793 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +08002794 return RETURN_ERR;
2795 }
developer72fb0bb2023-01-11 09:46:29 +08002796
developera3511852023-06-14 14:12:59 +08002797 if (gi == wifi_guard_interval_3200)
2798 GI_duration = 32;
2799 else if (gi == wifi_guard_interval_1600)
2800 GI_duration = 16;
2801 else if (gi == wifi_guard_interval_800)
2802 GI_duration = 8;
2803 else // auto, 400
2804 GI_duration = 4;
developer72fb0bb2023-01-11 09:46:29 +08002805
developera3511852023-06-14 14:12:59 +08002806 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08002807 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error\n");
developera3511852023-06-14 14:12:59 +08002808 return RETURN_ERR;
2809 }
developer72fb0bb2023-01-11 09:46:29 +08002810
developera3511852023-06-14 14:12:59 +08002811 if (strstr(channel_bandwidth_str, "80+80") != NULL)
developer32f2a182023-06-27 19:50:41 +08002812 memcpy(channel_bandwidth_str, "160", strlen("160"));
developer72fb0bb2023-01-11 09:46:29 +08002813
developera3511852023-06-14 14:12:59 +08002814 if (mode_map & WIFI_MODE_AX) {
2815 if (strstr(channel_bandwidth_str, "160") != NULL)
2816 num_subcarrier = 1960;
2817 else if (strstr(channel_bandwidth_str, "80") != NULL)
2818 num_subcarrier = 980;
2819 else if (strstr(channel_bandwidth_str, "40") != NULL)
2820 num_subcarrier = 468;
2821 else if (strstr(channel_bandwidth_str, "20") != NULL)
2822 num_subcarrier = 234;
2823 code_bits = 10;
2824 code_rate = (float)5/6;
2825 Symbol_duration = 128;
2826 GI_duration = 8;/*HE no GI 400ns*/
2827 } else if (mode_map & WIFI_MODE_AC) {
2828 if (strstr(channel_bandwidth_str, "160") != NULL)
2829 num_subcarrier = 468;
2830 else if (strstr(channel_bandwidth_str, "80") != NULL)
2831 num_subcarrier = 234;
2832 else if (strstr(channel_bandwidth_str, "40") != NULL)
2833 num_subcarrier = 108;
2834 else if (strstr(channel_bandwidth_str, "20") != NULL)
2835 num_subcarrier = 52;
2836 code_bits = 8;
2837 code_rate = (float)5/6;
2838 Symbol_duration = 32;
2839 } else if (mode_map & WIFI_MODE_N) {
2840 if (strstr(channel_bandwidth_str, "160") != NULL)
2841 num_subcarrier = 468;
2842 else if (strstr(channel_bandwidth_str, "80") != NULL)
2843 num_subcarrier = 234;
2844 else if (strstr(channel_bandwidth_str, "40") != NULL)
2845 num_subcarrier = 108;
2846 else if (strstr(channel_bandwidth_str, "20") != NULL)
2847 num_subcarrier = 52;
2848 code_bits = 6;
2849 code_rate = (float)3/4;
2850 Symbol_duration = 32;
2851 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2852 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
developere40952c2023-06-15 18:46:43 +08002853 res = snprintf(output_string, 64, "65 Mb/s");
2854 if (os_snprintf_error(64, res)) {
2855 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2856 return RETURN_ERR;
2857 }
developera3511852023-06-14 14:12:59 +08002858 return RETURN_OK;
2859 } else {
developere40952c2023-06-15 18:46:43 +08002860 res = snprintf(output_string, 64, "0 Mb/s");
2861 if (os_snprintf_error(64, res)) {
2862 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2863 return RETURN_ERR;
2864 }
developera3511852023-06-14 14:12:59 +08002865 return RETURN_OK;
2866 }
developer72fb0bb2023-01-11 09:46:29 +08002867
developera3511852023-06-14 14:12:59 +08002868 // Spatial streams
2869 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08002870 wifi_debug(DEBUG_ERROR, "wifi_getRadioTxChainMask return error\n");
developera3511852023-06-14 14:12:59 +08002871 return RETURN_ERR;
2872 }
2873 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2874 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002875
developera3511852023-06-14 14:12:59 +08002876 // multiple 10 is to align duration unit (0.1 us)
2877 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
developere40952c2023-06-15 18:46:43 +08002878 res = snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
2879 if (os_snprintf_error(64, res)) {
2880 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2881 return RETURN_ERR;
2882 }
developera3511852023-06-14 14:12:59 +08002883 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2884 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
2885 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002886
developera3511852023-06-14 14:12:59 +08002887 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002888}
developer72fb0bb2023-01-11 09:46:29 +08002889
2890//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2891//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.
2892INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2893{
developera3511852023-06-14 14:12:59 +08002894 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08002895
developera3511852023-06-14 14:12:59 +08002896 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2897 if (NULL == output_string)
2898 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002899
developera3511852023-06-14 14:12:59 +08002900 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002901
developera3511852023-06-14 14:12:59 +08002902 memset(output_string, 0, 10);
2903 if (band == band_2_4)
developer32f2a182023-06-27 19:50:41 +08002904 memcpy(output_string, "2.4GHz", strlen("2.4GHz"));
developera3511852023-06-14 14:12:59 +08002905 else if (band == band_5)
developer32f2a182023-06-27 19:50:41 +08002906 memcpy(output_string, "5GHz", strlen("5GHz"));
developera3511852023-06-14 14:12:59 +08002907 else if (band == band_6)
developer32f2a182023-06-27 19:50:41 +08002908 memcpy(output_string, "6GHz", strlen("6GHz"));
developera3511852023-06-14 14:12:59 +08002909 else
2910 return RETURN_ERR;
2911 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002912
developera3511852023-06-14 14:12:59 +08002913 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002914}
2915
2916//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2917//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.
2918INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2919{
developera3511852023-06-14 14:12:59 +08002920 wifi_band band = band_invalid;
developer9ce44382023-06-28 11:09:37 +08002921 int res = -1;
developere40952c2023-06-15 18:46:43 +08002922
developera3511852023-06-14 14:12:59 +08002923 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2924 if (NULL == output_string)
2925 return RETURN_ERR;
2926 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002927
developera3511852023-06-14 14:12:59 +08002928 if (band == band_2_4)
developere40952c2023-06-15 18:46:43 +08002929 res = snprintf(output_string, 64, "2.4GHz");
developera3511852023-06-14 14:12:59 +08002930 else if (band == band_5)
developere40952c2023-06-15 18:46:43 +08002931 res = snprintf(output_string, 64, "5GHz");
developera3511852023-06-14 14:12:59 +08002932 else if (band == band_6)
developere40952c2023-06-15 18:46:43 +08002933 res = snprintf(output_string, 64, "6GHz");
developer72fb0bb2023-01-11 09:46:29 +08002934
developere40952c2023-06-15 18:46:43 +08002935 if (os_snprintf_error(64, res)) {
2936 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2937 return RETURN_ERR;
2938 }
developera3511852023-06-14 14:12:59 +08002939 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002940
developera3511852023-06-14 14:12:59 +08002941 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002942}
2943
2944//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2945//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.
2946INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2947{
developera3511852023-06-14 14:12:59 +08002948 char cmd[128]={0};
2949 char buf[128]={0};
2950 char temp_output[128] = {0};
2951 wifi_band band;
developere40952c2023-06-15 18:46:43 +08002952 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002953
developera3511852023-06-14 14:12:59 +08002954 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2955 if (NULL == output_string)
2956 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002957
developera3511852023-06-14 14:12:59 +08002958 band = wifi_index_to_band(radioIndex);
2959 if (band == band_2_4) {
developer32f2a182023-06-27 19:50:41 +08002960 strncat(temp_output, "b,g,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08002961 } else if (band == band_5) {
developer32f2a182023-06-27 19:50:41 +08002962 strncat(temp_output, "a,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08002963 }
2964 phyId = radio_index_to_phy(radioIndex);
2965 // ht capabilities
developere40952c2023-06-15 18:46:43 +08002966 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep '[^PHY|MAC|VHT].Capabilities' | head -n 1 | cut -d ':' -f2 | sed 's/^.//' | tr -d '\\n'", phyId);
2967 if (os_snprintf_error(sizeof(cmd), res)) {
2968 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2969 return RETURN_ERR;
2970 }
developera3511852023-06-14 14:12:59 +08002971 _syscmd(cmd, buf, sizeof(buf));
2972 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
developer32f2a182023-06-27 19:50:41 +08002973 if (strlen(temp_output) >= sizeof(temp_output) - 2)
2974 return RETURN_ERR;
2975 strncat(temp_output, "n,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08002976 }
developer72fb0bb2023-01-11 09:46:29 +08002977
developera3511852023-06-14 14:12:59 +08002978 // vht capabilities
2979 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08002980 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2981 if (os_snprintf_error(sizeof(cmd), res)) {
2982 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2983 return RETURN_ERR;
2984 }
2985 _syscmd(cmd, buf, sizeof(buf));
2986 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
developer32f2a182023-06-27 19:50:41 +08002987 if (strlen(temp_output) >= sizeof(temp_output) - 3)
2988 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08002989 strcat(temp_output, "ac,");
2990 }
2991 }
developer72fb0bb2023-01-11 09:46:29 +08002992
developera3511852023-06-14 14:12:59 +08002993 // he capabilities
developere40952c2023-06-15 18:46:43 +08002994 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'HE MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
2995 if (os_snprintf_error(sizeof(cmd), res)) {
2996 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2997 return RETURN_ERR;
2998 }
developera3511852023-06-14 14:12:59 +08002999 _syscmd(cmd, buf, sizeof(buf));
3000 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08003001 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3002 return RETURN_ERR;
3003 strncat(temp_output, "ax,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003004 }
developer72fb0bb2023-01-11 09:46:29 +08003005
developere82c0ca2023-05-10 16:25:35 +08003006 // eht capabilities
developere40952c2023-06-15 18:46:43 +08003007 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'EHT MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
3008 if (os_snprintf_error(sizeof(cmd), res)) {
3009 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3010 return RETURN_ERR;
3011 }
developera3511852023-06-14 14:12:59 +08003012 _syscmd(cmd, buf, sizeof(buf));
3013 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08003014 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3015 return RETURN_ERR;
3016 strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003017 }
developere82c0ca2023-05-10 16:25:35 +08003018
developera3511852023-06-14 14:12:59 +08003019 // Remove the last comma
3020 if (strlen(temp_output) != 0)
3021 temp_output[strlen(temp_output)-1] = '\0';
3022 strncpy(output_string, temp_output, strlen(temp_output));
3023 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3024 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003025}
3026
3027//Get the radio operating mode, and pure mode flag. eg: "ac"
3028//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.
3029INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
3030{
developere40952c2023-06-15 18:46:43 +08003031 int res;
3032
developera3511852023-06-14 14:12:59 +08003033 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3034 if (NULL == output_string)
3035 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003036
developera3511852023-06-14 14:12:59 +08003037 if (radioIndex == 0) {
developere40952c2023-06-15 18:46:43 +08003038 res = snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
3039 if (os_snprintf_error(64, res)) {
3040 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3041 return RETURN_ERR;
3042 }
developera3511852023-06-14 14:12:59 +08003043 *gOnly = FALSE;
3044 *nOnly = TRUE;
3045 *acOnly = FALSE;
3046 } else {
developere40952c2023-06-15 18:46:43 +08003047 res = snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
3048 if (os_snprintf_error(64, res)) {
3049 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3050 return RETURN_ERR;
3051 }
developera3511852023-06-14 14:12:59 +08003052 *gOnly = FALSE;
3053 *nOnly = FALSE;
3054 *acOnly = FALSE;
3055 }
3056 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003057
developera3511852023-06-14 14:12:59 +08003058 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003059}
3060
developer0f10c772023-05-16 21:43:39 +08003061enum WIFI_MODE {
3062 WMODE_INVALID = 0,
3063 WMODE_A = 1 << 0,
3064 WMODE_B = 1 << 1,
3065 WMODE_G = 1 << 2,
3066 WMODE_GN = 1 << 3,
3067 WMODE_AN = 1 << 4,
3068 WMODE_AC = 1 << 5,
3069 WMODE_AX_24G = 1 << 6,
3070 WMODE_AX_5G = 1 << 7,
3071 WMODE_AX_6G = 1 << 8,
3072 WMODE_BE_24G = 1 << 9,
3073 WMODE_BE_5G = 1 << 10,
3074 WMODE_BE_6G = 1 << 11,
3075 /*
3076 * total types of supported wireless mode,
3077 * add this value once yow add new type
3078 */
3079 WMODE_COMP = 12,
3080};
3081
3082#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08003083
3084int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08003085{
developerfead3972023-05-25 20:15:02 +08003086 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3087 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
3088 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3089 unsigned int *phymode;
3090 int err = 0;
3091 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08003092
developerfead3972023-05-25 20:15:02 +08003093 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08003094 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developerfead3972023-05-25 20:15:02 +08003095 return NL_SKIP;
3096 }
developer72fb0bb2023-01-11 09:46:29 +08003097
developerfead3972023-05-25 20:15:02 +08003098 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3099 genlmsg_attrlen(gnlh, 0), NULL);
3100 if (err < 0) {
3101 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
3102 return NL_SKIP;
3103 }
developer0f10c772023-05-16 21:43:39 +08003104
developerfead3972023-05-25 20:15:02 +08003105 if (tb[NL80211_ATTR_VENDOR_DATA]) {
3106 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
3107 tb[NL80211_ATTR_VENDOR_DATA], NULL);
3108 if (err < 0)
3109 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08003110
developerfead3972023-05-25 20:15:02 +08003111 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
3112 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
3113
3114 memset(cb_data->out_buf, 0, cb_data->out_len);
3115 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
3116 }
3117 } else
3118 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
3119
3120 return NL_OK;
3121}
developer0f10c772023-05-16 21:43:39 +08003122
developerfead3972023-05-25 20:15:02 +08003123void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
3124{
3125 wifi_band band;
3126 unsigned char radio_mode_tem_len;
developere40952c2023-06-15 18:46:43 +08003127 int res;
developerfead3972023-05-25 20:15:02 +08003128
3129 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08003130 // puremode is a bit map
developera3511852023-06-14 14:12:59 +08003131 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08003132 memset(output_string, 0, RADIO_MODE_LEN);
3133
3134 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3135
3136 switch (band) {
3137 case band_2_4:
3138 if (phymode & WMODE_B) {
developere40952c2023-06-15 18:46:43 +08003139 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
3140 if (os_snprintf_error(radio_mode_tem_len, res)) {
3141 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3142 return;
3143 }
developer0f10c772023-05-16 21:43:39 +08003144 *pureMode |= WIFI_MODE_B;
3145 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3146 }
3147 if (phymode & WMODE_G) {
developere40952c2023-06-15 18:46:43 +08003148 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
3149 if (os_snprintf_error(radio_mode_tem_len, res)) {
3150 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3151 return;
3152 }
developer0f10c772023-05-16 21:43:39 +08003153 *pureMode |= WIFI_MODE_G;
3154 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3155 }
3156 if (phymode & WMODE_GN) {
developere40952c2023-06-15 18:46:43 +08003157 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3158 if (os_snprintf_error(radio_mode_tem_len, res)) {
3159 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3160 return;
3161 }
developer0f10c772023-05-16 21:43:39 +08003162 *pureMode |= WIFI_MODE_N;
3163 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3164 }
3165 if (phymode & WMODE_AX_24G) {
developere40952c2023-06-15 18:46:43 +08003166 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3167 if (os_snprintf_error(radio_mode_tem_len, res)) {
3168 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3169 return;
3170 }
developer0f10c772023-05-16 21:43:39 +08003171 *pureMode |= WIFI_MODE_AX;
3172 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3173 }
3174 if (phymode & WMODE_BE_24G) {
developere40952c2023-06-15 18:46:43 +08003175 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3176 if (os_snprintf_error(radio_mode_tem_len, res)) {
3177 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3178 return;
3179 }
developer0f10c772023-05-16 21:43:39 +08003180 *pureMode |= WIFI_MODE_BE;
3181 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3182 }
3183 break;
3184 case band_5:
3185 if (phymode & WMODE_A) {
developere40952c2023-06-15 18:46:43 +08003186 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
3187 if (os_snprintf_error(radio_mode_tem_len, res)) {
3188 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3189 return;
3190 }
developer0f10c772023-05-16 21:43:39 +08003191 *pureMode |= WIFI_MODE_A;
3192 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3193 }
3194 if (phymode & WMODE_AN) {
developere40952c2023-06-15 18:46:43 +08003195 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3196 if (os_snprintf_error(radio_mode_tem_len, res)) {
3197 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3198 return;
3199 }
developer0f10c772023-05-16 21:43:39 +08003200 *pureMode |= WIFI_MODE_N;
3201 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3202 }
3203 if (phymode & WMODE_AC) {
developere40952c2023-06-15 18:46:43 +08003204 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
3205 if (os_snprintf_error(radio_mode_tem_len, res)) {
3206 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3207 return;
3208 }
developer0f10c772023-05-16 21:43:39 +08003209 *pureMode |= WIFI_MODE_AC;
3210 }
3211 if (phymode & WMODE_AX_5G) {
developere40952c2023-06-15 18:46:43 +08003212 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3213 if (os_snprintf_error(radio_mode_tem_len, res)) {
3214 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3215 return;
3216 }
developer0f10c772023-05-16 21:43:39 +08003217 *pureMode |= WIFI_MODE_AX;
3218 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3219 }
3220 if (phymode & WMODE_BE_5G) {
developere40952c2023-06-15 18:46:43 +08003221 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3222 if (os_snprintf_error(radio_mode_tem_len, res)) {
3223 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3224 return;
3225 }
developer0f10c772023-05-16 21:43:39 +08003226 *pureMode |= WIFI_MODE_BE;
3227 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3228 }
3229 break;
3230 case band_6:
3231 if (phymode & WMODE_AX_6G) {
developere40952c2023-06-15 18:46:43 +08003232 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3233 if (os_snprintf_error(radio_mode_tem_len, res)) {
3234 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3235 return;
3236 }
developer0f10c772023-05-16 21:43:39 +08003237 *pureMode |= WIFI_MODE_AX;
3238 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3239 }
3240 if (phymode & WMODE_BE_6G) {
developere40952c2023-06-15 18:46:43 +08003241 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3242 if (os_snprintf_error(radio_mode_tem_len, res)) {
3243 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3244 return;
3245 }
developer0f10c772023-05-16 21:43:39 +08003246 *pureMode |= WIFI_MODE_BE;
3247 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3248 }
3249 break;
3250 default:
developer86035662023-06-28 19:21:12 +08003251 wifi_debug(DEBUG_ERROR, "%s band_idx invalid\n", __func__);
developer0f10c772023-05-16 21:43:39 +08003252 break;
3253 }
3254
3255 /* Remove the last comma */
3256 if (strlen(output_string) != 0)
developera3511852023-06-14 14:12:59 +08003257 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08003258
developerfead3972023-05-25 20:15:02 +08003259}
3260
3261INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
3262{
3263 unsigned int phymode;
3264 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003265 int ret = -1;
3266 unsigned int if_idx = 0;
3267 struct unl unl_ins;
3268 struct nl_msg *msg = NULL;
3269 struct nlattr * msg_data = NULL;
3270 struct mtk_nl80211_param param;
3271 struct mtk_nl80211_cb_data cb_data;
3272
developera3511852023-06-14 14:12:59 +08003273 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3274 if (NULL == output_string || NULL == pureMode)
developerdaf24792023-06-06 11:40:04 +08003275 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003276
3277 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3278 return RETURN_ERR;
3279
3280 if_idx = if_nametoindex(interface_name);
3281 if (!if_idx) {
3282 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
3283 return RETURN_ERR;
3284 }
3285 /*init mtk nl80211 vendor cmd*/
3286 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
3287 param.if_type = NL80211_ATTR_IFINDEX;
3288 param.if_idx = if_idx;
3289
3290 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3291 if (ret) {
3292 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3293 return RETURN_ERR;
3294 }
3295
3296 /*add mtk vendor cmd data*/
3297 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
3298 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
3299 nlmsg_free(msg);
3300 goto err;
3301 }
3302
3303 /*send mtk nl80211 vendor msg*/
3304 cb_data.out_buf = (char *)&phymode;
3305 cb_data.out_len = sizeof(unsigned int);
3306
3307 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
3308
3309 if (ret) {
3310 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3311 goto err;
3312 }
3313 /*deinit mtk nl80211 vendor msg*/
3314 mtk_nl80211_deint(&unl_ins);
3315
3316 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
developer6e578302023-06-21 10:11:16 +08003317 wifi_debug(DEBUG_INFO,"send cmd success\n");
developerfead3972023-05-25 20:15:02 +08003318
developera3511852023-06-14 14:12:59 +08003319 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3320 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003321err:
3322 mtk_nl80211_deint(&unl_ins);
3323 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
3324 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003325}
3326
3327// Set the radio operating mode, and pure mode flag.
3328INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
3329{
developera3511852023-06-14 14:12:59 +08003330 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
3331 if (strcmp (channelMode,"11A") == 0)
3332 {
3333 writeBandWidth(radioIndex,"20MHz");
3334 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3335 printf("\nChannel Mode is 802.11a (5GHz)\n");
3336 }
3337 else if (strcmp (channelMode,"11NAHT20") == 0)
3338 {
3339 writeBandWidth(radioIndex,"20MHz");
3340 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3341 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
3342 }
3343 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
3344 {
3345 writeBandWidth(radioIndex,"40MHz");
3346 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3347 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3348 }
3349 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
3350 {
3351 writeBandWidth(radioIndex,"40MHz");
3352 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3353 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3354 }
3355 else if (strcmp (channelMode,"11ACVHT20") == 0)
3356 {
3357 writeBandWidth(radioIndex,"20MHz");
3358 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3359 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
3360 }
3361 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
3362 {
3363 writeBandWidth(radioIndex,"40MHz");
3364 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3365 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3366 }
3367 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
3368 {
3369 writeBandWidth(radioIndex,"40MHz");
3370 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3371 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3372 }
3373 else if (strcmp (channelMode,"11ACVHT80") == 0)
3374 {
3375 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
3376 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
3377 }
3378 else if (strcmp (channelMode,"11ACVHT160") == 0)
3379 {
3380 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
3381 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
3382 }
3383 else if (strcmp (channelMode,"11B") == 0)
3384 {
3385 writeBandWidth(radioIndex,"20MHz");
3386 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3387 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
3388 }
3389 else if (strcmp (channelMode,"11G") == 0)
3390 {
3391 writeBandWidth(radioIndex,"20MHz");
3392 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3393 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
3394 }
3395 else if (strcmp (channelMode,"11NGHT20") == 0)
3396 {
3397 writeBandWidth(radioIndex,"20MHz");
3398 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3399 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3400 }
3401 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3402 {
3403 writeBandWidth(radioIndex,"40MHz");
3404 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3405 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3406 }
3407 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3408 {
3409 writeBandWidth(radioIndex,"40MHz");
3410 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3411 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3412 }
3413 else
3414 {
3415 return RETURN_ERR;
3416 }
3417 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003418
developera3511852023-06-14 14:12:59 +08003419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003420}
3421
developer0f10c772023-05-16 21:43:39 +08003422typedef enum _RT_802_11_PHY_MODE {
3423 PHY_11BG_MIXED = 0,
3424 PHY_11B = 1,
3425 PHY_11A = 2,
3426 PHY_11ABG_MIXED = 3,
3427 PHY_11G = 4,
3428 PHY_11ABGN_MIXED = 5, /* both band 5 */
developera3511852023-06-14 14:12:59 +08003429 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3430 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3431 PHY_11AN_MIXED = 8, /* 5G band 8 */
3432 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3433 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3434 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
developer0f10c772023-05-16 21:43:39 +08003435 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3436 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3437 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3438 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3439 PHY_11AX_24G = 16,
3440 PHY_11AX_5G = 17,
3441 PHY_11AX_6G = 18,
3442 PHY_11AX_24G_6G = 19,
3443 PHY_11AX_5G_6G = 20,
3444 PHY_11AX_24G_5G_6G = 21,
3445 PHY_11BE_24G = 22,
3446 PHY_11BE_5G = 23,
3447 PHY_11BE_6G = 24,
3448 PHY_11BE_24G_6G = 25,
3449 PHY_11BE_5G_6G = 26,
3450 PHY_11BE_24G_5G_6G = 27,
3451 PHY_MODE_MAX,
3452} RT_802_11_PHY_MODE;
3453
3454unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3455{
3456 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003457 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003458
3459 band_idx = radio_index_to_band(radioIndex);
3460
3461 switch (band_idx) {
3462 case band_2_4:
3463 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3464 wireless_mode = PHY_11GN_MIXED;
3465 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3466 wireless_mode = PHY_11BGN_MIXED;
3467 if (pureMode & WIFI_MODE_AX)
3468 wireless_mode = PHY_11AX_24G;
3469 if (pureMode & WIFI_MODE_BE)
3470 wireless_mode = PHY_11BE_24G;
3471 break;
3472 case band_5:
3473 if (pureMode == WIFI_MODE_N)
3474 wireless_mode = PHY_11N_5G;
3475 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3476 wireless_mode = PHY_11VHT_N_MIXED;
3477 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3478 wireless_mode = PHY_11VHT_N_A_MIXED;
3479 if (pureMode & WIFI_MODE_AX)
3480 wireless_mode = PHY_11AX_5G;
3481 if (pureMode & WIFI_MODE_BE)
3482 wireless_mode = PHY_11BE_5G;
3483 break;
3484 case band_6:
3485 if (pureMode & WIFI_MODE_AX)
3486 wireless_mode = PHY_11AX_6G;
3487 if (pureMode & WIFI_MODE_BE)
3488 wireless_mode = PHY_11BE_6G;
3489 break;
3490 default:
3491 fprintf(stderr, "%s band_idx invalid\n", __func__);
3492 break;
3493 }
3494
3495 return wireless_mode;
3496}
3497
developer72fb0bb2023-01-11 09:46:29 +08003498// Set the radio operating mode, and pure mode flag.
3499INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3500{
developerfead3972023-05-25 20:15:02 +08003501 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003502
developer0f10c772023-05-16 21:43:39 +08003503 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003504 int ret = -1;
3505 unsigned int if_idx = 0;
3506 struct unl unl_ins;
3507 struct nl_msg *msg = NULL;
3508 struct nlattr * msg_data = NULL;
3509 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003510
developer0f10c772023-05-16 21:43:39 +08003511 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003512
developer0f10c772023-05-16 21:43:39 +08003513 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003514
developera3511852023-06-14 14:12:59 +08003515 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08003516 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08003517 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003518 }
developer72fb0bb2023-01-11 09:46:29 +08003519
developer0f10c772023-05-16 21:43:39 +08003520 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08003521 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003522
3523 if_idx = if_nametoindex(interface_name);
3524 if (!if_idx) {
3525 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3526 return RETURN_ERR;
3527 }
3528 /*init mtk nl80211 vendor cmd*/
3529 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3530 param.if_type = NL80211_ATTR_IFINDEX;
3531 param.if_idx = if_idx;
3532
3533 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3534 if (ret) {
3535 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3536 return RETURN_ERR;
3537 }
3538
3539 /*add mtk vendor cmd data*/
3540 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3541 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3542 nlmsg_free(msg);
3543 goto err;
3544 }
3545 /*send mtk nl80211 vendor msg*/
3546 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3547 if (ret) {
3548 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3549 goto err;
3550 }
3551 /*deinit mtk nl80211 vendor msg*/
3552 mtk_nl80211_deint(&unl_ins);
3553 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003554
developera3511852023-06-14 14:12:59 +08003555 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer0f10c772023-05-16 21:43:39 +08003556
developera3511852023-06-14 14:12:59 +08003557 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003558err:
3559 mtk_nl80211_deint(&unl_ins);
3560 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3561 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003562}
3563
3564INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3565{
developerfead3972023-05-25 20:15:02 +08003566 unsigned char wireless_mode = PHY_MODE_MAX;
developera3511852023-06-14 14:12:59 +08003567 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003568 char dat_file[MAX_BUF_SIZE] = {0};
3569 struct params params={0};
developere40952c2023-06-15 18:46:43 +08003570 int res;
developer0f10c772023-05-16 21:43:39 +08003571
3572 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3573
3574 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3575
developera3511852023-06-14 14:12:59 +08003576 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08003577 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08003578 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003579 }
developer0f10c772023-05-16 21:43:39 +08003580
3581 params.name = "WirelessMode";
developere40952c2023-06-15 18:46:43 +08003582 res = snprintf(buf, sizeof(buf), "%d", wireless_mode);
3583 if (os_snprintf_error(sizeof(buf), res)) {
3584 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3585 return RETURN_ERR;
3586 }
3587
developera3511852023-06-14 14:12:59 +08003588 params.value = buf;
developer0f10c772023-05-16 21:43:39 +08003589
developere40952c2023-06-15 18:46:43 +08003590 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3591 if (os_snprintf_error(sizeof(dat_file), res)) {
3592 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3593 return RETURN_ERR;
3594 }
developera3511852023-06-14 14:12:59 +08003595 wifi_datfileWrite(dat_file, &params, 1);
developer0f10c772023-05-16 21:43:39 +08003596
developera3511852023-06-14 14:12:59 +08003597 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003598
developera3511852023-06-14 14:12:59 +08003599 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003600}
3601
3602INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3603
developera3511852023-06-14 14:12:59 +08003604 char config_file[64] = {0};
3605 char buf[64] = {0};
3606 struct params params = {0};
3607 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003608 int res;
developer72fb0bb2023-01-11 09:46:29 +08003609
developera3511852023-06-14 14:12:59 +08003610 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003611
developera3511852023-06-14 14:12:59 +08003612 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003613
developera3511852023-06-14 14:12:59 +08003614 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3615 return RETURN_ERR;
3616 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3617 return RETURN_ERR;
3618 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3619 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003620
developer75bd10c2023-06-27 11:34:08 +08003621 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3622 if (os_snprintf_error(sizeof(config_file), res)) {
3623 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3624 return RETURN_ERR;
3625 }
developera3511852023-06-14 14:12:59 +08003626 params.name = "hw_mode";
3627 params.value = hw_mode;
3628 wifi_hostapdWrite(config_file, &params, 1);
3629 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003630
developera3511852023-06-14 14:12:59 +08003631 if (band == band_2_4) {
3632 if (strncmp(hw_mode, "b", 1) == 0) {
3633 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
developere40952c2023-06-15 18:46:43 +08003634 res = snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3635 if (os_snprintf_error(sizeof(buf), res)) {
3636 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3637 return RETURN_ERR;
3638 }
developera3511852023-06-14 14:12:59 +08003639 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003640 res = snprintf(buf, sizeof(buf), "%s", "1,2");
3641 if (os_snprintf_error(sizeof(buf), res)) {
3642 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3643 return RETURN_ERR;
3644 }
developera3511852023-06-14 14:12:59 +08003645 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3646 } else {
3647 // 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 +08003648
developere40952c2023-06-15 18:46:43 +08003649 res = snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3650 if (os_snprintf_error(sizeof(buf), res)) {
3651 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3652 return RETURN_ERR;
3653 }
developera3511852023-06-14 14:12:59 +08003654 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003655 res = snprintf(buf, sizeof(buf), "%s", "6,12,24");
3656 if (os_snprintf_error(sizeof(buf), res)) {
3657 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3658 return RETURN_ERR;
3659 }
developera3511852023-06-14 14:12:59 +08003660 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3661 }
3662 }
developer72fb0bb2023-01-11 09:46:29 +08003663
developera3511852023-06-14 14:12:59 +08003664 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3665 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003666}
3667
3668INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3669{
developera3511852023-06-14 14:12:59 +08003670 char config_file[64] = {0};
3671 struct params params = {0};
3672 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08003673 int res;
developer72fb0bb2023-01-11 09:46:29 +08003674
developera3511852023-06-14 14:12:59 +08003675 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003676
developera3511852023-06-14 14:12:59 +08003677 band = wifi_index_to_band(radioIndex);
3678 if (band != band_2_4)
3679 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003680
developer75bd10c2023-06-27 11:34:08 +08003681 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3682 if (os_snprintf_error(sizeof(config_file), res)) {
3683 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3684 return RETURN_ERR;
3685 }
developera3511852023-06-14 14:12:59 +08003686 params.name = "noscan";
3687 params.value = noscan;
3688 wifi_hostapdWrite(config_file, &params, 1);
3689 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003690
developera3511852023-06-14 14:12:59 +08003691 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3692 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003693}
3694
3695//Get the list of supported channel. eg: "1-11"
3696//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.
3697INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3698{
developera3511852023-06-14 14:12:59 +08003699 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3700 if (NULL == output_string)
3701 return RETURN_ERR;
3702 char cmd[256] = {0};
3703 char buf[128] = {0};
3704 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +08003705 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08003706
developera3511852023-06-14 14:12:59 +08003707 // Parse possible channel number and separate them with commas.
3708 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3709 phyId = radio_index_to_phy(radioIndex);
3710 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3711 if (dfs_enable)
developere40952c2023-06-15 18:46:43 +08003712 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId);
developera3511852023-06-14 14:12:59 +08003713 else
developere40952c2023-06-15 18:46:43 +08003714 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'radar\\|no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId);
developer72fb0bb2023-01-11 09:46:29 +08003715
developere40952c2023-06-15 18:46:43 +08003716 if (os_snprintf_error(sizeof(cmd), res)) {
3717 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3718 return RETURN_ERR;
3719 }
developera3511852023-06-14 14:12:59 +08003720 _syscmd(cmd,buf,sizeof(buf));
3721 strncpy(output_string, buf, strlen(buf) < sizeof(buf) ? strlen(buf) : sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003722
developera3511852023-06-14 14:12:59 +08003723 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3724 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003725}
developerd1824452023-05-18 12:30:04 +08003726//Getting current radio extension channel
3727INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3728{
developera3511852023-06-14 14:12:59 +08003729 CHAR buf[150] = {0};
developer32f2a182023-06-27 19:50:41 +08003730 int len;
developerd1824452023-05-18 12:30:04 +08003731
developera3511852023-06-14 14:12:59 +08003732 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08003733 if (strncmp(buf, "Below", 5) == 0) {
3734 len = strlen("BelowControlChannel");
3735 memcpy(Value, "BelowControlChannel", len);
3736 }
3737 else if(strncmp(buf, "Above", 5) == 0) {
3738 len = strlen("AboveControlChannel");
3739 memcpy(Value, "AboveControlChannel", len);
3740 }
3741 Value[len] = '\0';
developera3511852023-06-14 14:12:59 +08003742 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08003743}
developerf6a87542023-05-16 15:47:28 +08003744
developer72fb0bb2023-01-11 09:46:29 +08003745//Get the list for used channel. eg: "1,6,9,11"
3746//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.
3747INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3748{
developera3511852023-06-14 14:12:59 +08003749 char interface_name[16] = {0};
3750 char cmd[128] = {0};
3751 char buf[128] = {0};
3752 char config_file[64] = {0};
3753 int channel = 0;
3754 int freq = 0;
3755 int bandwidth = 0;
3756 int center_freq = 0;
3757 int center_channel = 0;
3758 int channel_delta = 0;
3759 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003760 int res;
developer72fb0bb2023-01-11 09:46:29 +08003761
developera3511852023-06-14 14:12:59 +08003762 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003763
developera3511852023-06-14 14:12:59 +08003764 if (NULL == output_string)
3765 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003766
developera3511852023-06-14 14:12:59 +08003767 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3768 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08003769
3770 res = snprintf(cmd, sizeof(cmd), "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3771 if (os_snprintf_error(sizeof(cmd), res)) {
3772 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3773 return RETURN_ERR;
3774 }
developera3511852023-06-14 14:12:59 +08003775 _syscmd(cmd, buf, sizeof(buf));
3776 if (strlen(buf) == 0) {
developer75bd10c2023-06-27 11:34:08 +08003777 wifi_debug(DEBUG_ERROR, "failed to get channel information from iw.\n");
developera3511852023-06-14 14:12:59 +08003778 return RETURN_ERR;
3779 }
3780 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
developer72fb0bb2023-01-11 09:46:29 +08003781
developera3511852023-06-14 14:12:59 +08003782 if (bandwidth == 20) {
developere40952c2023-06-15 18:46:43 +08003783 res = snprintf(output_string, 256, "%d", channel);
3784 if (os_snprintf_error(256, res)) {
3785 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3786 return RETURN_ERR;
3787 }
developera3511852023-06-14 14:12:59 +08003788 return RETURN_OK;
3789 }
developer72fb0bb2023-01-11 09:46:29 +08003790
developera3511852023-06-14 14:12:59 +08003791 center_channel = ieee80211_frequency_to_channel(center_freq);
developer72fb0bb2023-01-11 09:46:29 +08003792
developera3511852023-06-14 14:12:59 +08003793 band = wifi_index_to_band(radioIndex);
3794 if (band == band_2_4 && bandwidth == 40) {
developer32f2a182023-06-27 19:50:41 +08003795 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3796 if (os_snprintf_error(sizeof(config_file), res)) {
3797 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3798 return RETURN_ERR;
3799 }
developera3511852023-06-14 14:12:59 +08003800 memset(buf, 0, sizeof(buf));
3801 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
developer72fb0bb2023-01-11 09:46:29 +08003802
developera3511852023-06-14 14:12:59 +08003803 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
developere40952c2023-06-15 18:46:43 +08003804 res = snprintf(output_string, 256, "%d,%d", channel, channel+4);
developera3511852023-06-14 14:12:59 +08003805 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
developere40952c2023-06-15 18:46:43 +08003806 res = snprintf(output_string, 256, "%d,%d", channel-4, channel);
developera3511852023-06-14 14:12:59 +08003807 } else {
3808 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
3809 return RETURN_ERR;
3810 }
developerb758dfd2023-06-21 17:32:07 +08003811
developere40952c2023-06-15 18:46:43 +08003812 if (os_snprintf_error(256, res)) {
3813 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3814 return RETURN_ERR;
3815 }
developera3511852023-06-14 14:12:59 +08003816 } else if (band == band_5 || band == band_6){
3817 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
3818 // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6.
3819 channel_delta = (bandwidth-20)/10;
3820 memset(output_string, 0, 256);
3821 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3822 // If i is not the last channel, we add a comma.
developere40952c2023-06-15 18:46:43 +08003823 res = snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
developer32f2a182023-06-27 19:50:41 +08003824
developere40952c2023-06-15 18:46:43 +08003825 if (os_snprintf_error(sizeof(buf), res)) {
3826 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3827 return RETURN_ERR;
3828 }
developer32f2a182023-06-27 19:50:41 +08003829 strncat(output_string, buf, sizeof(output_string) - strlen(output_string) - 1);
developera3511852023-06-14 14:12:59 +08003830 }
3831 } else
3832 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003833
developera3511852023-06-14 14:12:59 +08003834 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3835 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003836}
3837
developer69b61b02023-03-07 17:17:44 +08003838//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003839INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003840{
developera3511852023-06-14 14:12:59 +08003841 char channel_str[16] = {0};
3842 char config_file[128] = {0};
3843 char buf[MAX_BUF_SIZE] = {0};
3844 char cmd[MAX_CMD_SIZE] = {0};
3845 char interface_name[IF_NAME_SIZE] = {0};
3846 wifi_band band = band_invalid;
3847 ULONG iwChannel = 0;
developere40952c2023-06-15 18:46:43 +08003848 int res;
developer47a56bf2023-05-30 13:38:57 +08003849
developera3511852023-06-14 14:12:59 +08003850 if (output_ulong == NULL)
3851 return RETURN_ERR;
3852 band = wifi_index_to_band(radioIndex);
developerb758dfd2023-06-21 17:32:07 +08003853 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08003854 if (os_snprintf_error(sizeof(config_file), res)) {
3855 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3856 return RETURN_ERR;
3857 }
3858
developera3511852023-06-14 14:12:59 +08003859 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
3860 *output_ulong = strtoul(channel_str, NULL, 10);
3861 if (*output_ulong == 0) {
3862 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3863 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08003864 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
3865 if (os_snprintf_error(sizeof(cmd), res)) {
3866 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3867 return RETURN_ERR;
3868 }
3869
developera3511852023-06-14 14:12:59 +08003870 _syscmd(cmd,buf,sizeof(buf));
3871 sscanf(buf, "%lu", &iwChannel);
3872 *output_ulong = iwChannel;
3873 }
developer72fb0bb2023-01-11 09:46:29 +08003874
developera3511852023-06-14 14:12:59 +08003875 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003876}
3877
developer72fb0bb2023-01-11 09:46:29 +08003878INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
3879{
developera3511852023-06-14 14:12:59 +08003880 char cmd[1024] = {0}, buf[5] = {0};
3881 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08003882 int res;
developer72fb0bb2023-01-11 09:46:29 +08003883
developera3511852023-06-14 14:12:59 +08003884 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3885 if (NULL == output_ulong)
3886 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003887
developera3511852023-06-14 14:12:59 +08003888 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
3889 return RETURN_ERR;
developer47a56bf2023-05-30 13:38:57 +08003890
developere40952c2023-06-15 18:46:43 +08003891 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
3892 if (os_snprintf_error(sizeof(cmd), res)) {
3893 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3894 return RETURN_ERR;
3895 }
developera3511852023-06-14 14:12:59 +08003896 _syscmd(cmd,buf,sizeof(buf));
3897 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
3898 if (*output_ulong == 0) {
3899 return RETURN_ERR;
3900 }
developer72fb0bb2023-01-11 09:46:29 +08003901
developera3511852023-06-14 14:12:59 +08003902 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3903 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003904}
developer72fb0bb2023-01-11 09:46:29 +08003905//Storing the previous channel value
3906INT wifi_storeprevchanval(INT radioIndex)
3907{
developera3511852023-06-14 14:12:59 +08003908 char buf[256] = {0};
3909 char output[4]={'\0'};
3910 char config_file[MAX_BUF_SIZE] = {0};
3911 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003912 int res;
developerd1824452023-05-18 12:30:04 +08003913
developera3511852023-06-14 14:12:59 +08003914 band = wifi_index_to_band(radioIndex);
3915 if (band == band_invalid) {
3916 return RETURN_ERR;
3917 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
3918 }
developere40952c2023-06-15 18:46:43 +08003919 res = snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
3920 if (os_snprintf_error(sizeof(config_file), res)) {
3921 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3922 return RETURN_ERR;
3923 }
3924
developera3511852023-06-14 14:12:59 +08003925 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
developerd1824452023-05-18 12:30:04 +08003926
developera3511852023-06-14 14:12:59 +08003927 if(band == band_2_4)
developer75bd10c2023-06-27 11:34:08 +08003928 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developera3511852023-06-14 14:12:59 +08003929 else if(band == band_5)
developer75bd10c2023-06-27 11:34:08 +08003930 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developera3511852023-06-14 14:12:59 +08003931 else
developer75bd10c2023-06-27 11:34:08 +08003932 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
3933
3934 if (os_snprintf_error(sizeof(buf), res)) {
3935 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3936 return RETURN_ERR;
3937 }
developera3511852023-06-14 14:12:59 +08003938 system(buf);
3939 Radio_flag = FALSE;
3940 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003941}
3942
3943//Set the running channel number
3944INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
3945{
developera3511852023-06-14 14:12:59 +08003946 // We only write hostapd config here
3947 char str_channel[8]={0};
3948 char *list_channel;
3949 char possible_channels[256] = {0};
3950 char config_file_dat[128] = {0};
3951 struct params dat = {0};
3952 struct params acs = {0};
3953 wifi_band band = band_invalid;
3954 bool acs_channel = false;
developere40952c2023-06-15 18:46:43 +08003955 int res;
developer72fb0bb2023-01-11 09:46:29 +08003956
developera3511852023-06-14 14:12:59 +08003957 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003958
developera3511852023-06-14 14:12:59 +08003959 if (channel == 0)
3960 acs_channel = true;
3961 // Check valid
developer75bd10c2023-06-27 11:34:08 +08003962 res = snprintf(str_channel, sizeof(str_channel), "%lu", channel);
3963 if (os_snprintf_error(sizeof(str_channel), res)) {
3964 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3965 return RETURN_ERR;
3966 }
developer47a56bf2023-05-30 13:38:57 +08003967
developera3511852023-06-14 14:12:59 +08003968 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
3969 list_channel = strtok(possible_channels, ",");
3970 while(true)
3971 {
3972 if(list_channel == NULL) { // input not in the list
developer75bd10c2023-06-27 11:34:08 +08003973 wifi_debug(DEBUG_ERROR, "Channel %s is not in possible list\n", str_channel);
developera3511852023-06-14 14:12:59 +08003974 return RETURN_ERR;
3975 }
3976 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
3977 break;
3978 list_channel = strtok(NULL, ",");
3979 }
3980 /*
3981 list.name = "channel";
3982 list.value = str_channel;
3983 wifi_getMaxRadioNumber(&max_radio_num);
3984 for(int i=0; i<=MAX_APS/max_radio_num;i++)
3985 {
3986 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3987 wifi_hostapdWrite(config_file, &list, 1);
3988 }
3989 */
3990 dat.name = "Channel";
3991 dat.value = str_channel;
3992 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08003993 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3994 if (os_snprintf_error(sizeof(config_file_dat), res)) {
3995 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3996 return RETURN_ERR;
3997 }
3998
developera3511852023-06-14 14:12:59 +08003999 wifi_datfileWrite(config_file_dat, &dat, 1);
4000 if (acs_channel == true) {
4001 acs.name = "AutoChannelSelect";
4002 acs.value = "3";
4003 } else {
4004 acs.name = "AutoChannelSelect";
4005 acs.value = "0";
4006 }
4007 wifi_datfileWrite(config_file_dat, &acs, 1);
4008 wifi_reloadAp(radioIndex);
4009 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4010 return RETURN_OK;
4011}
4012
4013INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
4014{
4015 struct params list[2];
4016 char str_idx[16];
4017 char config_file[64];
developere40952c2023-06-15 18:46:43 +08004018 int max_num_radios = 0, res;
developera3511852023-06-14 14:12:59 +08004019 wifi_band band = band_invalid;
4020
4021 band = wifi_index_to_band(radioIndex);
4022 if (band == band_2_4)
4023 return RETURN_OK;
4024
developere40952c2023-06-15 18:46:43 +08004025 res = snprintf(str_idx, sizeof(str_idx), "%lu", channel);
4026 if (os_snprintf_error(sizeof(str_idx), res)) {
4027 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4028 return RETURN_ERR;
4029 }
4030
developera3511852023-06-14 14:12:59 +08004031 list[0].name = "vht_oper_centr_freq_seg0_idx";
4032 list[0].value = str_idx;
4033 list[1].name = "he_oper_centr_freq_seg0_idx";
4034 list[1].value = str_idx;
4035
4036 wifi_getMaxRadioNumber(&max_num_radios);
developer9ce44382023-06-28 11:09:37 +08004037 if(max_num_radios== 0){
4038 return RETURN_ERR;
4039 }
developera3511852023-06-14 14:12:59 +08004040 for(int i=0; i<=MAX_APS/max_num_radios; i++)
4041 {
developere40952c2023-06-15 18:46:43 +08004042 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
4043 if (os_snprintf_error(sizeof(config_file), res)) {
4044 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4045 return RETURN_ERR;
4046 }
developera3511852023-06-14 14:12:59 +08004047 if (band == band_6)
4048 wifi_hostapdWrite(config_file, &list[1], 1);
4049 else
4050 wifi_hostapdWrite(config_file, list, 2);
4051 }
4052
4053 return RETURN_OK;
4054}
4055
4056//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
4057//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
4058INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
4059{
4060 //Set to wifi config only. Wait for wifi reset to apply.
4061 ULONG Value = 0;
4062 char config_file_dat[128] = {0};
4063 struct params acs = {0};
4064 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004065 int res;
developera3511852023-06-14 14:12:59 +08004066
4067 if(enable == TRUE) {
4068 wifi_setRadioChannel(radioIndex,Value);
4069 } else {
4070 acs.name = "AutoChannelSelect";
4071 acs.value = "0";
4072 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004073 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4074 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4075 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4076 return RETURN_ERR;
4077 }
developera3511852023-06-14 14:12:59 +08004078 wifi_datfileWrite(config_file_dat, &acs, 1);
4079 }
4080 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004081}
4082
4083INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
4084{
developera3511852023-06-14 14:12:59 +08004085 if (output_bool == NULL)
4086 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004087
developera3511852023-06-14 14:12:59 +08004088 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004089
developera3511852023-06-14 14:12:59 +08004090 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004091}
4092
4093INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
4094{
developera3511852023-06-14 14:12:59 +08004095 if (NULL == output_bool)
4096 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004097 *output_bool=TRUE;
developera3511852023-06-14 14:12:59 +08004098 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004099}
4100
4101INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
4102{
developer326d4232023-06-15 16:45:30 +08004103 unsigned long period = 0;
4104
developera3511852023-06-14 14:12:59 +08004105 if (NULL == output_bool)
4106 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004107
4108 if (wifi_getRadioAutoChannelRefreshPeriod(radioIndex, &period) != RETURN_OK)
developerb758dfd2023-06-21 17:32:07 +08004109 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08004110
4111 *output_bool = (period > 0) ? TRUE : FALSE;
4112
developera3511852023-06-14 14:12:59 +08004113 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004114}
4115
developer326d4232023-06-15 16:45:30 +08004116INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08004117{
developer326d4232023-06-15 16:45:30 +08004118 ULONG period = 1800;
4119
4120 if (enable == TRUE) {
4121 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, period) != RETURN_OK)
4122 return RETURN_ERR;
4123 }
4124 else {
4125 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, 0) != RETURN_OK)
4126 return RETURN_ERR;
4127 }
developera3511852023-06-14 14:12:59 +08004128 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004129}
4130
4131INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
4132{
developera3511852023-06-14 14:12:59 +08004133 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004134}
4135
4136INT wifi_factoryResetAP(int apIndex)
4137{
developerb149d9d2023-06-06 16:14:22 +08004138 char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08004139 char cmd[MAX_CMD_SIZE] = {0};
4140 char ret_buf[MAX_BUF_SIZE] = {0};
4141 int radio_idx = 0;
4142 int bss_idx = 0;
4143 char ssid[32] = {0};
4144 char interface[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08004145 char psk_file[MAX_SUB_CMD_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08004146 struct params params[3] = {0};
developere40952c2023-06-15 18:46:43 +08004147 int res;
developer72fb0bb2023-01-11 09:46:29 +08004148
developera3511852023-06-14 14:12:59 +08004149 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004150
developer47cc27a2023-05-17 23:09:58 +08004151 /*del old config file*/
developer9ce44382023-06-28 11:09:37 +08004152 res = snprintf(ap_config_file, sizeof(ap_config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developere40952c2023-06-15 18:46:43 +08004153 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4154 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4155 return RETURN_ERR;
4156 }
4157
4158 res = snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
4159 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4160 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4161 return RETURN_ERR;
4162 }
4163
developer47cc27a2023-05-17 23:09:58 +08004164 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08004165
developer47cc27a2023-05-17 23:09:58 +08004166 memset(cmd, 0, sizeof(cmd));
4167 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08004168
developer47cc27a2023-05-17 23:09:58 +08004169 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
4170
4171 /*prepare new config file*/
developere40952c2023-06-15 18:46:43 +08004172 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
4173 if (os_snprintf_error(sizeof(cmd), res)) {
4174 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4175 return RETURN_ERR;
4176 }
4177
developer47cc27a2023-05-17 23:09:58 +08004178 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4179
4180 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08004181 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
4182 if (os_snprintf_error(sizeof(ssid), res)) {
4183 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4184 return RETURN_ERR;
4185 }
4186
4187 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
4188 if (os_snprintf_error(sizeof(interface), res)) {
4189 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4190 return RETURN_ERR;
4191 }
developer47cc27a2023-05-17 23:09:58 +08004192 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08004193 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
4194 if (os_snprintf_error(sizeof(ssid), res)) {
4195 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4196 return RETURN_ERR;
4197 }
4198
4199 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
4200 if (os_snprintf_error(sizeof(interface), res)) {
4201 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4202 return RETURN_ERR;
4203 }
developer47cc27a2023-05-17 23:09:58 +08004204 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08004205 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
4206 if (os_snprintf_error(sizeof(ssid), res)) {
4207 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4208 return RETURN_ERR;
4209 }
4210
4211 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
4212 if (os_snprintf_error(sizeof(interface), res)) {
4213 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4214 return RETURN_ERR;
4215 }
developer47cc27a2023-05-17 23:09:58 +08004216 }
4217
4218 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08004219 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
4220 if (os_snprintf_error(sizeof(psk_file), res)) {
4221 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4222 return RETURN_ERR;
4223 }
developer47cc27a2023-05-17 23:09:58 +08004224
4225 params[0].name = "ssid";
4226 params[0].value = ssid;
4227 params[1].name = "interface";
4228 params[1].value = interface;
4229 params[2].name = "wpa_psk_file";
4230 params[2].value = psk_file;
4231
4232 wifi_hostapdWrite(ap_config_file, params, 3);
4233
4234 /*clear psk file*/
4235 memset(cmd, 0, sizeof(cmd));
4236 memset(ret_buf, 0, sizeof(ret_buf));
4237
developere40952c2023-06-15 18:46:43 +08004238 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
4239 if (os_snprintf_error(sizeof(psk_file), res)) {
4240 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4241 return RETURN_ERR;
4242 }
developer47cc27a2023-05-17 23:09:58 +08004243
4244 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08004245 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
4246 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4247 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4248 return RETURN_ERR;
4249 }
4250
developer47cc27a2023-05-17 23:09:58 +08004251 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4252 } else {
developere40952c2023-06-15 18:46:43 +08004253 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
4254 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4255 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4256 return RETURN_ERR;
4257 }
4258
developer47cc27a2023-05-17 23:09:58 +08004259 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4260 }
4261
developer429ba832023-05-31 11:03:35 +08004262 wifi_setApEnable(apIndex, FALSE);
4263 wifi_setApEnable(apIndex, TRUE);
developer47cc27a2023-05-17 23:09:58 +08004264 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4265
4266 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004267}
4268
developer72fb0bb2023-01-11 09:46:29 +08004269INT wifi_setBandSteeringApGroup(char *ApGroup)
4270{
developera3511852023-06-14 14:12:59 +08004271 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004272}
4273
4274INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
4275{
developera3511852023-06-14 14:12:59 +08004276 char config_file[128] = {'\0'};
4277 char buf[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004278 int res;
developer72fb0bb2023-01-11 09:46:29 +08004279
developera3511852023-06-14 14:12:59 +08004280 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4281 if (dtimInterval == NULL)
4282 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004283
4284 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
4285 if (os_snprintf_error(sizeof(config_file), res)) {
4286 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4287 return RETURN_ERR;
4288 }
developer72fb0bb2023-01-11 09:46:29 +08004289
developera3511852023-06-14 14:12:59 +08004290 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004291
developera3511852023-06-14 14:12:59 +08004292 if (strlen(buf) == 0) {
4293 *dtimInterval = 2;
4294 } else {
4295 *dtimInterval = strtoul(buf, NULL, 10);
4296 }
developer72fb0bb2023-01-11 09:46:29 +08004297
developera3511852023-06-14 14:12:59 +08004298 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4299 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004300}
4301
4302INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
4303{
developera3511852023-06-14 14:12:59 +08004304 struct params params={0};
4305 char config_file[MAX_BUF_SIZE] = {'\0'};
4306 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004307 int res;
developer72fb0bb2023-01-11 09:46:29 +08004308
developera3511852023-06-14 14:12:59 +08004309 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4310 if (dtimInterval < 1 || dtimInterval > 255) {
4311 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
4312 return RETURN_ERR;
4313 }
developer69b61b02023-03-07 17:17:44 +08004314
developera3511852023-06-14 14:12:59 +08004315 params.name = "dtim_period";
developere40952c2023-06-15 18:46:43 +08004316 res = snprintf(buf, sizeof(buf), "%d", dtimInterval);
4317 if (os_snprintf_error(sizeof(buf), res)) {
4318 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4319 return RETURN_ERR;
4320 }
developera3511852023-06-14 14:12:59 +08004321 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08004322
developer75bd10c2023-06-27 11:34:08 +08004323 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
4324 if (os_snprintf_error(sizeof(config_file), res)) {
4325 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4326 return RETURN_ERR;
4327 }
developera3511852023-06-14 14:12:59 +08004328 wifi_hostapdWrite(config_file, &params, 1);
4329 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08004330
developera3511852023-06-14 14:12:59 +08004331 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4332 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004333}
4334
4335//Check if the driver support the Dfs
4336INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
4337{
developera3511852023-06-14 14:12:59 +08004338 wifi_band band = band_invalid;
4339 if (NULL == output_bool)
4340 return RETURN_ERR;
4341 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +08004342
developera3511852023-06-14 14:12:59 +08004343 band = wifi_index_to_band(radioIndex);
4344 if (band == band_5)
4345 *output_bool = TRUE;
4346 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004347}
4348
4349//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.
4350//The value of this parameter is a comma seperated list of channel number
4351INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
4352{
developer326d4232023-06-15 16:45:30 +08004353
4354 #define CHANNEL_AVAILABLE 0
4355 #define CHANNEL_INVALID 1
4356 #define CHANNEL_LIST_MAX_LENGTH 256
4357 #define MAX_CHANNEL_NUMBER 255
4358
4359 char config_file[MAX_BUF_SIZE] = {0};
4360 char possible_channels[CHANNEL_LIST_MAX_LENGTH] = {0};
4361 char skip_list[CHANNEL_LIST_MAX_LENGTH] = {0};
4362 int skip_table[MAX_CHANNEL_NUMBER +1] = {0};
4363 wifi_band band = band_invalid;
4364 char *token_channel = NULL, *token_skip = NULL;
developer75bd10c2023-06-27 11:34:08 +08004365 int res;
developere40952c2023-06-15 18:46:43 +08004366
developera3511852023-06-14 14:12:59 +08004367 if (NULL == output_pool)
4368 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004369 // get skiplist, possible_channels list
4370 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
4371 band = wifi_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08004372 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4373 if (os_snprintf_error(sizeof(config_file), res)) {
4374 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4375 return RETURN_ERR;
4376 }
developer326d4232023-06-15 16:45:30 +08004377 wifi_datfileRead(config_file, "AutoChannelSkipList", skip_list, sizeof(skip_list));
4378
4379 if (skip_list[0] != '\0') {
4380 int len = strlen(skip_list);
4381 for (int i = 0; i < len; i++) {
4382 if (skip_list[i] == ';') {
4383 skip_list[i] = ',';
4384 }
4385 }
4386 // skip list
4387 token_skip = strtok(skip_list, ",");
4388 while (token_skip != NULL) {
4389 int channel = atoi(token_skip);
4390 if (channel <= MAX_CHANNEL_NUMBER && strstr(possible_channels, token_skip) != NULL)
4391 skip_table[atoi(token_skip)] = CHANNEL_INVALID;
4392 token_skip = strtok(NULL, ",");
4393 }
developere40952c2023-06-15 18:46:43 +08004394 }
developer72fb0bb2023-01-11 09:46:29 +08004395
developer326d4232023-06-15 16:45:30 +08004396 int count = 0;
4397 token_channel = strtok(possible_channels, ",");
4398 while (token_channel != NULL) {
4399 int channel = atoi(token_channel);
4400 if (channel <= MAX_CHANNEL_NUMBER && skip_table[channel] == CHANNEL_AVAILABLE) {
4401 count += snprintf(&output_pool[count], CHANNEL_LIST_MAX_LENGTH-count, "%d,", channel);
4402 if (count >= CHANNEL_LIST_MAX_LENGTH-1)
4403 break;
4404 }
4405 token_channel = strtok(NULL, ",");
4406 }
4407 //delete the last one ','
4408 if (count >0 && output_pool[count-1] == ',')
4409 output_pool[count-1] = '\0';
developera3511852023-06-14 14:12:59 +08004410 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004411}
4412
4413INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
4414{
developer326d4232023-06-15 16:45:30 +08004415 char config_file_dat[128] = {0};
4416 struct params dat = {0};
4417 wifi_band band = band_invalid;
4418 char new_pool[128] = {0};
developer75bd10c2023-06-27 11:34:08 +08004419 int res;
developer326d4232023-06-15 16:45:30 +08004420
4421 if (NULL == pool)
4422 return RETURN_ERR;
4423
developer9ce44382023-06-28 11:09:37 +08004424 strncpy(new_pool, pool, sizeof(new_pool) - 1);
4425 new_pool[sizeof(new_pool) - 1] = '\0';
developer326d4232023-06-15 16:45:30 +08004426 for (int i = 0; new_pool[i] != '\0'; i++) {
4427 if (new_pool[i] == ',')
4428 new_pool[i] = ';';
4429 }
4430
4431 dat.name = "AutoChannelSkipList";
4432 dat.value = new_pool;
4433 band = wifi_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08004434 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4435 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4436 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4437 return RETURN_ERR;
4438 }
developer326d4232023-06-15 16:45:30 +08004439 if (wifi_datfileWrite(config_file_dat, &dat, 1) != 0)
4440 return RETURN_ERR;
4441 wifi_reloadAp(radioIndex);
4442
developera3511852023-06-14 14:12:59 +08004443 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004444}
4445
4446INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
4447{
developera3511852023-06-14 14:12:59 +08004448 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
4449 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004450 //Should refresh period time be filled in here? output_interval_seconds is INT type
4451 //wifi_getRadioAutoChannelRefreshPeriod is Ulong type
4452 *output_interval_seconds = 1800;
4453 *output_dwell_milliseconds = 200;
developer72fb0bb2023-01-11 09:46:29 +08004454
developera3511852023-06-14 14:12:59 +08004455 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004456}
4457
4458INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
4459{
developera3511852023-06-14 14:12:59 +08004460 //Set to wifi config. And apply instantly.
4461 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004462}
4463
4464INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
4465{
developera3511852023-06-14 14:12:59 +08004466 if (output_bool == NULL)
4467 return RETURN_ERR;
4468 *output_bool = true;
4469 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004470}
4471
4472INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
4473{
developera3511852023-06-14 14:12:59 +08004474 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004475}
4476
4477//Get the Dfs enable status
4478INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
4479{
developera3511852023-06-14 14:12:59 +08004480 char buf[16] = {0};
4481 char config_file_dat[128] = {0};
4482 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004483 int res;
developer72fb0bb2023-01-11 09:46:29 +08004484
developera3511852023-06-14 14:12:59 +08004485 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004486
developera3511852023-06-14 14:12:59 +08004487 if (output_bool == NULL)
4488 return RETURN_ERR;
4489 *output_bool = TRUE; // default
4490 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004491 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4492 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4493 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4494 return RETURN_ERR;
4495 }
developerd1824452023-05-18 12:30:04 +08004496
developera3511852023-06-14 14:12:59 +08004497 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08004498
developera3511852023-06-14 14:12:59 +08004499 if (strncmp(buf, "0", 1) == 0)
4500 *output_bool = FALSE;
4501 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4502 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004503}
4504
4505//Set the Dfs enable status
4506INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
4507{
developera3511852023-06-14 14:12:59 +08004508 char config_dat_file[128] = {0};
4509 FILE *f = NULL;
4510 struct params dat = {0};
4511 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08004512 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +08004513
developera3511852023-06-14 14:12:59 +08004514 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004515
developera3511852023-06-14 14:12:59 +08004516 f = fopen(DFS_ENABLE_FILE, "w");
4517 if (f == NULL)
4518 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08004519 ret = fprintf(f, "%d", enable);
4520 if (ret < 0)
4521 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developera3511852023-06-14 14:12:59 +08004522 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08004523
developera3511852023-06-14 14:12:59 +08004524 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08004525
developera3511852023-06-14 14:12:59 +08004526 dat.name = "DfsEnable";
4527 dat.value = enable?"1":"0";
4528 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004529 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4530 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4531 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4532 return RETURN_ERR;
4533 }
4534
developera3511852023-06-14 14:12:59 +08004535 wifi_datfileWrite(config_dat_file, &dat, 1);
4536 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4537 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004538}
4539
4540//Check if the driver support the AutoChannelRefreshPeriod
4541INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
4542{
developera3511852023-06-14 14:12:59 +08004543 if (NULL == output_bool)
4544 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004545 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004546
developera3511852023-06-14 14:12:59 +08004547 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004548}
4549
developer326d4232023-06-15 16:45:30 +08004550
4551int get_ACS_RefreshPeriod_callback(struct nl_msg *msg, void *arg)
4552{
4553 ULONG *data = (ULONG *)arg;
4554 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4555 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
4556 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4557 int err = 0;
4558
4559 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4560 genlmsg_attrlen(gnlh, 0), NULL);
4561 if (err < 0)
4562 return NL_SKIP;
4563
4564 if (tb[NL80211_ATTR_VENDOR_DATA]) {
4565 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
4566 tb[NL80211_ATTR_VENDOR_DATA], NULL);
4567 if (err < 0)
4568 return NL_SKIP;
4569
4570 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]) {
4571 *data = nla_get_u32(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]);
4572 }
4573 }
4574
4575 return NL_OK;
4576}
4577
developer72fb0bb2023-01-11 09:46:29 +08004578//Get the ACS refresh period in seconds
4579INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
4580{
developer326d4232023-06-15 16:45:30 +08004581 char interface_name[IF_NAME_SIZE] = {0};
4582 int ret = -1;
4583 unsigned int if_idx = 0;
4584 struct unl unl_ins;
4585 struct nl_msg *msg = NULL;
4586 struct nlattr * msg_data = NULL;
4587 struct mtk_nl80211_param param;
4588 unsigned long checktime = 0;
4589
4590 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08004591 if (NULL == output_ulong)
4592 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004593
4594 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4595 return RETURN_ERR;
4596
4597 if_idx = if_nametoindex(interface_name);
4598 if (!if_idx) {
4599 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4600 return RETURN_ERR;
4601 }
4602 /*init mtk nl80211 vendor cmd*/
4603 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
4604 param.if_type = NL80211_ATTR_IFINDEX;
4605 param.if_idx = if_idx;
developer72fb0bb2023-01-11 09:46:29 +08004606
developer326d4232023-06-15 16:45:30 +08004607 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4608 if (ret) {
4609 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4610 return RETURN_ERR;
4611 }
4612
4613 /*add mtk vendor cmd data*/
4614 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD, 0)) {
4615 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD attribute error\n");
4616 nlmsg_free(msg);
4617 goto err;
4618 }
4619
4620 /*send mtk nl80211 vendor msg*/
4621 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ACS_RefreshPeriod_callback, &checktime);
4622
4623 if (ret) {
4624 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4625 goto err;
4626 }
4627 /*deinit mtk nl80211 vendor msg*/
4628 mtk_nl80211_deint(&unl_ins);
4629 *output_ulong = checktime;
4630 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
4631
4632 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08004633 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08004634err:
4635 mtk_nl80211_deint(&unl_ins);
4636 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
4637 return RETURN_ERR;
4638
developer72fb0bb2023-01-11 09:46:29 +08004639}
4640
4641//Set the ACS refresh period in seconds
4642INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
4643{
developer326d4232023-06-15 16:45:30 +08004644 char interface_name[IF_NAME_SIZE] = {0};
4645 int ret = -1;
4646 unsigned int if_idx = 0;
4647 struct unl unl_ins;
4648 struct nl_msg *msg = NULL;
4649 struct nlattr * msg_data = NULL;
4650 struct mtk_nl80211_param param;
4651
4652 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4653
4654 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4655 return RETURN_ERR;
4656
4657 if_idx = if_nametoindex(interface_name);
4658 if (!if_idx) {
4659 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4660 return RETURN_ERR;
4661 }
4662 /*init mtk nl80211 vendor cmd*/
4663 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
4664 param.if_type = NL80211_ATTR_IFINDEX;
4665 param.if_idx = if_idx;
4666
4667 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4668 if (ret) {
4669 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4670 return RETURN_ERR;
4671 }
4672
4673 /*add mtk vendor cmd data*/
4674 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
4675 wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME attribute error\n");
4676 nlmsg_free(msg);
4677 goto err;
4678 }
4679
4680 /*send mtk nl80211 vendor msg*/
4681 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4682
4683 if (ret) {
4684 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4685 goto err;
4686 }
4687 /*deinit mtk nl80211 vendor msg*/
4688 mtk_nl80211_deint(&unl_ins);
4689 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
4690
4691 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4692 return RETURN_OK;
4693err:
4694 mtk_nl80211_deint(&unl_ins);
4695 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developera3511852023-06-14 14:12:59 +08004696 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004697}
4698
4699//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
4700//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.
4701INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
4702{
developera3511852023-06-14 14:12:59 +08004703 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
4704 char extchannel[128] = {0};
4705 char interface_name[64] = {0};
developere40952c2023-06-15 18:46:43 +08004706 int ret = 0, len=0, res;
developera3511852023-06-14 14:12:59 +08004707 BOOL radio_enable = FALSE;
4708 wifi_band band;
developer72fb0bb2023-01-11 09:46:29 +08004709
developera3511852023-06-14 14:12:59 +08004710 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004711
developera3511852023-06-14 14:12:59 +08004712 if (NULL == output_string) {
4713 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
4714 return RETURN_ERR;
4715 }
4716 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
4717 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
4718 return RETURN_ERR;
4719 }
4720 if (radio_enable != TRUE) {
4721 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
4722 return RETURN_OK;
4723 }
4724 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4725 return RETURN_ERR;
4726 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08004727
developere40952c2023-06-15 18:46:43 +08004728 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
4729 if (os_snprintf_error(sizeof(cmd), res)) {
4730 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4731 return RETURN_ERR;
4732 }
developera3511852023-06-14 14:12:59 +08004733 ret = _syscmd(cmd, buf, sizeof(buf));
4734 len = strlen(buf);
4735 if((ret != 0) || (len == 0))
4736 {
4737 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4738 return RETURN_ERR;
4739 }
developer8666b312023-03-24 14:05:31 +08004740
developera3511852023-06-14 14:12:59 +08004741 band = wifi_index_to_band(radioIndex);
4742 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
4743 wifi_getRadioExtChannel(radioIndex, extchannel);
developere40952c2023-06-15 18:46:43 +08004744 if (strncmp(extchannel, "Auto", 4) != 0) {
4745 res = snprintf(buf, sizeof(buf), "40");
4746 if (os_snprintf_error(sizeof(buf), res)) {
4747 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4748 return RETURN_ERR;
4749 }
4750 }
4751 }
4752 res = snprintf(output_string, 64, "%sMHz", buf);
4753 if (os_snprintf_error(64, res)) {
4754 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4755 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08004756 }
developera3511852023-06-14 14:12:59 +08004757 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004758
developera3511852023-06-14 14:12:59 +08004759 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004760}
4761
4762enum mwctl_chan_width {
4763 MWCTL_CHAN_WIDTH_20,
4764 MWCTL_CHAN_WIDTH_40,
4765 MWCTL_CHAN_WIDTH_80,
4766 MWCTL_CHAN_WIDTH_160,
4767 MWCTL_CHAN_WIDTH_320,
4768};
4769
4770struct bw_option {
4771 unsigned int bandwith;
4772 enum mwctl_chan_width mode;
4773};
4774
4775struct bw_option bw_opt[] = {
4776 {20, MWCTL_CHAN_WIDTH_20},
4777 {40, MWCTL_CHAN_WIDTH_40},
4778 {80, MWCTL_CHAN_WIDTH_80},
4779 {160, MWCTL_CHAN_WIDTH_160},
4780 {320, MWCTL_CHAN_WIDTH_320},
4781};
4782
4783INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
4784{
4785 int ret = -1;
4786 int i;
4787 struct unl unl_ins;
4788 struct nl_msg *msg = NULL;
4789 struct nlattr * msg_data = NULL;
4790 struct mtk_nl80211_param param;
4791 bool b_match = FALSE;
4792
4793 /*init mtk nl80211 vendor cmd*/
4794 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
4795 param.if_type = NL80211_ATTR_WIPHY;
4796 param.if_idx = radio_index_to_phy(radioIndex);
4797
4798 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4799 if (ret) {
4800 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4801 return RETURN_ERR;
4802 }
4803
4804 /*add mtk vendor cmd data*/
4805 if (channel != NULL)
4806 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
4807 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
4808 nlmsg_free(msg);
4809 goto err;
4810 }
4811
4812 if (bandwidth != NULL) {
4813 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
4814 if (bw_opt[i].bandwith == *bandwidth) {
4815 b_match = true;
4816 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
4817 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
4818 nlmsg_free(msg);
4819 goto err;
4820 }
4821 break;
4822 }
4823 }
4824
4825 if (!b_match) {
4826 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
4827 nlmsg_free(msg);
4828 goto err;
4829 }
4830 }
4831
4832 /*send mtk nl80211 vendor msg*/
4833 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4834 if (ret) {
4835 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4836 goto err;
4837 }
4838 /*deinit mtk nl80211 vendor msg*/
4839 mtk_nl80211_deint(&unl_ins);
4840 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developera3511852023-06-14 14:12:59 +08004841 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developerfead3972023-05-25 20:15:02 +08004842
developera3511852023-06-14 14:12:59 +08004843 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004844err:
4845 mtk_nl80211_deint(&unl_ins);
4846 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4847 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004848}
developerfead3972023-05-25 20:15:02 +08004849
developer72fb0bb2023-01-11 09:46:29 +08004850//Set the Operating Channel Bandwidth.
4851INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
4852{
developera3511852023-06-14 14:12:59 +08004853 char config_file[128];
4854 char ht_value[16];
4855 char vht_value[16];
4856 char eht_value[16];
4857 struct params dat[3];
4858 wifi_band band = band_invalid;
4859 unsigned int bw = 20;
developere40952c2023-06-15 18:46:43 +08004860 int ret = 0, res1, res2, res3;
developer72fb0bb2023-01-11 09:46:29 +08004861
developera3511852023-06-14 14:12:59 +08004862 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004863
developera3511852023-06-14 14:12:59 +08004864 if(NULL == bandwidth)
4865 return RETURN_ERR;
4866 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004867
developera3511852023-06-14 14:12:59 +08004868 if(strstr(bandwidth,"320") != NULL) {
developere40952c2023-06-15 18:46:43 +08004869 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4870 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4871 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developera3511852023-06-14 14:12:59 +08004872 bw = 320;
4873 } else if(strstr(bandwidth,"160") != NULL) {
developere40952c2023-06-15 18:46:43 +08004874 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4875 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4876 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developera3511852023-06-14 14:12:59 +08004877 bw = 160;
4878 } else if(strstr(bandwidth,"80") != NULL) {
developere40952c2023-06-15 18:46:43 +08004879 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4880 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
4881 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developera3511852023-06-14 14:12:59 +08004882 bw = 80;
4883 } else if(strstr(bandwidth,"40") != NULL) {
developere40952c2023-06-15 18:46:43 +08004884 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4885 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4886 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developera3511852023-06-14 14:12:59 +08004887 bw = 40;
4888 } else if(strstr(bandwidth,"20") != NULL) {
developere40952c2023-06-15 18:46:43 +08004889 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
4890 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4891 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developera3511852023-06-14 14:12:59 +08004892 bw = 20;
4893 } else {
4894 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
4895 return RETURN_ERR;
4896 }
developer72fb0bb2023-01-11 09:46:29 +08004897
developere40952c2023-06-15 18:46:43 +08004898 if (os_snprintf_error(sizeof(ht_value), res1)) {
4899 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4900 return RETURN_ERR;
4901 }
4902 if (os_snprintf_error(sizeof(vht_value), res2)) {
4903 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4904 return RETURN_ERR;
4905 }
4906 if (os_snprintf_error(sizeof(eht_value), res3)) {
4907 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4908 return RETURN_ERR;
4909 }
4910
4911 res1 = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4912 if (os_snprintf_error(sizeof(config_file), res1)) {
4913 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4914 return RETURN_ERR;
4915 }
developera3511852023-06-14 14:12:59 +08004916 dat[0].name = "HT_BW";
4917 dat[0].value = ht_value;
4918 dat[1].name = "VHT_BW";
4919 dat[1].value = vht_value;
4920 dat[2].name = "EHT_ApBw";
4921 dat[2].value = eht_value;
4922 wifi_datfileWrite(config_file, dat, 3);
4923 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
developerfead3972023-05-25 20:15:02 +08004924 if (ret != RETURN_OK) {
developera3511852023-06-14 14:12:59 +08004925 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
4926 return RETURN_ERR;
4927 }
developer72fb0bb2023-01-11 09:46:29 +08004928
developera3511852023-06-14 14:12:59 +08004929 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4930 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004931}
4932
developer72fb0bb2023-01-11 09:46:29 +08004933//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
4934//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.
4935INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
4936{
developera3511852023-06-14 14:12:59 +08004937 char config_file[64] = {0};
4938 char config_dat_file[64] = {0};
4939 char mode_str[16] = {0};
4940 char buf[64] = {0};
4941 char cmd[MAX_CMD_SIZE] = {0};
4942 char interface_name[64] = {0};
4943 int ret = 0, len=0;
4944 wifi_band band;
4945 ULONG channel = 0;
4946 int centr_channel = 0;
4947 UINT mode_map = 0;
developere40952c2023-06-15 18:46:43 +08004948 int freq=0, res;
developer72fb0bb2023-01-11 09:46:29 +08004949
developera3511852023-06-14 14:12:59 +08004950 if (output_string == NULL)
4951 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004952
developer86035662023-06-28 19:21:12 +08004953 if (wifi_getRadioMode(radioIndex, mode_str, &mode_map) != RETURN_OK) {
4954 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode fail\n");
4955 }
developer72fb0bb2023-01-11 09:46:29 +08004956
developera3511852023-06-14 14:12:59 +08004957 band = wifi_index_to_band(radioIndex);
4958 if (band == band_invalid)
4959 return RETURN_ERR;
4960 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4961 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004962
developere40952c2023-06-15 18:46:43 +08004963 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4964 if (os_snprintf_error(sizeof(config_file), res)) {
4965 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4966 return RETURN_ERR;
4967 }
4968
4969 res = snprintf(output_string, 64, "Auto");
4970 if (os_snprintf_error(64, res)) {
4971 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4972 return RETURN_ERR;
4973 }
developer72fb0bb2023-01-11 09:46:29 +08004974
developera3511852023-06-14 14:12:59 +08004975 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
4976 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
developere40952c2023-06-15 18:46:43 +08004977 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4978 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4979 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4980 return RETURN_ERR;
4981 }
developerb758dfd2023-06-21 17:32:07 +08004982
developera3511852023-06-14 14:12:59 +08004983 wifi_halgetRadioExtChannel(config_dat_file, output_string);
4984 if (!(mode_map&WIFI_MODE_N))
developere40952c2023-06-15 18:46:43 +08004985 res = snprintf(output_string, 64, "Auto");
developera3511852023-06-14 14:12:59 +08004986 } else {
4987 // 5G and 6G band with ac or ax mode.
4988 wifi_getRadioChannel(radioIndex, &channel);
developere40952c2023-06-15 18:46:43 +08004989 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
4990 if (os_snprintf_error(sizeof(cmd), res)) {
4991 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4992 return RETURN_ERR;
4993 }
developerd1824452023-05-18 12:30:04 +08004994
developera3511852023-06-14 14:12:59 +08004995 ret = _syscmd(cmd, buf, sizeof(buf));
4996 len = strlen(buf);
4997 if((ret != 0) || (len == 0))
4998 {
4999 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
5000 return RETURN_ERR;
5001 }
5002 sscanf(buf, "%d", &freq);
5003 centr_channel = ieee80211_frequency_to_channel(freq);
5004 if (centr_channel > (int)channel)
developere40952c2023-06-15 18:46:43 +08005005 res = snprintf(output_string, 64, "AboveControlChannel");
developera3511852023-06-14 14:12:59 +08005006 else
developere40952c2023-06-15 18:46:43 +08005007 res = snprintf(output_string, 64, "BelowControlChannel");
5008
5009 if (os_snprintf_error(64, res)) {
5010 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5011 return RETURN_ERR;
5012 }
developera3511852023-06-14 14:12:59 +08005013 }
developer72fb0bb2023-01-11 09:46:29 +08005014
developera3511852023-06-14 14:12:59 +08005015 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005016}
5017
5018//Set the extension channel.
5019INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08005020{
developera3511852023-06-14 14:12:59 +08005021 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5022 struct params params={0};
5023 char config_file[64] = {0};
5024 char config_dat_file[64] = {0};
5025 char ext_channel[64] = {0};
5026 char buf[128] = {0};
5027 char cmd[128] = {0};
5028 int max_radio_num =0, ret = 0, bandwidth = 0;
5029 unsigned long channel = 0;
5030 bool stbcEnable = FALSE;
5031 params.name = "ht_capab";
5032 wifi_band band;
developere40952c2023-06-15 18:46:43 +08005033 int res;
developer72fb0bb2023-01-11 09:46:29 +08005034
developer75bd10c2023-06-27 11:34:08 +08005035 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5036 if (os_snprintf_error(sizeof(config_file), res)) {
5037 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5038 return RETURN_ERR;
5039 }
5040
developere40952c2023-06-15 18:46:43 +08005041 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
5042 if (os_snprintf_error(sizeof(cmd), res)) {
5043 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5044 return RETURN_ERR;
5045 }
developera3511852023-06-14 14:12:59 +08005046 _syscmd(cmd, buf, sizeof(buf));
5047 if (strlen(buf) != 0)
5048 stbcEnable = TRUE;
5049 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
5050 return RETURN_ERR;
5051 bandwidth = strtol(buf, NULL, 10);
5052 // TDK expected to get error with 20MHz
5053 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
5054 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
5055 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005056
developera3511852023-06-14 14:12:59 +08005057 band = wifi_index_to_band(radioIndex);
5058 if (band == band_invalid)
5059 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005060
developera3511852023-06-14 14:12:59 +08005061 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
5062 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005063
developere40952c2023-06-15 18:46:43 +08005064 res = snprintf(buf, sizeof(buf), "HT%d", bandwidth);
5065 if (os_snprintf_error(sizeof(buf), res)) {
5066 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5067 return RETURN_ERR;
5068 }
developera3511852023-06-14 14:12:59 +08005069 ret = util_get_sec_chan_offset(channel, buf);
5070 if (ret == -EINVAL)
5071 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005072
developera3511852023-06-14 14:12:59 +08005073 if(NULL!= strstr(string,"Above")) {
5074 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
5075 return RETURN_OK;
developer32f2a182023-06-27 19:50:41 +08005076 memcpy(ext_channel, "Above", strlen("Above"));
developera3511852023-06-14 14:12:59 +08005077 } else if(NULL!= strstr(string,"Below")) {
5078 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
5079 return RETURN_OK;
developer32f2a182023-06-27 19:50:41 +08005080 memcpy(ext_channel, "Below", strlen("Below"));
developera3511852023-06-14 14:12:59 +08005081 } else {
5082 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08005083 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08005084 }
5085 params.name = "HT_EXTCHA";
5086 params.value = ext_channel;
developer72fb0bb2023-01-11 09:46:29 +08005087
developera3511852023-06-14 14:12:59 +08005088 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08005089 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5090 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5091 return RETURN_ERR;
5092 }
developera3511852023-06-14 14:12:59 +08005093 wifi_datfileWrite(config_dat_file, &params, 1);
developerd1824452023-05-18 12:30:04 +08005094
developera3511852023-06-14 14:12:59 +08005095 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08005096 if(max_radio_num== 0){
5097 return RETURN_ERR;
5098 }
developera3511852023-06-14 14:12:59 +08005099 for(int i=0; i<=MAX_APS/max_radio_num; i++)
5100 {
developer32f2a182023-06-27 19:50:41 +08005101 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
5102 if (os_snprintf_error(sizeof(config_file), res)) {
5103 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5104 return RETURN_ERR;
5105 }
developera3511852023-06-14 14:12:59 +08005106 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
5107 }
developer72fb0bb2023-01-11 09:46:29 +08005108
developera3511852023-06-14 14:12:59 +08005109 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
5110 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5111 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005112}
5113
5114//Get the guard interval value. eg "400nsec" or "800nsec"
5115//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.
5116INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
5117{
developera3511852023-06-14 14:12:59 +08005118 wifi_guard_interval_t GI;
developer32f2a182023-06-27 19:50:41 +08005119 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08005120
developera3511852023-06-14 14:12:59 +08005121 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005122
developera3511852023-06-14 14:12:59 +08005123 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
5124 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005125
developer32f2a182023-06-27 19:50:41 +08005126 if (GI == wifi_guard_interval_400) {
5127 len = strlen("400nsec");
5128 memcpy(output_string, "400nsec", len);
5129 } else if (GI == wifi_guard_interval_800) {
5130 len = strlen("800nsec");
5131 memcpy(output_string, "800nsec", strlen("800nsec"));
5132 } else if (GI == wifi_guard_interval_1600) {
5133 len = strlen("1600nsec");
5134 memcpy(output_string, "1600nsec", strlen("1600nsec"));
5135 } else if (GI == wifi_guard_interval_3200) {
5136 len = strlen("3200nsec");
5137 memcpy(output_string, "3200nsec", strlen("3200nsec"));
5138 } else {
5139 len = strlen("Auto");
5140 memcpy(output_string, "Auto", strlen("Auto"));
5141 }
5142 output_string[len] = '\0';
developera3511852023-06-14 14:12:59 +08005143 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5144 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005145}
5146
5147//Set the guard interval value.
5148INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
5149{
developera3511852023-06-14 14:12:59 +08005150 wifi_guard_interval_t GI;
5151 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08005152
developera3511852023-06-14 14:12:59 +08005153 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005154
developera3511852023-06-14 14:12:59 +08005155 if (strcmp(string, "400nsec") == 0)
5156 GI = wifi_guard_interval_400;
5157 else if (strcmp(string , "800nsec") == 0)
5158 GI = wifi_guard_interval_800;
5159 else if (strcmp(string , "1600nsec") == 0)
5160 GI = wifi_guard_interval_1600;
5161 else if (strcmp(string , "3200nsec") == 0)
5162 GI = wifi_guard_interval_3200;
5163 else
5164 GI = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +08005165
developera3511852023-06-14 14:12:59 +08005166 ret = wifi_setGuardInterval(radioIndex, GI);
developer72fb0bb2023-01-11 09:46:29 +08005167
developera3511852023-06-14 14:12:59 +08005168 if (ret == RETURN_ERR) {
5169 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
5170 return RETURN_ERR;
5171 }
developer72fb0bb2023-01-11 09:46:29 +08005172
developera3511852023-06-14 14:12:59 +08005173 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5174 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005175}
5176
5177//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
5178INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
5179{
developera3511852023-06-14 14:12:59 +08005180 char buf[32]={0};
5181 char mcs_file[64] = {0};
5182 char cmd[MAX_CMD_SIZE] = {0};
5183 UINT mode_bitmap = 0;
developere40952c2023-06-15 18:46:43 +08005184 int res;
developer72fb0bb2023-01-11 09:46:29 +08005185
developera3511852023-06-14 14:12:59 +08005186 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5187 if(output_int == NULL)
5188 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005189 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
5190 if (os_snprintf_error(sizeof(mcs_file), res)) {
5191 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5192 return RETURN_ERR;
5193 }
5194
5195 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
5196 if (os_snprintf_error(sizeof(cmd), res)) {
5197 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5198 return RETURN_ERR;
5199 }
developer72fb0bb2023-01-11 09:46:29 +08005200
developera3511852023-06-14 14:12:59 +08005201 _syscmd(cmd, buf, sizeof(buf));
5202 if (strlen(buf) > 0)
5203 *output_int = strtol(buf, NULL, 10);
5204 else {
5205 // output the max MCS for the current radio mode
5206 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
5207 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
5208 return RETURN_ERR;
5209 }
5210 if (mode_bitmap & WIFI_MODE_AX) {
5211 *output_int = 11;
5212 } else if (mode_bitmap & WIFI_MODE_AC) {
5213 *output_int = 9;
5214 } else if (mode_bitmap & WIFI_MODE_N) {
5215 *output_int = 7;
5216 }
5217 }
5218 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005219
developera3511852023-06-14 14:12:59 +08005220 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005221}
5222
5223//Set the Modulation Coding Scheme index
5224INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
5225{
developera3511852023-06-14 14:12:59 +08005226 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
5227 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
5228 char config_file[64] = {0};
5229 char set_value[16] = {0};
5230 char mcs_file[32] = {0};
5231 struct params set_config = {0};
5232 FILE *f = NULL;
5233 INT nss = 0;
5234 int ant_bitmap = 0;
5235 unsigned short cal_value = 0;
5236 UCHAR tval = 0, i = 0;
developere40952c2023-06-15 18:46:43 +08005237 int res;
developer72fb0bb2023-01-11 09:46:29 +08005238
developera3511852023-06-14 14:12:59 +08005239 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005240
developere40952c2023-06-15 18:46:43 +08005241 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5242 if (os_snprintf_error(sizeof(config_file), res)) {
5243 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5244 return RETURN_ERR;
5245 }
developer72fb0bb2023-01-11 09:46:29 +08005246
developera3511852023-06-14 14:12:59 +08005247 // -1 means auto
5248 if (MCS > 15 || MCS < -1) {
developer75bd10c2023-06-27 11:34:08 +08005249 wifi_debug(DEBUG_ERROR, "invalid MCS %d\n", MCS);
developera3511852023-06-14 14:12:59 +08005250 return RETURN_ERR;
5251 }
5252 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
5253 for(; ant_bitmap > 0; ant_bitmap >>= 1)
5254 nss += 1;
5255 //printf("%s:nss = %d\n", __func__, nss);
5256 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
5257 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
5258 if (MCS > 9 || MCS == -1)
5259 tval = 2;/*one stream value*/
5260 else if (MCS > 7)
5261 tval = 1;
5262 else
5263 tval = 0;
5264 for (i = 0; i < nss; i++)
5265 cal_value |= (tval << (2*i));
developere40952c2023-06-15 18:46:43 +08005266 res = snprintf(set_value, sizeof(set_value), "%x", cal_value);
5267 if (os_snprintf_error(sizeof(set_value), res)) {
5268 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5269 return RETURN_ERR;
5270 }
5271
developera3511852023-06-14 14:12:59 +08005272 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
5273 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
5274 set_config.value = set_value;
developer72fb0bb2023-01-11 09:46:29 +08005275
developera3511852023-06-14 14:12:59 +08005276 wifi_hostapdWrite(config_file, &set_config, 1);
5277 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
developer72fb0bb2023-01-11 09:46:29 +08005278
developera3511852023-06-14 14:12:59 +08005279 // 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 +08005280 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
5281 if (os_snprintf_error(sizeof(mcs_file), res)) {
5282 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5283 return RETURN_ERR;
5284 }
5285
developera3511852023-06-14 14:12:59 +08005286 f = fopen(mcs_file, "w");
5287 if (f == NULL) {
5288 fprintf(stderr, "%s: fopen failed\n", __func__);
5289 return RETURN_ERR;
5290 }
5291 fprintf(f, "%d", MCS);
5292 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08005293
developera3511852023-06-14 14:12:59 +08005294 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5295 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005296}
5297
5298//Get supported Transmit Power list, eg : "0,25,50,75,100"
5299//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.
5300INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
5301{
developere40952c2023-06-15 18:46:43 +08005302 int res;
5303 if (NULL == output_list)
5304 return RETURN_ERR;
5305 res = snprintf(output_list, 64,"0,25,50,75,100");
5306 if (os_snprintf_error(64, res)) {
5307 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5308 return RETURN_ERR;
5309 }
5310
5311 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005312}
5313
5314//Get current Transmit Power in dBm units.
5315//The transmite power level is in units of full power for this radio.
5316INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
5317{
developera3511852023-06-14 14:12:59 +08005318 char interface_name[16] = {0};
5319 char cmd[MAX_CMD_SIZE]={0};
5320 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08005321 char pwr_file[128]={0};
developere40952c2023-06-15 18:46:43 +08005322 int res;
developera1255e42023-05-13 17:45:02 +08005323
developera3511852023-06-14 14:12:59 +08005324 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005325
developera3511852023-06-14 14:12:59 +08005326 if(output_ulong == NULL)
5327 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005328
developera3511852023-06-14 14:12:59 +08005329 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5330 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005331 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
5332 if (os_snprintf_error(sizeof(pwr_file), res)) {
5333 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5334 return RETURN_ERR;
5335 }
5336
5337 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
5338 if (os_snprintf_error(sizeof(cmd), res)) {
5339 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5340 return RETURN_ERR;
5341 }
5342
developera1255e42023-05-13 17:45:02 +08005343 _syscmd(cmd, buf, sizeof(buf));
5344 if (strlen(buf) > 0)
5345 *output_ulong = strtol(buf, NULL, 10);
5346 else
5347 *output_ulong = 100;
developera3511852023-06-14 14:12:59 +08005348 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5349 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005350}
5351
5352//Set Transmit Power
5353//The transmite power level is in units of full power for this radio.
5354INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
5355{
developera3511852023-06-14 14:12:59 +08005356 char interface_name[16] = {0};
5357 char *support;
5358 char buf[128]={0};
5359 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08005360 char pwr_file[128]={0};
developera3511852023-06-14 14:12:59 +08005361 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08005362 int if_idx, ret = 0;
5363 struct nl_msg *msg = NULL;
5364 struct nlattr * msg_data = NULL;
5365 struct mtk_nl80211_param param;
5366 struct unl unl_ins;
developere40952c2023-06-15 18:46:43 +08005367 int res;
developer72fb0bb2023-01-11 09:46:29 +08005368
developera3511852023-06-14 14:12:59 +08005369 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005370
developera3511852023-06-14 14:12:59 +08005371 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5372 return RETURN_ERR;
5373 // Get the Tx power supported list and check that is the input in the list
developere40952c2023-06-15 18:46:43 +08005374 res = snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
5375 if (os_snprintf_error(sizeof(txpower_str), res)) {
5376 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5377 return RETURN_ERR;
5378 }
developera3511852023-06-14 14:12:59 +08005379 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
5380 support = strtok(buf, ",");
5381 while(true)
5382 {
5383 if(support == NULL) { // input not in the list
5384 wifi_dbg_printf("Input value is invalid.\n");
5385 return RETURN_ERR;
5386 }
5387 if (strncmp(txpower_str, support, strlen(support)) == 0) {
5388 break;
5389 }
5390 support = strtok(NULL, ",");
5391 }
developerfead3972023-05-25 20:15:02 +08005392
5393 if_idx = if_nametoindex(interface_name);
5394 /*init mtk nl80211 vendor cmd*/
5395 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
5396 param.if_type = NL80211_ATTR_IFINDEX;
5397 param.if_idx = if_idx;
5398 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
5399 if (ret) {
5400 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
5401 return RETURN_ERR;
5402 }
5403 /*add mtk vendor cmd data*/
5404 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
5405 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
5406 nlmsg_free(msg);
5407 goto err;
5408 }
5409
5410 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
5411 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
5412 nlmsg_free(msg);
5413 goto err;
5414 }
5415
5416 /*send mtk nl80211 vendor msg*/
5417 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
5418 if (ret) {
5419 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
5420 goto err;
5421 }
5422 /*deinit mtk nl80211 vendor msg*/
5423 mtk_nl80211_deint(&unl_ins);
5424 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
5425
developere40952c2023-06-15 18:46:43 +08005426 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
5427 if (os_snprintf_error(sizeof(pwr_file), res)) {
5428 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5429 return RETURN_ERR;
5430 }
5431
developera3511852023-06-14 14:12:59 +08005432 f = fopen(pwr_file, "w");
5433 if (f == NULL) {
5434 fprintf(stderr, "%s: fopen failed\n", __func__);
5435 return RETURN_ERR;
5436 }
5437 fprintf(f, "%lu", TransmitPower);
5438 fclose(f);
developera1255e42023-05-13 17:45:02 +08005439 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08005440err:
5441 mtk_nl80211_deint(&unl_ins);
5442 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
5443 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005444}
5445
5446//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
5447INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
5448{
developera3511852023-06-14 14:12:59 +08005449 if (NULL == Supported)
5450 return RETURN_ERR;
5451 *Supported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08005452
developera3511852023-06-14 14:12:59 +08005453 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005454}
5455
5456//Get 80211h feature enable
5457INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
5458{
developera3511852023-06-14 14:12:59 +08005459 char buf[64]={'\0'};
5460 char config_file[64] = {'\0'};
developer75bd10c2023-06-27 11:34:08 +08005461 int res;
developer72fb0bb2023-01-11 09:46:29 +08005462
developera3511852023-06-14 14:12:59 +08005463 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5464 if(enable == NULL)
5465 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005466
developer75bd10c2023-06-27 11:34:08 +08005467 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5468 if (os_snprintf_error(sizeof(config_file), res)) {
5469 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5470 return RETURN_ERR;
5471 }
developera3511852023-06-14 14:12:59 +08005472 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
5473 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005474
developera3511852023-06-14 14:12:59 +08005475 if (strncmp(buf, "1", 1) == 0)
5476 *enable = TRUE;
5477 else
5478 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08005479
developera3511852023-06-14 14:12:59 +08005480 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5481 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005482}
5483
5484//Set 80211h feature enable
5485INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
5486{
developera3511852023-06-14 14:12:59 +08005487 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5488 struct params params={'\0'};
5489 struct params dat={0};
5490 char config_file[MAX_BUF_SIZE] = {0};
5491 char config_dat_file[MAX_BUF_SIZE] = {0};
5492 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08005493 int res;
developer72fb0bb2023-01-11 09:46:29 +08005494
developera3511852023-06-14 14:12:59 +08005495 params.name = "ieee80211h";
developer72fb0bb2023-01-11 09:46:29 +08005496
developera3511852023-06-14 14:12:59 +08005497 if (enable) {
5498 params.value = "1";
5499 } else {
5500 params.value = "0";
5501 }
developer72fb0bb2023-01-11 09:46:29 +08005502
developera3511852023-06-14 14:12:59 +08005503 dat.name = "IEEE80211H";
5504 dat.value = params.value;
developerd1824452023-05-18 12:30:04 +08005505
developera3511852023-06-14 14:12:59 +08005506 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08005507 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5508 if (os_snprintf_error(sizeof(config_file), res)) {
5509 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5510 return RETURN_ERR;
5511 }
5512
5513 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5514 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5515 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5516 return RETURN_ERR;
5517 }
developer69b61b02023-03-07 17:17:44 +08005518
developera3511852023-06-14 14:12:59 +08005519 wifi_hostapdWrite(config_file, &params, 1);
5520 wifi_datfileWrite(config_dat_file, &dat, 1);
5521 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
5522 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5523 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005524}
5525
5526//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.
5527INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
5528{
developera3511852023-06-14 14:12:59 +08005529 if (NULL == output)
5530 return RETURN_ERR;
5531 *output=100;
developer72fb0bb2023-01-11 09:46:29 +08005532
developera3511852023-06-14 14:12:59 +08005533 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005534}
5535
5536//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.
5537INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
5538{
developera3511852023-06-14 14:12:59 +08005539 if (NULL == output)
5540 return RETURN_ERR;
5541 *output = -99;
developer72fb0bb2023-01-11 09:46:29 +08005542
developera3511852023-06-14 14:12:59 +08005543 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005544}
5545
5546INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
5547{
developera3511852023-06-14 14:12:59 +08005548 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005549}
5550
5551
5552//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
5553INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
5554{
developera3511852023-06-14 14:12:59 +08005555 char interface_name[16] = {0};
5556 char cmd[MAX_BUF_SIZE]={'\0'};
5557 char buf[MAX_CMD_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08005558 int res;
developer72fb0bb2023-01-11 09:46:29 +08005559
developera3511852023-06-14 14:12:59 +08005560 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5561 if(output == NULL)
5562 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005563
developera3511852023-06-14 14:12:59 +08005564 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5565 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005566 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
5567 if (os_snprintf_error(sizeof(cmd), res)) {
5568 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5569 return RETURN_ERR;
5570 }
5571
developera3511852023-06-14 14:12:59 +08005572 _syscmd(cmd, buf, sizeof(buf));
5573 *output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08005574
developera3511852023-06-14 14:12:59 +08005575 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5576 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005577}
developer69b61b02023-03-07 17:17:44 +08005578
developer72fb0bb2023-01-11 09:46:29 +08005579INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
5580{
developera3511852023-06-14 14:12:59 +08005581 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5582 struct params params={'\0'};
5583 char buf[MAX_BUF_SIZE] = {'\0'};
5584 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08005585 int res;
developer72fb0bb2023-01-11 09:46:29 +08005586
developera3511852023-06-14 14:12:59 +08005587 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
5588 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005589
developera3511852023-06-14 14:12:59 +08005590 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08005591 res = snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
5592 if (os_snprintf_error(sizeof(buf), res)) {
5593 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5594 return RETURN_ERR;
5595 }
5596
developera3511852023-06-14 14:12:59 +08005597 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08005598
developer75bd10c2023-06-27 11:34:08 +08005599 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5600 if (os_snprintf_error(sizeof(config_file), res)) {
5601 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5602 return RETURN_ERR;
5603 }
developera3511852023-06-14 14:12:59 +08005604 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08005605
developera3511852023-06-14 14:12:59 +08005606 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
5607 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5608 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005609}
5610
5611//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.
5612INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
5613{
developera3511852023-06-14 14:12:59 +08005614 //TODO: need to revisit below implementation
5615 char *temp;
5616 char temp_output[128] = {0};
5617 char temp_TransmitRates[64] = {0};
5618 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +08005619 int res;
developer72fb0bb2023-01-11 09:46:29 +08005620
developera3511852023-06-14 14:12:59 +08005621 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5622 if (NULL == output)
5623 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08005624
5625 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5626 if (os_snprintf_error(sizeof(config_file), res)) {
5627 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5628 return RETURN_ERR;
5629 }
developera3511852023-06-14 14:12:59 +08005630 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08005631
developera3511852023-06-14 14:12:59 +08005632 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
5633 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
5634 } else {
5635 temp = strtok(temp_TransmitRates," ");
5636 while(temp!=NULL)
5637 {
5638 // Convert 100 kbps to Mbps
5639 temp[strlen(temp)-1]=0;
5640 if((temp[0]=='5') && (temp[1]=='\0'))
5641 {
5642 temp="5.5";
5643 }
developer32f2a182023-06-27 19:50:41 +08005644 if (strlen(temp) >= sizeof(temp_output))
5645 return RETURN_ERR;
5646 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005647 temp = strtok(NULL," ");
5648 if(temp!=NULL)
5649 {
developer32f2a182023-06-27 19:50:41 +08005650 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
5651 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005652 }
5653 }
developer32f2a182023-06-27 19:50:41 +08005654 memcpy(output, temp_output, strlen(temp_output));
5655 output[strlen(temp_output)] = '\0';
developera3511852023-06-14 14:12:59 +08005656 }
5657 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5658 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005659}
5660
5661INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
5662{
developera3511852023-06-14 14:12:59 +08005663 char *temp;
developer32f2a182023-06-27 19:50:41 +08005664 char temp1[128] = {0};
5665 char temp_output[128] = {0};
5666 char temp_TransmitRates[128] = {0};
5667 char set[128] = {0};
5668 char sub_set[128] = {0};
developera3511852023-06-14 14:12:59 +08005669 int set_count=0,subset_count=0;
5670 int set_index=0,subset_index=0;
5671 char *token;
5672 int flag=0, i=0;
5673 struct params params={'\0'};
5674 char config_file[MAX_BUF_SIZE] = {0};
5675 wifi_band band = wifi_index_to_band(radioIndex);
developer32f2a182023-06-27 19:50:41 +08005676 int res;
developer72fb0bb2023-01-11 09:46:29 +08005677
developera3511852023-06-14 14:12:59 +08005678 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5679 if(NULL == TransmitRates)
5680 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +08005681 if (strlen(TransmitRates) >= sizeof(sub_set))
5682 return RETURN_ERR;
5683
5684 memcpy(sub_set, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08005685
developera3511852023-06-14 14:12:59 +08005686 //Allow only supported Data transmit rate to be set
5687 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
5688 token = strtok(sub_set,",");
5689 while( token != NULL ) /* split the basic rate to be set, by comma */
5690 {
5691 sub_set[subset_count]=atoi(token);
5692 subset_count++;
5693 token=strtok(NULL,",");
5694 }
5695 token=strtok(set,",");
5696 while(token!=NULL) /* split the supported rate by comma */
5697 {
5698 set[set_count]=atoi(token);
5699 set_count++;
5700 token=strtok(NULL,",");
5701 }
5702 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
5703 {
5704 for(set_index=0;set_index < set_count;set_index++)
5705 {
5706 flag=0;
5707 if(sub_set[subset_index]==set[set_index])
5708 break;
5709 else
5710 flag=1; /* No match found */
5711 }
5712 if(flag==1)
5713 return RETURN_ERR; //If value not found return Error
5714 }
developer32f2a182023-06-27 19:50:41 +08005715
5716 if (strlen(TransmitRates) >= sizeof(temp_TransmitRates))
5717 return RETURN_ERR;
5718
5719 memcpy(temp_TransmitRates, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08005720
developera3511852023-06-14 14:12:59 +08005721 for(i=0;i<strlen(temp_TransmitRates);i++)
5722 {
5723 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
5724 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
5725 {
5726 continue;
5727 }
5728 else
5729 {
5730 return RETURN_ERR;
5731 }
5732 }
developera3511852023-06-14 14:12:59 +08005733 temp = strtok(temp_TransmitRates,",");
5734 while(temp!=NULL)
5735 {
developer32f2a182023-06-27 19:50:41 +08005736 if (strlen(temp) >= sizeof(temp1))
5737 return RETURN_ERR;
5738 strncpy(temp1, temp, strlen(temp));
developera3511852023-06-14 14:12:59 +08005739 if(band == band_5)
5740 {
5741 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
5742 {
5743 return RETURN_ERR;
5744 }
5745 }
developer72fb0bb2023-01-11 09:46:29 +08005746
developera3511852023-06-14 14:12:59 +08005747 if(strcmp(temp,"5.5")==0)
5748 {
developer32f2a182023-06-27 19:50:41 +08005749 memcpy(temp1, "55", 2);
developera3511852023-06-14 14:12:59 +08005750 }
5751 else
5752 {
developer32f2a182023-06-27 19:50:41 +08005753 if (strlen(temp1) >= (sizeof(temp1) - 1))
5754 return RETURN_ERR;
5755 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +08005756 }
developer32f2a182023-06-27 19:50:41 +08005757 if (strlen(temp1) >= (sizeof(temp_output) - strlen(temp_output)))
5758 return RETURN_ERR;
5759 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005760 temp = strtok(NULL,",");
5761 if(temp!=NULL)
5762 {
developer32f2a182023-06-27 19:50:41 +08005763 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
5764 return RETURN_ERR;
5765 strncat(temp_output," ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005766 }
5767 }
developer32f2a182023-06-27 19:50:41 +08005768 memcpy(TransmitRates, temp_output, strlen(temp_output));
5769 TransmitRates[strlen(temp_output)] = '\0';
5770
developera3511852023-06-14 14:12:59 +08005771 params.name= "basic_rates";
5772 params.value =TransmitRates;
developer72fb0bb2023-01-11 09:46:29 +08005773
developera3511852023-06-14 14:12:59 +08005774 wifi_dbg_printf("\n%s:",__func__);
5775 wifi_dbg_printf("\nparams.value=%s\n",params.value);
5776 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
developer32f2a182023-06-27 19:50:41 +08005777 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,radioIndex);
5778 if (os_snprintf_error(sizeof(config_file), res)) {
5779 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5780 return RETURN_ERR;
5781 }
5782
developera3511852023-06-14 14:12:59 +08005783 wifi_hostapdWrite(config_file,&params,1);
5784 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5785 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005786}
5787
developer72fb0bb2023-01-11 09:46:29 +08005788INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
5789{
developera3511852023-06-14 14:12:59 +08005790 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5791 output_struct->radio_BytesSent = 0;
5792 output_struct->radio_BytesReceived = 0;
5793 output_struct->radio_PacketsSent = 0;
5794 output_struct->radio_PacketsReceived = 0;
5795 output_struct->radio_ErrorsSent = 0;
5796 output_struct->radio_ErrorsReceived = 0;
5797 output_struct->radio_DiscardPacketsSent = 0;
5798 output_struct->radio_DiscardPacketsReceived = 0;
5799 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5800 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005801}
5802
5803
5804INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
5805{
developera3511852023-06-14 14:12:59 +08005806 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5807 CHAR buf[MAX_CMD_SIZE] = {0};
5808 CHAR Value[MAX_BUF_SIZE] = {0};
5809 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08005810 int res;
developer72fb0bb2023-01-11 09:46:29 +08005811
developera3511852023-06-14 14:12:59 +08005812 if (ifname == NULL || strlen(ifname) <= 1)
5813 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005814
developere40952c2023-06-15 18:46:43 +08005815 res = snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
5816 if (os_snprintf_error(sizeof(buf), res)) {
5817 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5818 return RETURN_ERR;
5819 }
5820
developera3511852023-06-14 14:12:59 +08005821 system(buf);
developer72fb0bb2023-01-11 09:46:29 +08005822
developera3511852023-06-14 14:12:59 +08005823 fp = fopen("/tmp/Radio_Stats.txt", "r");
5824 if(fp == NULL)
5825 {
5826 printf("/tmp/Radio_Stats.txt not exists \n");
5827 return RETURN_ERR;
5828 }
5829 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +08005830
developer75bd10c2023-06-27 11:34:08 +08005831 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5832 if (os_snprintf_error(sizeof(buf), res)) {
5833 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5834 return RETURN_ERR;
5835 }
5836
developera3511852023-06-14 14:12:59 +08005837 File_Reading(buf, Value);
5838 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005839
developer86035662023-06-28 19:21:12 +08005840 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5841 if (os_snprintf_error(sizeof(buf), res)) {
5842 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5843 return RETURN_ERR;
5844 }
developera3511852023-06-14 14:12:59 +08005845 File_Reading(buf, Value);
5846 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005847
developer86035662023-06-28 19:21:12 +08005848 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5849 if (os_snprintf_error(sizeof(buf), res)) {
5850 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5851 return RETURN_ERR;
5852 }
developera3511852023-06-14 14:12:59 +08005853 File_Reading(buf, Value);
5854 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005855
developer86035662023-06-28 19:21:12 +08005856 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5857 if (os_snprintf_error(sizeof(buf), res)) {
5858 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5859 return RETURN_ERR;
5860 }
developera3511852023-06-14 14:12:59 +08005861 File_Reading(buf, Value);
5862 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005863
developer86035662023-06-28 19:21:12 +08005864 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5865 if (os_snprintf_error(sizeof(buf), res)) {
5866 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5867 return RETURN_ERR;
5868 }
developera3511852023-06-14 14:12:59 +08005869 File_Reading(buf, Value);
5870 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005871
developer86035662023-06-28 19:21:12 +08005872 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5873 if (os_snprintf_error(sizeof(buf), res)) {
5874 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5875 return RETURN_ERR;
5876 }
developera3511852023-06-14 14:12:59 +08005877 File_Reading(buf, Value);
5878 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005879
developer86035662023-06-28 19:21:12 +08005880 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5881 if (os_snprintf_error(sizeof(buf), res)) {
5882 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5883 return RETURN_ERR;
5884 }
developera3511852023-06-14 14:12:59 +08005885 File_Reading(buf, Value);
5886 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005887
developer86035662023-06-28 19:21:12 +08005888 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5889 if (os_snprintf_error(sizeof(buf), res)) {
5890 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5891 return RETURN_ERR;
5892 }
developera3511852023-06-14 14:12:59 +08005893 File_Reading(buf, Value);
5894 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005895
developera3511852023-06-14 14:12:59 +08005896 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5897 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005898}
5899
5900INT GetIfacestatus(CHAR *interface_name, CHAR *status)
5901{
developer7e4a2a62023-04-06 19:56:03 +08005902 CHAR buf[MAX_CMD_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08005903 int res;
developer72fb0bb2023-01-11 09:46:29 +08005904
developer7e4a2a62023-04-06 19:56:03 +08005905 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5906
5907 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
developer75bd10c2023-06-27 11:34:08 +08005908 res = snprintf(buf, sizeof(buf), "%s%s%s%s%s", "ifconfig -a ",
5909 interface_name, " | grep ", interface_name, " | wc -l");
5910
5911 if (os_snprintf_error(sizeof(buf), res)) {
5912 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5913 return RETURN_ERR;
5914 }
developer7e4a2a62023-04-06 19:56:03 +08005915 File_Reading(buf, status);
5916 }
5917
5918 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5919 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005920}
5921
5922//Get detail radio traffic static info
5923INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
5924{
developera3511852023-06-14 14:12:59 +08005925 CHAR interface_name[64] = {0};
5926 BOOL iface_status = FALSE;
5927 wifi_radioTrafficStats2_t radioTrafficStats = {0};
developer72fb0bb2023-01-11 09:46:29 +08005928
developera3511852023-06-14 14:12:59 +08005929 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5930 if (NULL == output_struct)
5931 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005932
developera3511852023-06-14 14:12:59 +08005933 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5934 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005935
developera3511852023-06-14 14:12:59 +08005936 wifi_getApEnable(radioIndex, &iface_status);
developer72fb0bb2023-01-11 09:46:29 +08005937
developera3511852023-06-14 14:12:59 +08005938 if (iface_status == TRUE)
5939 wifi_halGetIfStats(interface_name, &radioTrafficStats);
5940 else
5941 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
developer72fb0bb2023-01-11 09:46:29 +08005942
developera3511852023-06-14 14:12:59 +08005943 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
5944 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
5945 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
5946 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
5947 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
5948 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
5949 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
5950 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +08005951
developera3511852023-06-14 14:12:59 +08005952 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
5953 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].
5954 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
5955 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.
5956 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
5957 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
5958 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
5959 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
5960 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 +08005961
developera3511852023-06-14 14:12:59 +08005962 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
5963 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
5964 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
5965 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 +08005966
developera3511852023-06-14 14:12:59 +08005967 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005968
developera3511852023-06-14 14:12:59 +08005969 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005970}
5971
5972//Set radio traffic static Measureing rules
5973INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
5974{
developera39cfb22023-06-20 16:28:17 +08005975 char inf_name[IF_NAME_SIZE] = {0};
5976 unsigned int if_idx = 0;
5977 int ret = -1;
5978 struct unl unl_ins;
5979 struct nl_msg *msg = NULL;
5980 struct nlattr * msg_data = NULL;
5981 struct mtk_nl80211_param param;
5982
5983 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
5984 return RETURN_ERR;
5985 if_idx = if_nametoindex(inf_name);
5986 if (!if_idx) {
5987 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
5988 return RETURN_ERR;
5989 }
5990 /*init mtk nl80211 vendor cmd*/
5991 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
5992 param.if_type = NL80211_ATTR_IFINDEX;
5993 param.if_idx = if_idx;
5994
5995 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
5996 if (ret) {
5997 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
5998 return RETURN_ERR;
5999 }
6000 /*add mtk vendor cmd data*/
6001 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD,
6002 sizeof(wifi_radioTrafficStatsMeasure_t), input_struct)) {
6003 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
6004 MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD);
6005 nlmsg_free(msg);
6006 goto err;
6007 }
6008
6009 /*send mtk nl80211 vendor msg*/
6010 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6011 if (ret) {
6012 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6013 goto err;
6014 }
6015 /*deinit mtk nl80211 vendor msg*/
6016 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08006017 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08006018err:
6019 mtk_nl80211_deint(&unl_ins);
6020 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6021 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006022}
6023
6024//To start or stop RadioTrafficStats
6025INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
6026{
developera39cfb22023-06-20 16:28:17 +08006027 char inf_name[IF_NAME_SIZE] = {0};
6028 unsigned int if_idx = 0;
6029 int ret = -1;
6030 struct unl unl_ins;
6031 struct nl_msg *msg = NULL;
6032 struct nlattr * msg_data = NULL;
6033 struct mtk_nl80211_param param;
6034
6035 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
6036 return RETURN_ERR;
6037 if_idx = if_nametoindex(inf_name);
6038 if (!if_idx) {
6039 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6040 return RETURN_ERR;
6041 }
6042 /*init mtk nl80211 vendor cmd*/
6043 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
6044 param.if_type = NL80211_ATTR_IFINDEX;
6045 param.if_idx = if_idx;
6046
6047 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6048 if (ret) {
6049 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6050 return RETURN_ERR;
6051 }
6052 /*add mtk vendor cmd data*/
6053 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL, enable)) {
6054 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
6055 MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL);
6056 nlmsg_free(msg);
6057 goto err;
6058 }
6059
6060 /*send mtk nl80211 vendor msg*/
6061 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6062 if (ret) {
6063 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6064 goto err;
6065 }
6066 /*deinit mtk nl80211 vendor msg*/
6067 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08006068 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08006069err:
6070 mtk_nl80211_deint(&unl_ins);
6071 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6072 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006073}
6074
6075//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
6076INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
6077{
developera3511852023-06-14 14:12:59 +08006078 if (NULL == SignalLevel)
6079 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08006080
developer9ce44382023-06-28 11:09:37 +08006081 *SignalLevel = -19;
developer72fb0bb2023-01-11 09:46:29 +08006082
developera3511852023-06-14 14:12:59 +08006083 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006084}
6085
6086//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
6087INT wifi_applyRadioSettings(INT radioIndex)
6088{
developera3511852023-06-14 14:12:59 +08006089 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006090}
6091
6092//Get the radio index assocated with this SSID entry
6093INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
6094{
developera3511852023-06-14 14:12:59 +08006095 if(NULL == radioIndex)
6096 return RETURN_ERR;
6097 int max_radio_num = 0;
6098 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08006099 if(max_radio_num == 0){
6100 return RETURN_ERR;
6101 }
developera3511852023-06-14 14:12:59 +08006102 *radioIndex = ssidIndex%max_radio_num;
6103 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006104}
6105
6106//Device.WiFi.SSID.{i}.Enable
6107//Get SSID enable configuration parameters (not the SSID enable status)
6108INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
6109{
developera3511852023-06-14 14:12:59 +08006110 if (NULL == output_bool)
6111 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006112
developera3511852023-06-14 14:12:59 +08006113 return wifi_getApEnable(ssidIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006114}
6115
6116//Device.WiFi.SSID.{i}.Enable
6117//Set SSID enable configuration parameters
6118INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
6119{
developera3511852023-06-14 14:12:59 +08006120 return wifi_setApEnable(ssidIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08006121}
6122
6123//Device.WiFi.SSID.{i}.Status
6124//Get the SSID enable status
6125INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
6126{
developer9ce44382023-06-28 11:09:37 +08006127 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +08006128 int res;
developer72fb0bb2023-01-11 09:46:29 +08006129
developera3511852023-06-14 14:12:59 +08006130 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6131 if (NULL == output_string)
6132 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08006133
developera3511852023-06-14 14:12:59 +08006134 wifi_getApEnable(ssidIndex,&output_bool);
developere40952c2023-06-15 18:46:43 +08006135 res = snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
6136 if (os_snprintf_error(32, res)) {
6137 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6138 return RETURN_ERR;
6139 }
developer72fb0bb2023-01-11 09:46:29 +08006140
developera3511852023-06-14 14:12:59 +08006141 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6142 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006143}
6144
6145// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
6146INT wifi_getSSIDName(INT apIndex, CHAR *output)
6147{
developera3511852023-06-14 14:12:59 +08006148 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006149 int res;
developer72fb0bb2023-01-11 09:46:29 +08006150
developera3511852023-06-14 14:12:59 +08006151 if (NULL == output)
6152 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006153
developer75bd10c2023-06-27 11:34:08 +08006154 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6155 if (os_snprintf_error(sizeof(config_file), res)) {
6156 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6157 return RETURN_ERR;
6158 }
developera3511852023-06-14 14:12:59 +08006159 wifi_hostapdRead(config_file,"ssid",output,32);
developer72fb0bb2023-01-11 09:46:29 +08006160
developera3511852023-06-14 14:12:59 +08006161 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
6162 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006163}
6164
developer69b61b02023-03-07 17:17:44 +08006165// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08006166INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
6167{
developera3511852023-06-14 14:12:59 +08006168 struct params params;
6169 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006170 int res;
developer72fb0bb2023-01-11 09:46:29 +08006171
developera3511852023-06-14 14:12:59 +08006172 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6173 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
6174 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006175
developera3511852023-06-14 14:12:59 +08006176 params.name = "ssid";
6177 params.value = ssid_string;
developer75bd10c2023-06-27 11:34:08 +08006178
6179 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6180 if (os_snprintf_error(sizeof(config_file), res)) {
6181 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6182 return RETURN_ERR;
6183 }
6184
developera3511852023-06-14 14:12:59 +08006185 wifi_hostapdWrite(config_file, &params, 1);
6186 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6187 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006188
developera3511852023-06-14 14:12:59 +08006189 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006190}
6191
6192//Get the BSSID
6193INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
6194{
developer7e4a2a62023-04-06 19:56:03 +08006195 char cmd[MAX_CMD_SIZE] = {0};
6196 char inf_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08006197 int res;
developer72fb0bb2023-01-11 09:46:29 +08006198
developera3511852023-06-14 14:12:59 +08006199 if (!output_string)
developerdaf24792023-06-06 11:40:04 +08006200 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006201
developer47cc27a2023-05-17 23:09:58 +08006202 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
6203 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08006204
developer5b2f10c2023-05-25 17:02:21 +08006205 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
6206 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
6207 strncpy(output_string, "\0", 1);
6208 return RETURN_ERR;
6209 }
developere40952c2023-06-15 18:46:43 +08006210 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
6211 if (os_snprintf_error(sizeof(cmd), res)) {
6212 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6213 return RETURN_ERR;
6214 }
6215
developer5b2f10c2023-05-25 17:02:21 +08006216 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08006217
developer5b2f10c2023-05-25 17:02:21 +08006218 /* if hostapd does not control interface even if this interface has been brought up,
6219 * try to get its mac address by iw command.
6220 */
6221 if(strlen(output_string) == 0) {
6222 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08006223 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
6224 if (os_snprintf_error(sizeof(cmd), res)) {
6225 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6226 return RETURN_ERR;
6227 }
6228
developer5b2f10c2023-05-25 17:02:21 +08006229 _syscmd(cmd, output_string, 64);
6230 }
developer72fb0bb2023-01-11 09:46:29 +08006231
developer5b2f10c2023-05-25 17:02:21 +08006232 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006233}
6234
6235//Get the MAC address associated with this Wifi SSID
6236INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
6237{
developera3511852023-06-14 14:12:59 +08006238 wifi_getBaseBSSID(ssidIndex,output_string);
6239 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006240}
6241
6242//Get the basic SSID traffic static info
6243//Apply SSID and AP (in the case of Acess Point devices) to the hardware
6244//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
6245INT wifi_applySSIDSettings(INT ssidIndex)
6246{
developera3511852023-06-14 14:12:59 +08006247 char interface_name[16] = {0};
6248 BOOL status = false;
6249 char cmd[MAX_CMD_SIZE] = {0};
6250 char buf[MAX_CMD_SIZE] = {0};
6251 int apIndex, ret;
6252 int max_radio_num = 0;
6253 int radioIndex = 0;
developere40952c2023-06-15 18:46:43 +08006254 int res;
developer72fb0bb2023-01-11 09:46:29 +08006255
developera3511852023-06-14 14:12:59 +08006256 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08006257 if(max_radio_num == 0){
6258 return RETURN_ERR;
6259 }
developera3511852023-06-14 14:12:59 +08006260 radioIndex = ssidIndex % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +08006261
developera3511852023-06-14 14:12:59 +08006262 wifi_getApEnable(ssidIndex,&status);
6263 // Do not apply when ssid index is disabled
6264 if (status == false)
6265 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006266
developera3511852023-06-14 14:12:59 +08006267 /* Doing full remove and add for ssid Index
6268 * Not all hostapd options are supported with reload
6269 * for example macaddr_acl
6270 */
6271 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
6272 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006273
developera3511852023-06-14 14:12:59 +08006274 ret = wifi_setApEnable(ssidIndex,true);
developer72fb0bb2023-01-11 09:46:29 +08006275
developera3511852023-06-14 14:12:59 +08006276 /* Workaround for hostapd issue with multiple bss definitions
6277 * when first created interface will be removed
6278 * then all vaps other vaps on same phy are removed
6279 * after calling setApEnable to false readd all enabled vaps */
6280 for(int i=0; i < MAX_APS/max_radio_num; i++) {
6281 apIndex = max_radio_num*i+radioIndex;
6282 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6283 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006284 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
6285 if (os_snprintf_error(sizeof(cmd), res)) {
6286 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6287 return RETURN_ERR;
6288 }
6289
developera3511852023-06-14 14:12:59 +08006290 _syscmd(cmd, buf, sizeof(buf));
6291 if(*buf == '1')
6292 wifi_setApEnable(apIndex, true);
6293 }
developer72fb0bb2023-01-11 09:46:29 +08006294
developera3511852023-06-14 14:12:59 +08006295 return ret;
developer72fb0bb2023-01-11 09:46:29 +08006296}
6297
6298struct channels_noise {
developera3511852023-06-14 14:12:59 +08006299 int channel;
6300 int noise;
developer72fb0bb2023-01-11 09:46:29 +08006301};
6302
6303// Return noise array for each channel
6304int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
6305{
developera3511852023-06-14 14:12:59 +08006306 char interface_name[16] = {0};
6307 FILE *f = NULL;
6308 char cmd[128] = {0};
6309 char line[256] = {0};
developer75bd10c2023-06-27 11:34:08 +08006310 int tmp = 0, arr_index = -1, res;
developer72fb0bb2023-01-11 09:46:29 +08006311
developera3511852023-06-14 14:12:59 +08006312 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6313 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08006314
6315 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
6316 if (os_snprintf_error(sizeof(cmd), res)) {
6317 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6318 return RETURN_ERR;
6319 }
developer72fb0bb2023-01-11 09:46:29 +08006320
developera3511852023-06-14 14:12:59 +08006321 if ((f = popen(cmd, "r")) == NULL) {
6322 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6323 return RETURN_ERR;
6324 }
developer69b61b02023-03-07 17:17:44 +08006325
developera3511852023-06-14 14:12:59 +08006326 while(fgets(line, sizeof(line), f) != NULL) {
6327 if(arr_index < channels_num){
6328 sscanf(line, "%d", &tmp);
6329 if (tmp > 0) { // channel frequency, the first line must be frequency
6330 arr_index++;
6331 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
6332 } else { // noise
6333 channels_noise_arr[arr_index].noise = tmp;
6334 }
6335 }else{
6336 break;
6337 }
6338 }
6339 pclose(f);
6340 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006341}
6342
6343//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
6344//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08006345INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08006346{
developera3511852023-06-14 14:12:59 +08006347 int index = -1;
6348 wifi_neighbor_ap2_t *scan_array = NULL;
6349 char cmd[256]={0};
6350 char buf[128]={0};
6351 char file_name[32] = {0};
6352 char filter_SSID[32] = {0};
6353 char line[256] = {0};
6354 char interface_name[16] = {0};
6355 char *ret = NULL;
6356 int freq=0;
6357 FILE *f = NULL;
6358 int channels_num = 0;
6359 int vht_channel_width = 0;
6360 int get_noise_ret = RETURN_ERR;
6361 bool filter_enable = false;
6362 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
developere40952c2023-06-15 18:46:43 +08006363 int phyId = 0, res;
developer32f2a182023-06-27 19:50:41 +08006364 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08006365
developera3511852023-06-14 14:12:59 +08006366 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006367
developera3511852023-06-14 14:12:59 +08006368 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6369 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006370
6371 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
6372 if (os_snprintf_error(sizeof(file_name), res)) {
6373 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6374 return RETURN_ERR;
6375 }
developer72fb0bb2023-01-11 09:46:29 +08006376
developera3511852023-06-14 14:12:59 +08006377 f = fopen(file_name, "r");
6378 if (f != NULL) {
6379 fgets(buf, sizeof(file_name), f);
6380 if ((strncmp(buf, "0", 1)) != 0) {
6381 fgets(filter_SSID, sizeof(file_name), f);
6382 if (strlen(filter_SSID) != 0)
6383 filter_enable = true;
6384 }
6385 fclose(f);
6386 }
developer72fb0bb2023-01-11 09:46:29 +08006387
developera3511852023-06-14 14:12:59 +08006388 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08006389 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
6390 if (os_snprintf_error(sizeof(cmd), res)) {
6391 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6392 return RETURN_ERR;
6393 }
6394
developera3511852023-06-14 14:12:59 +08006395 _syscmd(cmd, buf, sizeof(buf));
6396 channels_num = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08006397
developer32f2a182023-06-27 19:50:41 +08006398 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 +08006399 // 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 +08006400 if (os_snprintf_error(sizeof(cmd), res)) {
6401 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6402 return RETURN_ERR;
6403 }
developer86035662023-06-28 19:21:12 +08006404 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developera3511852023-06-14 14:12:59 +08006405 if ((f = popen(cmd, "r")) == NULL) {
6406 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6407 return RETURN_ERR;
6408 }
developer9ce44382023-06-28 11:09:37 +08006409 struct channels_noise *channels_noise_arr = NULL;
6410 if(channels_num > 0 && channels_num <= 243){
6411 channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
6412 } else{
6413 return RETURN_ERR;
6414 }
6415
6416 if(channels_noise_arr != NULL){
6417 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
6418 } else{
6419 fclose(f);
6420 return RETURN_ERR;
6421 }
6422
developer69b61b02023-03-07 17:17:44 +08006423
developera3511852023-06-14 14:12:59 +08006424 ret = fgets(line, sizeof(line), f);
6425 while (ret != NULL) {
6426 if(strstr(line, "BSS") != NULL) { // new neighbor info
6427 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
6428 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
6429 // 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 +08006430
developera3511852023-06-14 14:12:59 +08006431 if (!filter_BSS) {
6432 index++;
6433 wifi_neighbor_ap2_t *tmp;
6434 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
6435 if (tmp == NULL) { // no more memory to use
6436 index--;
6437 wifi_dbg_printf("%s: realloc failed\n", __func__);
6438 break;
6439 }
6440 scan_array = tmp;
6441 }
6442 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +08006443
developera3511852023-06-14 14:12:59 +08006444 filter_BSS = false;
developer86035662023-06-28 19:21:12 +08006445 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
6446 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6447 goto err;
6448 }
developerc79e9172023-06-06 19:48:03 +08006449 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +08006450 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +08006451 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +08006452 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +08006453 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +08006454 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
6455 } else if (strstr(line, "freq") != NULL) {
developer86035662023-06-28 19:21:12 +08006456 if (sscanf(line," freq: %d", &freq) != 1) {
6457 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6458 goto err;
6459 }
developera3511852023-06-14 14:12:59 +08006460 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +08006461
developera3511852023-06-14 14:12:59 +08006462 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +08006463 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08006464 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +08006465 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08006466 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +08006467 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08006468 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
6469 }
6470 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +08006471 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08006472 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +08006473 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08006474 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +08006475 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08006476 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
6477 }
developer72fb0bb2023-01-11 09:46:29 +08006478
developera3511852023-06-14 14:12:59 +08006479 scan_array[index].ap_Noise = 0;
6480 if (get_noise_ret == RETURN_OK) {
6481 for (int i = 0; i < channels_num; i++) {
6482 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
6483 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
6484 break;
6485 }
6486 }
6487 }
6488 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +08006489 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
6490 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6491 goto err;
6492 }
developera3511852023-06-14 14:12:59 +08006493 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +08006494 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
6495 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6496 goto err;
6497 }
developera3511852023-06-14 14:12:59 +08006498 } else if (strstr(line,"SSID") != NULL) {
developer86035662023-06-28 19:21:12 +08006499 if (sscanf(line," SSID: %32s", scan_array[index].ap_SSID) != 1) {
6500 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6501 goto err;
6502 }
developera3511852023-06-14 14:12:59 +08006503 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
6504 filter_BSS = true;
6505 }
6506 } else if (strstr(line, "Supported rates") != NULL) {
6507 char SRate[80] = {0}, *tmp = NULL;
6508 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08006509 if (strlen(line) >= sizeof(SRate))
developer86035662023-06-28 19:21:12 +08006510 goto err;
developer32f2a182023-06-27 19:50:41 +08006511 strncpy(SRate, line, strlen(line));
developera3511852023-06-14 14:12:59 +08006512 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +08006513 if (tmp == NULL)
6514 goto err;
developera3511852023-06-14 14:12:59 +08006515 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +08006516 if (tmp == NULL)
6517 goto err;
developer32f2a182023-06-27 19:50:41 +08006518 if (strlen(tmp) >= sizeof(buf))
developer86035662023-06-28 19:21:12 +08006519 goto err;
developer32f2a182023-06-27 19:50:41 +08006520 strncpy(buf, tmp, strlen(tmp));
developera3511852023-06-14 14:12:59 +08006521 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +08006522
developera3511852023-06-14 14:12:59 +08006523 tmp = strtok(buf, " \n");
6524 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +08006525 if (strlen(tmp) >= (sizeof(SRate) - strlen(SRate)))
developer86035662023-06-28 19:21:12 +08006526 goto err;
developer32f2a182023-06-27 19:50:41 +08006527 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +08006528 if (SRate[strlen(SRate) - 1] == '*') {
6529 SRate[strlen(SRate) - 1] = '\0';
6530 }
developer32f2a182023-06-27 19:50:41 +08006531 if (strlen(SRate) >= (sizeof(SRate) - 1))
developer86035662023-06-28 19:21:12 +08006532 goto err;
developer32f2a182023-06-27 19:50:41 +08006533 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +08006534
developera3511852023-06-14 14:12:59 +08006535 tmp = strtok(NULL, " \n");
6536 }
6537 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +08006538 if (sizeof(scan_array[index].ap_SupportedDataTransferRates) <= strlen(SRate))
developer86035662023-06-28 19:21:12 +08006539 goto err;
developer32f2a182023-06-27 19:50:41 +08006540 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, strlen(SRate));
developera3511852023-06-14 14:12:59 +08006541 } else if (strstr(line, "DTIM") != NULL) {
developer86035662023-06-28 19:21:12 +08006542 if (sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod)) != 1) {
6543 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6544 goto err;
6545 }
developera3511852023-06-14 14:12:59 +08006546 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006547 if (sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) <= 4)
developer86035662023-06-28 19:21:12 +08006548 goto err;
developer32f2a182023-06-27 19:50:41 +08006549 strncat(scan_array[index].ap_SupportedStandards, ",ac",
6550 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6551 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
6552 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +08006553 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006554 strncat(scan_array[index].ap_SupportedStandards, ",n", sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6555 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
6556 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +08006557 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08006558 if (fgets(line, sizeof(line), f) == NULL) {
6559 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6560 goto err;
6561 }
6562 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
6563 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6564 goto err;
6565 }
developera3511852023-06-14 14:12:59 +08006566 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +08006567 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +08006568 } else {
developere40952c2023-06-15 18:46:43 +08006569 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +08006570 }
developere40952c2023-06-15 18:46:43 +08006571 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
6572 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +08006573 free(channels_noise_arr);
6574 fclose(f);
developere40952c2023-06-15 18:46:43 +08006575 return RETURN_ERR;
6576 }
6577
developera3511852023-06-14 14:12:59 +08006578 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
6579 continue;
6580 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08006581 if (fgets(line, sizeof(line), f) == NULL) {
6582 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6583 goto err;
6584 }
6585 if (sscanf(line," * secondary channel offset: %s", buf) != 1) {
6586 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6587 goto err;
6588 }
developera3511852023-06-14 14:12:59 +08006589 if (!strcmp(buf, "above")) {
6590 //40Mhz +
developere40952c2023-06-15 18:46:43 +08006591 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 +08006592 }
6593 else if (!strcmp(buf, "below")) {
6594 //40Mhz -
developere40952c2023-06-15 18:46:43 +08006595 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 +08006596 } else {
6597 //20Mhz
developere40952c2023-06-15 18:46:43 +08006598 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
6599 }
6600 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
6601 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +08006602 goto err;
developera3511852023-06-14 14:12:59 +08006603 }
developere40952c2023-06-15 18:46:43 +08006604
developera3511852023-06-14 14:12:59 +08006605 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
6606 continue;
6607 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006608 strncat(scan_array[index].ap_SupportedStandards, ",ax",
6609 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6610 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
6611 scan_array[index].ap_OperatingStandards[2] = '\0';
developer86035662023-06-28 19:21:12 +08006612 if (fgets(line, sizeof(line), f) == NULL) {
6613 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6614 goto err;
6615 }
developera3511852023-06-14 14:12:59 +08006616 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +08006617 if (strstr(line, "HE40/2.4GHz") != NULL) {
6618 len = strlen("11AXHE40PLUS");
6619 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
6620 } else {
6621 len = strlen("11AXHE20");
6622 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
6623 }
6624 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +08006625 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
6626 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006627 len = strlen("11AXHE80");
6628 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
6629 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developer86035662023-06-28 19:21:12 +08006630 if (fgets(line, sizeof(line), f) == NULL) {
6631 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6632 goto err;
6633 }
developera3511852023-06-14 14:12:59 +08006634 } else
6635 continue;
developer32f2a182023-06-27 19:50:41 +08006636 if (strstr(line, "HE160/5GHz") != NULL) {
6637 len = strlen("11AXHE160");
6638 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
6639 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
6640 }
developera3511852023-06-14 14:12:59 +08006641 }
6642 continue;
6643 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006644 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
6645 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08006646 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006647 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
6648 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08006649 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +08006650 if (sscanf(line, " * Group cipher: %64s", scan_array[index].ap_EncryptionMode) != 1) {
6651 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6652 goto err;
6653 }
developera3511852023-06-14 14:12:59 +08006654 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +08006655 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
6656 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +08006657 }
6658 }
developer86035662023-06-28 19:21:12 +08006659 if (fgets(line, sizeof(line), f) == NULL) {
6660 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6661 goto err;
6662 }
developera3511852023-06-14 14:12:59 +08006663 }
developer72fb0bb2023-01-11 09:46:29 +08006664
developera3511852023-06-14 14:12:59 +08006665 if (!filter_BSS) {
6666 *output_array_size = index + 1;
6667 } else {
6668 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
6669 *output_array_size = index;
6670 }
6671 *neighbor_ap_array = scan_array;
6672 pclose(f);
6673 free(channels_noise_arr);
6674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6675 return RETURN_OK;
developer86035662023-06-28 19:21:12 +08006676err:
6677 pclose(f);
6678 free(channels_noise_arr);
6679 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6680 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006681}
6682
6683//>> Deprecated: used for old RDKB code.
6684INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
6685{
developera3511852023-06-14 14:12:59 +08006686 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006687
developera3511852023-06-14 14:12:59 +08006688 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6689 output_struct->wifi_PLCPErrorCount = 0;
6690 output_struct->wifi_FCSErrorCount = 0;
6691 output_struct->wifi_InvalidMACCount = 0;
6692 output_struct->wifi_PacketsOtherReceived = 0;
6693 output_struct->wifi_Noise = 0;
6694 status = RETURN_OK;
6695 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6696 return status;
developer72fb0bb2023-01-11 09:46:29 +08006697}
6698
6699INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
6700{
developera3511852023-06-14 14:12:59 +08006701 char interface_name[16] = {0};
6702 char cmd[128] = {0};
6703 char buf[1280] = {0};
6704 char *pos = NULL;
developere40952c2023-06-15 18:46:43 +08006705 int res;
developer72fb0bb2023-01-11 09:46:29 +08006706
developera3511852023-06-14 14:12:59 +08006707 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6708 if (NULL == output_struct)
6709 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006710
developera3511852023-06-14 14:12:59 +08006711 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6712 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006713
developera3511852023-06-14 14:12:59 +08006714 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08006715
developere40952c2023-06-15 18:46:43 +08006716 res = snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
6717 if (os_snprintf_error(sizeof(cmd), res)) {
6718 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6719 return RETURN_ERR;
6720 }
6721
developera3511852023-06-14 14:12:59 +08006722 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006723
developera3511852023-06-14 14:12:59 +08006724 pos = buf;
6725 if ((pos = strstr(pos, "RX packets:")) == NULL)
6726 return RETURN_ERR;
6727 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08006728
developera3511852023-06-14 14:12:59 +08006729 if ((pos = strstr(pos, "TX packets:")) == NULL)
6730 return RETURN_ERR;
6731 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08006732
developera3511852023-06-14 14:12:59 +08006733 if ((pos = strstr(pos, "RX bytes:")) == NULL)
6734 return RETURN_ERR;
6735 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08006736
developera3511852023-06-14 14:12:59 +08006737 if ((pos = strstr(pos, "TX bytes:")) == NULL)
6738 return RETURN_ERR;
6739 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08006740
developera3511852023-06-14 14:12:59 +08006741 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
6742 _syscmd(cmd, buf, sizeof(buf));
6743 sscanf(buf, "%lu", &output_struct->wifi_Associations);
developer72fb0bb2023-01-11 09:46:29 +08006744
developera3511852023-06-14 14:12:59 +08006745 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6746 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006747}
6748
6749INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
6750{
developera3511852023-06-14 14:12:59 +08006751 char interface_name[IF_NAME_SIZE] = {0};
6752 char interface_status[MAX_BUF_SIZE] = {0};
6753 char Value[MAX_BUF_SIZE] = {0};
6754 char buf[MAX_CMD_SIZE] = {0};
6755 char cmd[MAX_CMD_SIZE] = {0};
6756 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08006757 int res;
developer72fb0bb2023-01-11 09:46:29 +08006758
developera3511852023-06-14 14:12:59 +08006759 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6760 if (NULL == output_struct)
6761 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006762
developera3511852023-06-14 14:12:59 +08006763 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08006764
developera3511852023-06-14 14:12:59 +08006765 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
6766 return RETURN_ERR;
6767 GetIfacestatus(interface_name, interface_status);
developer72fb0bb2023-01-11 09:46:29 +08006768
developera3511852023-06-14 14:12:59 +08006769 if(0 != strcmp(interface_status, "1"))
6770 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006771
6772 res = snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
6773 if (os_snprintf_error(sizeof(cmd), res)) {
6774 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6775 return RETURN_ERR;
6776 }
developer72fb0bb2023-01-11 09:46:29 +08006777
developera3511852023-06-14 14:12:59 +08006778 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +08006779
developera3511852023-06-14 14:12:59 +08006780 fp = fopen("/tmp/SSID_Stats.txt", "r");
6781 if(fp == NULL)
6782 {
6783 printf("/tmp/SSID_Stats.txt not exists \n");
6784 return RETURN_ERR;
6785 }
6786 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +08006787
developera3511852023-06-14 14:12:59 +08006788 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6789 File_Reading(buf, Value);
6790 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08006791
developera3511852023-06-14 14:12:59 +08006792 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6793 File_Reading(buf, Value);
6794 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08006795
developera3511852023-06-14 14:12:59 +08006796 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
6797 File_Reading(buf, Value);
6798 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08006799
developera3511852023-06-14 14:12:59 +08006800 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
6801 File_Reading(buf, Value);
6802 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08006803
developera3511852023-06-14 14:12:59 +08006804 output_struct->wifi_UnicastPacketsSent = 0;
6805 output_struct->wifi_UnicastPacketsReceived = 0;
6806 output_struct->wifi_MulticastPacketsSent = 0;
6807 output_struct->wifi_MulticastPacketsReceived = 0;
6808 output_struct->wifi_BroadcastPacketsSent = 0;
6809 output_struct->wifi_BroadcastPacketsRecevied = 0;
6810 output_struct->wifi_UnknownPacketsReceived = 0;
developer72fb0bb2023-01-11 09:46:29 +08006811
developera3511852023-06-14 14:12:59 +08006812 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6813 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006814}
6815
6816INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
6817{
developera3511852023-06-14 14:12:59 +08006818 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006819
developera3511852023-06-14 14:12:59 +08006820 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6821 //Below values should get updated from hal
6822 output_struct->wifi_RetransCount=0;
6823 output_struct->wifi_FailedRetransCount=0;
6824 output_struct->wifi_RetryCount=0;
6825 output_struct->wifi_MultipleRetryCount=0;
6826 output_struct->wifi_ACKFailureCount=0;
6827 output_struct->wifi_AggregatedPacketCount=0;
developer72fb0bb2023-01-11 09:46:29 +08006828
developera3511852023-06-14 14:12:59 +08006829 status = RETURN_OK;
6830 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006831
developera3511852023-06-14 14:12:59 +08006832 return status;
developer72fb0bb2023-01-11 09:46:29 +08006833}
6834
6835INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
6836{
developera3511852023-06-14 14:12:59 +08006837 INT status = RETURN_ERR;
6838 UINT index;
6839 wifi_neighbor_ap_t *pt=NULL;
developer72fb0bb2023-01-11 09:46:29 +08006840
developera3511852023-06-14 14:12:59 +08006841 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6842 *output_array_size=2;
6843 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
6844 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
developer86035662023-06-28 19:21:12 +08006845 if (*neighbor_ap_array == NULL) {
6846 wifi_debug(DEBUG_ERROR, "calloc fail!\n");
6847 return RETURN_ERR;
6848 }
developera3511852023-06-14 14:12:59 +08006849 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
developer32f2a182023-06-27 19:50:41 +08006850 pt->ap_Radio[0] = '\0';
6851 pt->ap_SSID[0] = '\0';
6852 pt->ap_BSSID[0] = '\0';
6853 pt->ap_Mode[0] = '\0';
developera3511852023-06-14 14:12:59 +08006854 pt->ap_Channel=1;
6855 pt->ap_SignalStrength=0;
developer32f2a182023-06-27 19:50:41 +08006856 pt->ap_SecurityModeEnabled[0] = '\0';
6857 pt->ap_EncryptionMode[0] = '\0';
6858 pt->ap_OperatingFrequencyBand[0] = '\0';
6859 pt->ap_SupportedStandards[0] = '\0';
6860 pt->ap_OperatingStandards[0] = '\0';
6861 pt->ap_OperatingChannelBandwidth[0] = '\0';
6862 pt->ap_BasicDataTransferRates[0] = '\0';
6863 pt->ap_SupportedDataTransferRates[0] = '\0';
developera3511852023-06-14 14:12:59 +08006864 pt->ap_BeaconPeriod=1;
6865 pt->ap_Noise=0;
developera3511852023-06-14 14:12:59 +08006866 pt->ap_DTIMPeriod=1;
6867 pt->ap_ChannelUtilization = 1;
6868 }
developer72fb0bb2023-01-11 09:46:29 +08006869
developera3511852023-06-14 14:12:59 +08006870 status = RETURN_OK;
6871 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006872
developera3511852023-06-14 14:12:59 +08006873 return status;
developer72fb0bb2023-01-11 09:46:29 +08006874}
6875
6876//----------------- AP HAL -------------------------------
6877
6878//>> Deprecated: used for old RDKB code.
6879INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
6880{
developera3511852023-06-14 14:12:59 +08006881 if (NULL == output_ulong || NULL == output_struct)
6882 return RETURN_ERR;
6883 *output_ulong = 0;
6884 *output_struct = NULL;
6885 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006886}
6887
6888#ifdef HAL_NETLINK_IMPL
6889static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +08006890 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6891 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6892 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
6893 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
6894 char mac_addr[20];
6895 static int count=0;
6896 int rate=0;
developer72fb0bb2023-01-11 09:46:29 +08006897
developera3511852023-06-14 14:12:59 +08006898 wifi_device_info_t *out = (wifi_device_info_t*)arg;
developer72fb0bb2023-01-11 09:46:29 +08006899
developera3511852023-06-14 14:12:59 +08006900 nla_parse(tb,
6901 NL80211_ATTR_MAX,
6902 genlmsg_attrdata(gnlh, 0),
6903 genlmsg_attrlen(gnlh, 0),
6904 NULL);
developer72fb0bb2023-01-11 09:46:29 +08006905
developera3511852023-06-14 14:12:59 +08006906 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +08006907 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +08006908 return NL_SKIP;
6909 }
developer72fb0bb2023-01-11 09:46:29 +08006910
6911
developera3511852023-06-14 14:12:59 +08006912 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +08006913 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +08006914 return NL_SKIP;
6915 }
developer72fb0bb2023-01-11 09:46:29 +08006916
developera3511852023-06-14 14:12:59 +08006917 //devIndex starts from 1
6918 if( ++count == out->wifi_devIndex )
6919 {
6920 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
6921 //Getting the mac addrress
6922 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
developer72fb0bb2023-01-11 09:46:29 +08006923
developera3511852023-06-14 14:12:59 +08006924 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +08006925 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +08006926 return NL_SKIP;
6927 }
developer72fb0bb2023-01-11 09:46:29 +08006928
developera3511852023-06-14 14:12:59 +08006929 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
6930 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
6931 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
6932 out->wifi_devTxRate = rate/10;
6933 }
6934 }
developer72fb0bb2023-01-11 09:46:29 +08006935
developera3511852023-06-14 14:12:59 +08006936 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +08006937 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +08006938 return NL_SKIP;
6939 }
developer72fb0bb2023-01-11 09:46:29 +08006940
developera3511852023-06-14 14:12:59 +08006941 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
6942 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
6943 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
6944 out->wifi_devRxRate = rate/10;
6945 }
6946 }
6947 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
6948 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
developer72fb0bb2023-01-11 09:46:29 +08006949
developera3511852023-06-14 14:12:59 +08006950 out->wifi_devAssociatedDeviceAuthentiationState = 1;
6951 count = 0; //starts the count for next cycle
6952 return NL_STOP;
6953 }
developer72fb0bb2023-01-11 09:46:29 +08006954
developera3511852023-06-14 14:12:59 +08006955 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08006956
6957}
6958#endif
6959
6960INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
6961{
developera3511852023-06-14 14:12:59 +08006962 Netlink nl = {0};
6963 char if_name[IF_NAME_SIZE] = {0};
6964 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08006965 int res;
developer72fb0bb2023-01-11 09:46:29 +08006966
developera3511852023-06-14 14:12:59 +08006967 wifi_device_info_t info = {0};
6968 info.wifi_devIndex = devIndex;
developer72fb0bb2023-01-11 09:46:29 +08006969
developera3511852023-06-14 14:12:59 +08006970 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6971 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006972
developere40952c2023-06-15 18:46:43 +08006973 res = snprintf(if_name,sizeof(if_name),"%s", interface_name);
6974 if (os_snprintf_error(sizeof(if_name), res)) {
6975 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6976 return RETURN_ERR;
6977 }
developer72fb0bb2023-01-11 09:46:29 +08006978
developera3511852023-06-14 14:12:59 +08006979 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +08006980
developera3511852023-06-14 14:12:59 +08006981 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +08006982 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +08006983 return -1;
6984 }
developer72fb0bb2023-01-11 09:46:29 +08006985
developera3511852023-06-14 14:12:59 +08006986 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +08006987
developera3511852023-06-14 14:12:59 +08006988 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +08006989 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +08006990 nlfree(&nl);
6991 return -2;
6992 }
developer72fb0bb2023-01-11 09:46:29 +08006993
developera3511852023-06-14 14:12:59 +08006994 genlmsg_put(msg,
6995 NL_AUTO_PID,
6996 NL_AUTO_SEQ,
6997 nl.id,
6998 0,
6999 NLM_F_DUMP,
7000 NL80211_CMD_GET_STATION,
7001 0);
developer72fb0bb2023-01-11 09:46:29 +08007002
developera3511852023-06-14 14:12:59 +08007003 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
7004 nl_send_auto_complete(nl.socket, msg);
7005 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
7006 nl_recvmsgs(nl.socket, nl.cb);
7007 nlmsg_free(msg);
7008 nlfree(&nl);
developer72fb0bb2023-01-11 09:46:29 +08007009
developera3511852023-06-14 14:12:59 +08007010 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
7011 output_struct->wifi_devRxRate = info.wifi_devRxRate;
7012 output_struct->wifi_devTxRate = info.wifi_devTxRate;
7013 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
7014 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
7015 return RETURN_OK;
7016}
developer72fb0bb2023-01-11 09:46:29 +08007017
developera3511852023-06-14 14:12:59 +08007018INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
7019{
7020 if (NULL == device)
7021 return RETURN_ERR;
7022 return RETURN_OK;
7023}
7024//<<
developer72fb0bb2023-01-11 09:46:29 +08007025
developer72fb0bb2023-01-11 09:46:29 +08007026
7027//--------------wifi_ap_hal-----------------------------
7028//enables CTS protection for the radio used by this AP
7029INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
7030{
developera3511852023-06-14 14:12:59 +08007031 //save config and Apply instantly
7032 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007033}
7034
7035// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
7036INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
7037{
developera3511852023-06-14 14:12:59 +08007038 char config_file[64] = {'\0'};
7039 char config_dat_file[64] = {'\0'};
7040 char buf[64] = {'\0'};
7041 struct params list = {0};
7042 struct params dat = {0};
7043 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007044 int res;
developer72fb0bb2023-01-11 09:46:29 +08007045
developera3511852023-06-14 14:12:59 +08007046 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7047 list.name = "ht_coex";
developere40952c2023-06-15 18:46:43 +08007048 res = snprintf(buf, sizeof(buf), "%d", enable);
7049 if (os_snprintf_error(sizeof(buf), res)) {
7050 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7051 return RETURN_ERR;
7052 }
7053
developera3511852023-06-14 14:12:59 +08007054 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007055
developera3511852023-06-14 14:12:59 +08007056 dat.name = "HT_BSSCoexistence";
7057 dat.value = buf;
developerd1824452023-05-18 12:30:04 +08007058
developera3511852023-06-14 14:12:59 +08007059 band = wifi_index_to_band(apIndex);
developere40952c2023-06-15 18:46:43 +08007060 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7061 if (os_snprintf_error(sizeof(config_file), res)) {
7062 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7063 return RETURN_ERR;
7064 }
7065
7066 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7067 if (os_snprintf_error(sizeof(config_dat_file), res)) {
7068 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7069 return RETURN_ERR;
7070 }
7071
developera3511852023-06-14 14:12:59 +08007072 wifi_hostapdWrite(config_file, &list, 1);
7073 wifi_datfileWrite(config_dat_file, &dat, 1);
7074 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08007075
developera3511852023-06-14 14:12:59 +08007076 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007077
developera3511852023-06-14 14:12:59 +08007078 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007079}
7080
7081//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
7082INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
7083{
developera3511852023-06-14 14:12:59 +08007084 char config_file[MAX_BUF_SIZE] = {'\0'};
7085 char buf[MAX_BUF_SIZE] = {'\0'};
7086 struct params list;
developere40952c2023-06-15 18:46:43 +08007087 int res;
developer72fb0bb2023-01-11 09:46:29 +08007088
developera3511852023-06-14 14:12:59 +08007089 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7090 if (threshold < 256 || threshold > 2346 )
7091 return RETURN_ERR;
7092 list.name = "fragm_threshold";
developere40952c2023-06-15 18:46:43 +08007093 res = snprintf(buf, sizeof(buf), "%d", threshold);
7094 if (os_snprintf_error(sizeof(buf), res)) {
7095 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7096 return RETURN_ERR;
7097 }
7098
developera3511852023-06-14 14:12:59 +08007099 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007100
developere40952c2023-06-15 18:46:43 +08007101 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7102 if (os_snprintf_error(sizeof(config_file), res)) {
7103 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7104 return RETURN_ERR;
7105 }
7106
developera3511852023-06-14 14:12:59 +08007107 wifi_hostapdWrite(config_file, &list, 1);
7108 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08007109
developera3511852023-06-14 14:12:59 +08007110 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007111
developera3511852023-06-14 14:12:59 +08007112 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007113}
7114
7115// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
7116INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
7117{
developera3511852023-06-14 14:12:59 +08007118 char config_file[64] = {'\0'};
7119 char cmd[512] = {'\0'};
7120 char buf[512] = {'\0'};
7121 char stbc_config[16] = {'\0'};
7122 wifi_band band;
7123 int iterator = 0;
7124 BOOL current_stbc = FALSE;
7125 int ant_count = 0;
7126 int ant_bitmap = 0;
7127 struct params list;
7128 char dat_file[64] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007129 int res;
developer72fb0bb2023-01-11 09:46:29 +08007130
developera3511852023-06-14 14:12:59 +08007131 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007132
developera3511852023-06-14 14:12:59 +08007133 band = wifi_index_to_band(radioIndex);
7134 if (band == band_invalid)
7135 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007136
developera3511852023-06-14 14:12:59 +08007137 if (band == band_2_4)
7138 iterator = 1;
7139 else if ((band == band_5) || (band == band_6))
7140 iterator = 2;
7141 else
7142 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007143
developera3511852023-06-14 14:12:59 +08007144 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
7145 for (; ant_bitmap > 0; ant_bitmap >>= 1)
7146 ant_count += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08007147
developera3511852023-06-14 14:12:59 +08007148 if (ant_count == 1 && STBC_Enable == TRUE) {
developer75bd10c2023-06-27 11:34:08 +08007149 wifi_debug(DEBUG_ERROR, "can not enable STBC when using only one antenna\n");
developera3511852023-06-14 14:12:59 +08007150 return RETURN_OK;
7151 }
developer72fb0bb2023-01-11 09:46:29 +08007152
developere40952c2023-06-15 18:46:43 +08007153 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
7154 if (os_snprintf_error(sizeof(config_file), res)) {
7155 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7156 return RETURN_ERR;
7157 }
developer72fb0bb2023-01-11 09:46:29 +08007158
developera3511852023-06-14 14:12:59 +08007159 // set ht and vht config
7160 for (int i = 0; i < iterator; i++) {
7161 memset(stbc_config, 0, sizeof(stbc_config));
7162 memset(cmd, 0, sizeof(cmd));
7163 memset(buf, 0, sizeof(buf));
7164 list.name = (i == 0)?"ht_capab":"vht_capab";
developere40952c2023-06-15 18:46:43 +08007165 res = snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
7166 if (os_snprintf_error(sizeof(stbc_config), res)) {
7167 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7168 return RETURN_ERR;
7169 }
7170
7171 res = snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
7172 if (os_snprintf_error(sizeof(cmd), res)) {
7173 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7174 return RETURN_ERR;
7175 }
7176
developera3511852023-06-14 14:12:59 +08007177 _syscmd(cmd, buf, sizeof(buf));
7178 if (strlen(buf) != 0)
7179 current_stbc = TRUE;
7180 if (current_stbc == STBC_Enable)
7181 continue;
developer72fb0bb2023-01-11 09:46:29 +08007182
developera3511852023-06-14 14:12:59 +08007183 if (STBC_Enable == TRUE) {
7184 // Append the STBC flags in capab config
7185 memset(cmd, 0, sizeof(cmd));
7186 if (i == 0)
developere40952c2023-06-15 18:46:43 +08007187 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
developera3511852023-06-14 14:12:59 +08007188 else
developere40952c2023-06-15 18:46:43 +08007189 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
7190 if (os_snprintf_error(sizeof(cmd), res)) {
7191 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7192 return RETURN_ERR;
7193 }
7194
developera3511852023-06-14 14:12:59 +08007195 _syscmd(cmd, buf, sizeof(buf));
7196 } else if (STBC_Enable == FALSE) {
7197 // Remove the STBC flags and remain other flags in capab
7198 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08007199 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
7200 if (os_snprintf_error(sizeof(cmd), res)) {
7201 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7202 return RETURN_ERR;
7203 }
7204
developera3511852023-06-14 14:12:59 +08007205 _syscmd(cmd, buf, sizeof(buf));
7206 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08007207 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
7208 if (os_snprintf_error(sizeof(cmd), res)) {
7209 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7210 return RETURN_ERR;
7211 }
7212
developera3511852023-06-14 14:12:59 +08007213 _syscmd(cmd, buf, sizeof(buf));
7214 }
7215 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
7216 list.value = buf;
7217 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
7218 }
developere40952c2023-06-15 18:46:43 +08007219 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7220 if (os_snprintf_error(sizeof(dat_file), res)) {
7221 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7222 return RETURN_ERR;
7223 }
7224
7225 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
7226 if (os_snprintf_error(sizeof(cmd), res)) {
7227 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7228 return RETURN_ERR;
7229 }
7230
developera1255e42023-05-13 17:45:02 +08007231 _syscmd(cmd, buf, sizeof(buf));
7232 if ((band == band_5) || (band == band_6)) {
developere40952c2023-06-15 18:46:43 +08007233 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
7234 if (os_snprintf_error(sizeof(cmd), res)) {
7235 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7236 return RETURN_ERR;
7237 }
7238
developera1255e42023-05-13 17:45:02 +08007239 _syscmd(cmd, buf, sizeof(buf));
7240 }
developera3511852023-06-14 14:12:59 +08007241 /*wifi_reloadAp(radioIndex);
developera1255e42023-05-13 17:45:02 +08007242 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08007243
developera3511852023-06-14 14:12:59 +08007244 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7245 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007246}
7247
7248// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
7249INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
7250{
developera3511852023-06-14 14:12:59 +08007251 char dat_file[128] = {0};
developer2c22d832023-05-18 17:46:26 +08007252 wifi_band band;
7253 char amdus_buff[8] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007254 int res;
developer72fb0bb2023-01-11 09:46:29 +08007255
developer2c22d832023-05-18 17:46:26 +08007256 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007257
developer2c22d832023-05-18 17:46:26 +08007258 band = wifi_index_to_band(radioIndex);
7259 if (band == band_invalid) {
7260 printf("%s:Band Error\n", __func__);
7261 return RETURN_ERR;
7262 }
developere40952c2023-06-15 18:46:43 +08007263 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7264 if (os_snprintf_error(sizeof(dat_file), res)) {
7265 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7266 return RETURN_ERR;
7267 }
7268
developer2c22d832023-05-18 17:46:26 +08007269 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
7270 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08007271 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08007272 else
7273 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08007274
developer2c22d832023-05-18 17:46:26 +08007275 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7276
7277 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007278}
7279
7280// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
7281INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
7282{
developer2c22d832023-05-18 17:46:26 +08007283 char dat_file[128] = {0};
7284 BOOL enable;
7285 wifi_band band;
7286 char amdus_buff[8] = {'\0'};
7287 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08007288 int res;
developer72fb0bb2023-01-11 09:46:29 +08007289
developer2c22d832023-05-18 17:46:26 +08007290 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007291
developer2c22d832023-05-18 17:46:26 +08007292 band = wifi_index_to_band(radioIndex);
7293 if (band == band_invalid) {
7294 printf("%s:Band Error\n", __func__);
7295 return RETURN_ERR;
7296 }
developere40952c2023-06-15 18:46:43 +08007297 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7298 if (os_snprintf_error(sizeof(dat_file), res)) {
7299 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7300 return RETURN_ERR;
7301 }
7302
developer2c22d832023-05-18 17:46:26 +08007303 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
7304 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08007305 enable = TRUE;
developer2c22d832023-05-18 17:46:26 +08007306 else
7307 enable = FALSE;
7308 if (amsduEnable == enable)
developera3511852023-06-14 14:12:59 +08007309 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007310
developer2c22d832023-05-18 17:46:26 +08007311 params.name = "HT_AMSDU";
7312 if (amsduEnable)
7313 params.value = "1";
7314 else
7315 params.value = "0";
7316 wifi_datfileWrite(dat_file, &params, 1);
7317 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08007318
developer2c22d832023-05-18 17:46:26 +08007319 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007320
developera3511852023-06-14 14:12:59 +08007321 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007322}
7323
7324//P2 // outputs the number of Tx streams
7325INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
7326{
developera3511852023-06-14 14:12:59 +08007327 char buf[8] = {0};
7328 char cmd[128] = {0};
7329 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08007330 int res;
developer72fb0bb2023-01-11 09:46:29 +08007331
developera3511852023-06-14 14:12:59 +08007332 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007333
developera3511852023-06-14 14:12:59 +08007334 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08007335 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
7336 if (os_snprintf_error(sizeof(cmd), res)) {
7337 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7338 return RETURN_ERR;
7339 }
7340
developera3511852023-06-14 14:12:59 +08007341 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007342
developera3511852023-06-14 14:12:59 +08007343 *output_int = (INT)strtol(buf, NULL, 16);
developer72fb0bb2023-01-11 09:46:29 +08007344
developera3511852023-06-14 14:12:59 +08007345 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007346
developera3511852023-06-14 14:12:59 +08007347 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007348}
7349
7350INT fitChainMask(INT radioIndex, int antcount)
7351{
developera3511852023-06-14 14:12:59 +08007352 char buf[128] = {0};
7353 char cmd[128] = {0};
7354 char config_file[64] = {0};
7355 wifi_band band;
7356 struct params list[2] = {0};
developere40952c2023-06-15 18:46:43 +08007357 int res;
developer72fb0bb2023-01-11 09:46:29 +08007358
developera3511852023-06-14 14:12:59 +08007359 band = wifi_index_to_band(radioIndex);
7360 if (band == band_invalid)
7361 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007362
developera3511852023-06-14 14:12:59 +08007363 list[0].name = "he_mu_beamformer";
7364 list[1].name = "he_su_beamformer";
developer72fb0bb2023-01-11 09:46:29 +08007365
developere40952c2023-06-15 18:46:43 +08007366 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
7367 if (os_snprintf_error(sizeof(config_file), res)) {
7368 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7369 return RETURN_ERR;
7370 }
7371
developera3511852023-06-14 14:12:59 +08007372 if (antcount == 1) {
7373 // remove config about multiple antennas
developere40952c2023-06-15 18:46:43 +08007374 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
7375 if (os_snprintf_error(sizeof(cmd), res)) {
7376 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7377 return RETURN_ERR;
7378 }
7379
developera3511852023-06-14 14:12:59 +08007380 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007381
developere40952c2023-06-15 18:46:43 +08007382 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
7383 if (os_snprintf_error(sizeof(cmd), res)) {
7384 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7385 return RETURN_ERR;
7386 }
7387
developera3511852023-06-14 14:12:59 +08007388 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007389
developere40952c2023-06-15 18:46:43 +08007390 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
7391 if (os_snprintf_error(sizeof(cmd), res)) {
7392 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7393 return RETURN_ERR;
7394 }
7395
developera3511852023-06-14 14:12:59 +08007396 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007397
developere40952c2023-06-15 18:46:43 +08007398 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
7399 if (os_snprintf_error(sizeof(cmd), res)) {
7400 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7401 return RETURN_ERR;
7402 }
7403
developera3511852023-06-14 14:12:59 +08007404 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007405
developera3511852023-06-14 14:12:59 +08007406 list[0].value = "0";
7407 list[1].value = "0";
7408 } else {
7409 // 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.
7410 if (band == band_2_4 || band == band_5) {
developere40952c2023-06-15 18:46:43 +08007411 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
7412 if (os_snprintf_error(sizeof(cmd), res)) {
7413 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7414 return RETURN_ERR;
7415 }
7416
developera3511852023-06-14 14:12:59 +08007417 _syscmd(cmd, buf, sizeof(buf));
7418 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08007419 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
7420 if (os_snprintf_error(sizeof(cmd), res)) {
7421 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7422 return RETURN_ERR;
7423 }
7424
developera3511852023-06-14 14:12:59 +08007425 _syscmd(cmd, buf, sizeof(buf));
7426 }
7427 }
7428 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08007429 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
7430 if (os_snprintf_error(sizeof(cmd), res)) {
7431 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7432 return RETURN_ERR;
7433 }
7434
developera3511852023-06-14 14:12:59 +08007435 _syscmd(cmd, buf, sizeof(buf));
7436 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08007437 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
7438 if (os_snprintf_error(sizeof(cmd), res)) {
7439 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7440 return RETURN_ERR;
7441 }
7442
developera3511852023-06-14 14:12:59 +08007443 _syscmd(cmd, buf, sizeof(buf));
7444 }
7445 }
developer72fb0bb2023-01-11 09:46:29 +08007446
developere40952c2023-06-15 18:46:43 +08007447 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
7448 if (os_snprintf_error(sizeof(cmd), res)) {
7449 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7450 return RETURN_ERR;
7451 }
7452
developera3511852023-06-14 14:12:59 +08007453 _syscmd(cmd, buf, sizeof(buf));
7454 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007455 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
7456 if (os_snprintf_error(sizeof(cmd), res)) {
7457 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7458 return RETURN_ERR;
7459 }
7460
developera3511852023-06-14 14:12:59 +08007461 _syscmd(cmd, buf, sizeof(buf));
7462 }
developer72fb0bb2023-01-11 09:46:29 +08007463
developere40952c2023-06-15 18:46:43 +08007464 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
developera3511852023-06-14 14:12:59 +08007465 _syscmd(cmd, buf, sizeof(buf));
7466 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007467 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
7468 if (os_snprintf_error(sizeof(cmd), res)) {
7469 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7470 return RETURN_ERR;
7471 }
7472
developera3511852023-06-14 14:12:59 +08007473 _syscmd(cmd, buf, sizeof(buf));
7474 }
developer72fb0bb2023-01-11 09:46:29 +08007475
developere40952c2023-06-15 18:46:43 +08007476 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
7477 if (os_snprintf_error(sizeof(cmd), res)) {
7478 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7479 return RETURN_ERR;
7480 }
7481
developera3511852023-06-14 14:12:59 +08007482 _syscmd(cmd, buf, sizeof(buf));
7483 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007484 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
developera3511852023-06-14 14:12:59 +08007485 } else {
developere40952c2023-06-15 18:46:43 +08007486 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
7487 }
7488 if (os_snprintf_error(sizeof(cmd), res)) {
7489 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7490 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08007491 }
developere40952c2023-06-15 18:46:43 +08007492
developera3511852023-06-14 14:12:59 +08007493 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007494
developera3511852023-06-14 14:12:59 +08007495 list[0].value = "1";
7496 list[1].value = "1";
7497 }
7498 wifi_hostapdWrite(config_file, list, 2);
developerdaf24792023-06-06 11:40:04 +08007499 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007500}
7501
7502//P2 // sets the number of Tx streams to an enviornment variable
7503INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
7504{
developera3511852023-06-14 14:12:59 +08007505 char cmd[128] = {0};
7506 char buf[128] = {0};
7507 int phyId = 0;
7508 int cur_mask = 0;
7509 int antcountmsk = 0;
developera1255e42023-05-13 17:45:02 +08007510 INT cur_nss = 0;
developer863a4a62023-06-06 16:55:59 +08007511 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +08007512 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007513 int res;
developer72fb0bb2023-01-11 09:46:29 +08007514
developera3511852023-06-14 14:12:59 +08007515 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007516
developera3511852023-06-14 14:12:59 +08007517 if (numStreams <= 0) {
developer75bd10c2023-06-27 11:34:08 +08007518 wifi_debug(DEBUG_ERROR, "chainmask is not supported %d.\n", numStreams);
developera3511852023-06-14 14:12:59 +08007519 return RETURN_ERR;
7520 }
developer72fb0bb2023-01-11 09:46:29 +08007521
developera3511852023-06-14 14:12:59 +08007522 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
developera1255e42023-05-13 17:45:02 +08007523 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
7524 cur_nss += 1;
7525 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
developera3511852023-06-14 14:12:59 +08007526 if (cur_nss == numStreams)
7527 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007528
developera3511852023-06-14 14:12:59 +08007529 wifi_setRadioEnable(radioIndex, FALSE);
developer72fb0bb2023-01-11 09:46:29 +08007530
developera3511852023-06-14 14:12:59 +08007531 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08007532 //iw need mask value.
7533 for (;numStreams > 0; numStreams--)
7534 antcountmsk |= 0x1 << (numStreams - 1);
developere40952c2023-06-15 18:46:43 +08007535 res = snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
7536 if (os_snprintf_error(sizeof(cmd), res)) {
7537 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7538 return RETURN_ERR;
7539 }
developerb758dfd2023-06-21 17:32:07 +08007540
developera3511852023-06-14 14:12:59 +08007541 _syscmd(cmd, buf, sizeof(buf));
7542 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007543 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007544 return RETURN_ERR;
7545 }
7546 band = wifi_index_to_band(radioIndex);
developera1255e42023-05-13 17:45:02 +08007547 if (band == band_invalid) {
7548 printf("%s:Band Error\n", __func__);
7549 return RETURN_ERR;
7550 }
developere40952c2023-06-15 18:46:43 +08007551 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7552 if (os_snprintf_error(sizeof(dat_file), res)) {
7553 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7554 return RETURN_ERR;
7555 }
developerb758dfd2023-06-21 17:32:07 +08007556
developere40952c2023-06-15 18:46:43 +08007557 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
7558 if (os_snprintf_error(sizeof(cmd), res)) {
7559 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7560 return RETURN_ERR;
7561 }
developerb758dfd2023-06-21 17:32:07 +08007562
developera1255e42023-05-13 17:45:02 +08007563 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08007564 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007565 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007566 return RETURN_ERR;
7567 }
developere40952c2023-06-15 18:46:43 +08007568 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
7569 if (os_snprintf_error(sizeof(cmd), res)) {
7570 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7571 return RETURN_ERR;
7572 }
developerb758dfd2023-06-21 17:32:07 +08007573
developera1255e42023-05-13 17:45:02 +08007574 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08007575 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007576 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007577 return RETURN_ERR;
7578 }
7579 fitChainMask(radioIndex, numStreams);
7580 wifi_setRadioEnable(radioIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +08007581
developera3511852023-06-14 14:12:59 +08007582 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7583 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007584}
7585
7586//P2 // outputs the number of Rx streams
7587INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
7588{
developera3511852023-06-14 14:12:59 +08007589 char buf[8] = {0};
7590 char cmd[128] = {0};
7591 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +08007592 int res;
developer72fb0bb2023-01-11 09:46:29 +08007593
developera3511852023-06-14 14:12:59 +08007594 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007595
developera3511852023-06-14 14:12:59 +08007596 phyId = radio_index_to_phy(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08007597
7598 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
7599 if (os_snprintf_error(sizeof(cmd), res)) {
7600 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7601 return RETURN_ERR;
7602 }
developera3511852023-06-14 14:12:59 +08007603 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007604
developera3511852023-06-14 14:12:59 +08007605 *output_int = (INT)strtol(buf, NULL, 16);
developer72fb0bb2023-01-11 09:46:29 +08007606
developera3511852023-06-14 14:12:59 +08007607 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007608
developera3511852023-06-14 14:12:59 +08007609 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007610}
7611
7612//P2 // sets the number of Rx streams to an enviornment variable
7613INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
7614{
developera3511852023-06-14 14:12:59 +08007615 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7616 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08007617 wifi_debug(DEBUG_ERROR, "wifi_setRadioTxChainMask return error.\n");
developera3511852023-06-14 14:12:59 +08007618 return RETURN_ERR;
7619 }
7620 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7621 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007622}
7623
7624//Get radio RDG enable setting
7625INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
7626{
developer47cc27a2023-05-17 23:09:58 +08007627 if (NULL == output_bool)
7628 return RETURN_ERR;
7629
7630 *output_bool = TRUE;
7631 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007632}
7633
7634//Get radio RDG enable setting
7635INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
7636{
developer47cc27a2023-05-17 23:09:58 +08007637 char rdg_status[2] = {0};
7638 char dat_file[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08007639 int res;
developer47cc27a2023-05-17 23:09:58 +08007640
7641 if (NULL == output_bool)
7642 return RETURN_ERR;
7643
7644 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08007645 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7646 if (os_snprintf_error(sizeof(dat_file), res)) {
7647 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7648 return RETURN_ERR;
7649 }
developer47cc27a2023-05-17 23:09:58 +08007650
7651 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
7652 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
7653 *output_bool = TRUE;
7654 else
7655 *output_bool = FALSE;
7656
7657 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007658}
7659
7660//Set radio RDG enable setting
7661INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
7662{
developer47cc27a2023-05-17 23:09:58 +08007663 char dat_file[MAX_CMD_SIZE] = {0};
7664 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08007665 int res;
developer47cc27a2023-05-17 23:09:58 +08007666
7667 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08007668 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7669 if (os_snprintf_error(sizeof(dat_file), res)) {
7670 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7671 return RETURN_ERR;
7672 }
developer47cc27a2023-05-17 23:09:58 +08007673
7674 params.name = "HT_RDG";
7675
developera3511852023-06-14 14:12:59 +08007676 if (enable) {
7677 params.value = "1";
7678 } else {
7679 params.value = "0";
7680 }
developer47cc27a2023-05-17 23:09:58 +08007681
7682 wifi_datfileWrite(dat_file, &params, 1);
7683
7684 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007685}
7686
developer5cd4c862023-05-26 09:34:42 +08007687
7688int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08007689{
developer5cd4c862023-05-26 09:34:42 +08007690 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7691 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
7692 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7693 unsigned char status;
7694 unsigned char *out_status = data;
7695 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08007696
developer5cd4c862023-05-26 09:34:42 +08007697 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7698 genlmsg_attrlen(gnlh, 0), NULL);
7699 if (err < 0){
7700 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7701 return err;
7702 }
developer8e6583c2023-05-23 13:36:06 +08007703
developer5cd4c862023-05-26 09:34:42 +08007704 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7705 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
7706 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7707 if (err < 0){
7708 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
7709 return err;
7710 }
developer8e6583c2023-05-23 13:36:06 +08007711
developer5cd4c862023-05-26 09:34:42 +08007712 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
7713 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
7714 if (status == 0) {
7715 wifi_debug(DEBUG_NOTICE, "disabled\n");
7716 } else {
7717 wifi_debug(DEBUG_NOTICE, "enabled\n");
7718 }
7719 *out_status = status;
7720 }
7721 }
developer8e6583c2023-05-23 13:36:06 +08007722
developer5cd4c862023-05-26 09:34:42 +08007723 return 0;
7724}
developer8e6583c2023-05-23 13:36:06 +08007725
developer5cd4c862023-05-26 09:34:42 +08007726int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
7727{
7728 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7729 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
7730 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7731 unsigned char status;
7732 unsigned char *out_status = data;
7733 int err = 0;
7734
7735 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7736 genlmsg_attrlen(gnlh, 0), NULL);
7737 if (err < 0) {
7738 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7739 return err;
7740 }
7741
7742 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7743 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
7744 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7745 if (err < 0) {
7746 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
7747 return err;
7748 }
7749
7750 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
7751 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
7752 if (status == 0) {
7753 wifi_debug(DEBUG_NOTICE, "disabled\n");
7754 } else {
7755 wifi_debug(DEBUG_NOTICE, "enabled\n");
7756 }
7757 *out_status = status;
7758 }
7759 }
7760
7761 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08007762}
7763
developer5cd4c862023-05-26 09:34:42 +08007764INT mtk_wifi_get_ba_decl_auto_status(
7765 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
7766{
7767 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08007768 unsigned int if_idx = 0;
7769 int ret = -1;
7770 struct unl unl_ins;
7771 struct nl_msg *msg = NULL;
7772 struct nlattr * msg_data = NULL;
7773 struct mtk_nl80211_param param;
7774
7775 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7776 return RETURN_ERR;
7777 if_idx = if_nametoindex(inf_name);
7778 if (!if_idx) {
7779 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
7780 return RETURN_ERR;
7781 }
7782 /*init mtk nl80211 vendor cmd*/
7783 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
7784 param.if_type = NL80211_ATTR_IFINDEX;
7785 param.if_idx = if_idx;
7786
7787 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7788 if (ret) {
7789 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7790 return RETURN_ERR;
7791 }
7792 /*add mtk vendor cmd data*/
7793 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
7794 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
7795 nlmsg_free(msg);
7796 goto err;
7797 }
7798
7799 /*send mtk nl80211 vendor msg*/
7800 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
7801 if (ret) {
7802 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7803 goto err;
7804 }
7805 /*deinit mtk nl80211 vendor msg*/
7806 mtk_nl80211_deint(&unl_ins);
7807 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
7808 return RETURN_OK;
7809err:
7810 mtk_nl80211_deint(&unl_ins);
7811 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
7812 return RETURN_ERR;
7813}
developere0ff7232023-06-08 16:33:14 +08007814
7815INT mtk_wifi_set_auto_ba_en(
7816 INT apIndex, INT vendor_data_attr, BOOL enable)
7817{
7818 char inf_name[IF_NAME_SIZE] = {0};
7819 unsigned int if_idx = 0;
7820 int ret = -1;
7821 struct unl unl_ins;
7822 struct nl_msg *msg = NULL;
7823 struct nlattr * msg_data = NULL;
7824 struct mtk_nl80211_param param;
7825
7826 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7827 return RETURN_ERR;
7828 if_idx = if_nametoindex(inf_name);
7829 if (!if_idx) {
7830 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
7831 return RETURN_ERR;
7832 }
7833 /*init mtk nl80211 vendor cmd*/
7834 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
7835 param.if_type = NL80211_ATTR_IFINDEX;
7836 param.if_idx = if_idx;
7837
7838 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7839 if (ret) {
7840 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7841 return RETURN_ERR;
7842 }
7843 /*add mtk vendor cmd data*/
7844 if (nla_put_u8(msg, vendor_data_attr, enable)) {
7845 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
7846 nlmsg_free(msg);
7847 goto err;
7848 }
7849
7850 /*send mtk nl80211 vendor msg*/
7851 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7852 if (ret) {
7853 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7854 goto err;
7855 }
7856 /*deinit mtk nl80211 vendor msg*/
7857 mtk_nl80211_deint(&unl_ins);
7858 return RETURN_OK;
7859err:
7860 mtk_nl80211_deint(&unl_ins);
7861 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
7862 return RETURN_ERR;
7863}
7864
developer5cd4c862023-05-26 09:34:42 +08007865//Get radio ADDBA enable setting
7866INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
7867{
7868 if (output_bool == NULL) {
7869 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
7870 return RETURN_ERR;
7871 }
7872 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
7873 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
7874 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
7875 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
7876 return RETURN_ERR;
7877 }
7878 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
7879 return RETURN_OK;
7880}
7881
developer72fb0bb2023-01-11 09:46:29 +08007882//Set radio ADDBA enable setting
7883INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
7884{
developera3511852023-06-14 14:12:59 +08007885 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007886}
7887
7888//Get radio auto block ack enable setting
7889INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
7890{
developer5cd4c862023-05-26 09:34:42 +08007891 if (output_bool == NULL) {
7892 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
7893 return RETURN_ERR;
7894 }
developer8e6583c2023-05-23 13:36:06 +08007895
developera3511852023-06-14 14:12:59 +08007896 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
developer5cd4c862023-05-26 09:34:42 +08007897 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
7898 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
7899 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
7900 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
7901 return RETURN_ERR;
7902 }
7903 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
7904 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007905}
7906
7907//Set radio auto block ack enable setting
7908INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
7909{
developera3511852023-06-14 14:12:59 +08007910 if (mtk_wifi_set_auto_ba_en
developere0ff7232023-06-08 16:33:14 +08007911 (radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
7912 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
7913 return RETURN_ERR;
7914 }
7915 wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08007916 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007917}
7918
7919//Get radio 11n pure mode enable support
7920INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
7921{
developera3511852023-06-14 14:12:59 +08007922 if (NULL == output_bool)
7923 return RETURN_ERR;
7924 *output_bool = TRUE;
7925 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007926}
7927
7928//Get radio 11n pure mode enable setting
7929INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
7930{
developera3511852023-06-14 14:12:59 +08007931 if (NULL == output_bool)
7932 return RETURN_ERR;
7933 *output_bool = TRUE;
7934 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007935}
7936
7937//Set radio 11n pure mode enable setting
developer86035662023-06-28 19:21:12 +08007938INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
developer72fb0bb2023-01-11 09:46:29 +08007939{
developer82533be2023-06-28 17:21:01 +08007940//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)
7941 char interface_name[16] = {0};
7942 int if_idx, ret = 0;
7943 struct nl_msg *msg = NULL;
7944 struct nlattr * msg_data = NULL;
7945 struct mtk_nl80211_param param;
7946 struct unl unl_ins;
7947
7948 if (radioIndex > MAX_APS) {
7949 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", radioIndex);
7950 return RETURN_ERR;
7951 }
7952 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7953 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
7954 return RETURN_ERR;
7955 /*step 1. mwctl dev %s set vlan_tag 0*/
7956 if_idx = if_nametoindex(interface_name);
7957 /*init mtk nl80211 vendor cmd*/
7958 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
7959 param.if_type = NL80211_ATTR_IFINDEX;
7960 param.if_idx = if_idx;
7961 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7962 if (ret) {
7963 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7964 return RETURN_ERR;
7965 }
7966 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_HT_OP_MODE, enable)) {
7967 printf("Nla put attribute error\n");
7968 nlmsg_free(msg);
7969 goto err;
7970 }
7971 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7972 if (ret) {
7973 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7974 goto err;
7975 }
7976 mtk_nl80211_deint(&unl_ins);
7977 //wifi_debug(DEBUG_NOTICE, "set Gf cmd success.\n");
7978 printf("set gf=%d cmd success.\n", enable);
7979 return RETURN_OK;
7980err:
7981 mtk_nl80211_deint(&unl_ins);
7982 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08007983 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007984}
7985
developer5cd4c862023-05-26 09:34:42 +08007986int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08007987{
developer5cd4c862023-05-26 09:34:42 +08007988 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7989 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
7990 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7991 unsigned char status = 0, *out_status = data;
7992 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08007993
developer5cd4c862023-05-26 09:34:42 +08007994 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7995 genlmsg_attrlen(gnlh, 0), NULL);
7996 if (err < 0) {
7997 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7998 return err;
7999 }
developer72fb0bb2023-01-11 09:46:29 +08008000
developer5cd4c862023-05-26 09:34:42 +08008001 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8002 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
8003 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8004 if (err < 0){
8005 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
8006 return err;
8007 }
developer72fb0bb2023-01-11 09:46:29 +08008008
developer5cd4c862023-05-26 09:34:42 +08008009 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
8010 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
8011 if (status == 0) {
8012 wifi_debug(DEBUG_NOTICE, "disabled\n");
8013 } else {
8014 wifi_debug(DEBUG_NOTICE, "enabled\n");
8015 }
8016 *out_status = status;
8017 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
8018 }
8019 }
8020
8021 return 0;
8022}
8023
8024INT mtk_wifi_set_igmp_en_status(
8025 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
8026 unsigned char in_en_stat, BOOL *output_bool)
8027{
8028 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08008029 unsigned int if_idx = 0;
8030 int ret = -1;
8031 struct unl unl_ins;
8032 struct nl_msg *msg = NULL;
8033 struct nlattr * msg_data = NULL;
8034 struct mtk_nl80211_param param;
8035
8036 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8037 return RETURN_ERR;
8038 if_idx = if_nametoindex(inf_name);
8039 if (!if_idx) {
8040 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8041 return RETURN_ERR;
8042 }
8043 /*init mtk nl80211 vendor cmd*/
8044 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
8045 param.if_type = NL80211_ATTR_IFINDEX;
8046 param.if_idx = if_idx;
8047
8048 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8049 if (ret) {
8050 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8051 return RETURN_ERR;
8052 }
8053 /*add mtk vendor cmd data*/
8054 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
8055 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8056 nlmsg_free(msg);
8057 goto err;
8058 }
8059
8060 /*send mtk nl80211 vendor msg*/
8061 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
8062 if (ret) {
8063 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8064 goto err;
8065 }
8066 /*deinit mtk nl80211 vendor msg*/
8067 mtk_nl80211_deint(&unl_ins);
8068 if (output_bool) {
8069 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
8070 } else {
8071 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
8072 }
8073 return RETURN_OK;
8074err:
8075 mtk_nl80211_deint(&unl_ins);
8076 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8077 return RETURN_ERR;
8078}
8079
8080
8081//Get radio IGMP snooping enable setting
8082INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
8083{
8084 if (output_bool == NULL) {
8085 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8086 return RETURN_ERR;
8087 }
developera3511852023-06-14 14:12:59 +08008088 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08008089 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
8090 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
8091 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
8092 return RETURN_ERR;
8093 }
8094 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developera3511852023-06-14 14:12:59 +08008095 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008096}
8097
8098//Set radio IGMP snooping enable setting
8099INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
8100{
developera3511852023-06-14 14:12:59 +08008101 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08008102 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
8103 NULL, enable, NULL) != RETURN_OK) {
8104 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
8105 return RETURN_ERR;
8106 }
8107 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08008108 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008109}
8110
8111//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08008112INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08008113{
developera3511852023-06-14 14:12:59 +08008114 if (NULL == output_int)
8115 return RETURN_ERR;
8116 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08008117
developera3511852023-06-14 14:12:59 +08008118 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008119}
8120
8121
8122//---------------------------------------------------------------------------------------------------
8123//
8124// Additional Wifi AP level APIs used for Access Point devices
8125//
8126//---------------------------------------------------------------------------------------------------
8127
8128// creates a new ap and pushes these parameters to the hardware
8129INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
8130{
developera3511852023-06-14 14:12:59 +08008131 // Deprecated when use hal version 3, use wifi_createVap() instead.
8132 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008133}
8134
8135// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
8136INT wifi_deleteAp(INT apIndex)
8137{
developer7e4a2a62023-04-06 19:56:03 +08008138 char interface_name[16] = {0};
8139 char buf[MAX_BUF_SIZE];
8140 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08008141 int res;
developer72fb0bb2023-01-11 09:46:29 +08008142
developer7e4a2a62023-04-06 19:56:03 +08008143 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8144 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08008145
developere40952c2023-06-15 18:46:43 +08008146 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8147 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
8148 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8149 return RETURN_ERR;
8150 }
developer7e4a2a62023-04-06 19:56:03 +08008151 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008152
developer7e4a2a62023-04-06 19:56:03 +08008153 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008154
developer7e4a2a62023-04-06 19:56:03 +08008155 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008156}
8157
8158// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
8159INT wifi_getApName(INT apIndex, CHAR *output_string)
8160{
developer7e4a2a62023-04-06 19:56:03 +08008161 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008162 int radio_idx = 0;
8163 int bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08008164 int res;
developer72fb0bb2023-01-11 09:46:29 +08008165
developer7e4a2a62023-04-06 19:56:03 +08008166 if(!output_string)
8167 return RETURN_ERR;
8168
8169 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8170 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
8171
developere40952c2023-06-15 18:46:43 +08008172 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 +08008173 } else
developere40952c2023-06-15 18:46:43 +08008174 res = snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
8175
8176 if (os_snprintf_error(IF_NAME_SIZE, res)) {
8177 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8178 return RETURN_ERR;
8179 }
developer7e4a2a62023-04-06 19:56:03 +08008180
8181 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008182}
8183
8184// Outputs the index number in that corresponds to the SSID string
8185INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
8186{
developer7e4a2a62023-04-06 19:56:03 +08008187 char cmd [128] = {0};
8188 char buf[32] = {0};
8189 char ap_idx = 0;
8190 char *apIndex_str = NULL;
8191 char radio_idx = 0;
8192 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08008193 int res;
developer72fb0bb2023-01-11 09:46:29 +08008194
developere40952c2023-06-15 18:46:43 +08008195 res = snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +08008196 inputSsidString);
developere40952c2023-06-15 18:46:43 +08008197
8198 if (os_snprintf_error(sizeof(cmd), res)) {
8199 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8200 return RETURN_ERR;
8201 }
8202
developer7e4a2a62023-04-06 19:56:03 +08008203 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008204
developer7e4a2a62023-04-06 19:56:03 +08008205 if (strlen(buf)) {
8206 apIndex_str = strtok(buf, "\n");
8207 *output_int = strtoul(apIndex_str, NULL, 10);
8208 return RETURN_OK;
8209 }
developer72fb0bb2023-01-11 09:46:29 +08008210
developer7e4a2a62023-04-06 19:56:03 +08008211 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
8212 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
8213 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
8214 radio_idx = 2;
8215 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
8216 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
8217 radio_idx = 1;
8218 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
8219 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
8220 radio_idx = 0;
8221 } else {
8222 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
8223 __func__, inputSsidString, ap_idx);
developera3511852023-06-14 14:12:59 +08008224 *output_int = -1;
8225 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08008226 }
8227
8228 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
8229
8230 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
8231 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
8232 __func__, inputSsidString, ap_idx);
8233 *output_int = ap_idx;
8234 return RETURN_OK;
8235 }
8236
8237 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008238}
8239
8240INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
8241{
developera3511852023-06-14 14:12:59 +08008242 return wifi_getIndexFromName(inputSsidString, output_int);
developer72fb0bb2023-01-11 09:46:29 +08008243}
8244
8245// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
8246INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
8247{
developera3511852023-06-14 14:12:59 +08008248 char buf[MAX_BUF_SIZE] = {0};
8249 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08008250 int res;
developer72fb0bb2023-01-11 09:46:29 +08008251
developera3511852023-06-14 14:12:59 +08008252 if(NULL == output_string)
8253 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008254
developer32f2a182023-06-27 19:50:41 +08008255 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
8256 if (os_snprintf_error(sizeof(config_file), res)) {
8257 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8258 return RETURN_ERR;
8259 }
developera3511852023-06-14 14:12:59 +08008260 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
8261 if((strcmp(buf,"3")==0))
developere40952c2023-06-15 18:46:43 +08008262 res = snprintf(output_string, 32, "WPAand11i");
developera3511852023-06-14 14:12:59 +08008263 else if((strcmp(buf,"2")==0))
developere40952c2023-06-15 18:46:43 +08008264 res = snprintf(output_string, 32, "11i");
developera3511852023-06-14 14:12:59 +08008265 else if((strcmp(buf,"1")==0))
developere40952c2023-06-15 18:46:43 +08008266 res = snprintf(output_string, 32, "WPA");
developera3511852023-06-14 14:12:59 +08008267 else
developere40952c2023-06-15 18:46:43 +08008268 res = snprintf(output_string, 32, "None");
8269 if (os_snprintf_error(32, res)) {
8270 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8271 return RETURN_ERR;
8272 }
developer72fb0bb2023-01-11 09:46:29 +08008273
developera3511852023-06-14 14:12:59 +08008274 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008275}
8276
8277// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
8278INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
8279{
developera3511852023-06-14 14:12:59 +08008280 char config_file[MAX_BUF_SIZE] = {0};
8281 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008282 int res;
developer72fb0bb2023-01-11 09:46:29 +08008283
developera3511852023-06-14 14:12:59 +08008284 if (NULL == beaconTypeString)
8285 return RETURN_ERR;
8286 list.name = "wpa";
8287 list.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08008288
developera3511852023-06-14 14:12:59 +08008289 if((strcmp(beaconTypeString,"WPAand11i")==0))
8290 list.value="3";
8291 else if((strcmp(beaconTypeString,"11i")==0))
8292 list.value="2";
8293 else if((strcmp(beaconTypeString,"WPA")==0))
8294 list.value="1";
developer72fb0bb2023-01-11 09:46:29 +08008295
developer75bd10c2023-06-27 11:34:08 +08008296 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8297 if (os_snprintf_error(sizeof(config_file), res)) {
8298 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8299 return RETURN_ERR;
8300 }
developera3511852023-06-14 14:12:59 +08008301 wifi_hostapdWrite(config_file, &list, 1);
8302 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8303 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8304 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008305}
8306
8307// sets the beacon interval on the hardware for this AP
8308INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
8309{
developera3511852023-06-14 14:12:59 +08008310 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8311 struct params params={'\0'};
8312 char buf[MAX_BUF_SIZE] = {'\0'};
8313 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08008314 int res;
developer72fb0bb2023-01-11 09:46:29 +08008315
developera3511852023-06-14 14:12:59 +08008316 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08008317 res = snprintf(buf, sizeof(buf), "%u", beaconInterval);
8318 if (os_snprintf_error(sizeof(buf), res)) {
8319 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8320 return RETURN_ERR;
8321 }
developera3511852023-06-14 14:12:59 +08008322 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08008323
developer75bd10c2023-06-27 11:34:08 +08008324 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8325 if (os_snprintf_error(sizeof(config_file), res)) {
8326 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8327 return RETURN_ERR;
8328 }
developera3511852023-06-14 14:12:59 +08008329 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08008330
developera3511852023-06-14 14:12:59 +08008331 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8332 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8333 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008334}
8335
8336INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
8337{
developera3511852023-06-14 14:12:59 +08008338 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
8339 return RETURN_ERR;
8340 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008341}
8342
8343// Get the packet size threshold supported.
8344INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
8345{
developera3511852023-06-14 14:12:59 +08008346 //save config and apply instantly
8347 if (NULL == output_bool)
8348 return RETURN_ERR;
8349 *output_bool = TRUE;
8350 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008351}
8352
8353// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
8354INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
8355{
developera3511852023-06-14 14:12:59 +08008356 char buf[16] = {0};
8357 char config_file[128] = {0};
8358 struct params param = {0};
developere40952c2023-06-15 18:46:43 +08008359 int res;
developer72fb0bb2023-01-11 09:46:29 +08008360
developera3511852023-06-14 14:12:59 +08008361 if (threshold > 65535) {
developer75bd10c2023-06-27 11:34:08 +08008362 wifi_debug(DEBUG_ERROR, "rts threshold %u is too big.\n", threshold);
developera3511852023-06-14 14:12:59 +08008363 return RETURN_ERR;
8364 }
developer72fb0bb2023-01-11 09:46:29 +08008365
developere40952c2023-06-15 18:46:43 +08008366 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8367 if (os_snprintf_error(sizeof(config_file), res)) {
8368 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8369 return RETURN_ERR;
8370 }
8371
8372 res = snprintf(buf, sizeof(buf), "%u", threshold);
8373 if (os_snprintf_error(sizeof(buf), res)) {
8374 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8375 return RETURN_ERR;
8376 }
developera3511852023-06-14 14:12:59 +08008377 param.name = "rts_threshold";
8378 param.value = buf;
8379 wifi_hostapdWrite(config_file, &param, 1);
8380 wifi_hostapdProcessUpdate(apIndex, &param, 1);
8381 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008382
developera3511852023-06-14 14:12:59 +08008383 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008384}
8385
8386// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8387INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
8388{
developere40952c2023-06-15 18:46:43 +08008389 int res;
8390
developera3511852023-06-14 14:12:59 +08008391 if (NULL == output_string)
8392 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008393 res = snprintf(output_string, 32, "TKIPandAESEncryption");
8394 if (os_snprintf_error(32, res)) {
8395 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8396 return RETURN_ERR;
8397 }
developera3511852023-06-14 14:12:59 +08008398 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008399
8400}
8401
8402// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8403INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
8404{
developera3511852023-06-14 14:12:59 +08008405 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8406 char *param_name = NULL;
8407 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
developerc79e9172023-06-06 19:48:03 +08008408 unsigned int len;
developere40952c2023-06-15 18:46:43 +08008409 int res;
developer72fb0bb2023-01-11 09:46:29 +08008410
developera3511852023-06-14 14:12:59 +08008411 if(NULL == output_string)
8412 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008413
developer75bd10c2023-06-27 11:34:08 +08008414 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8415 if (os_snprintf_error(sizeof(config_file), res)) {
8416 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8417 return RETURN_ERR;
8418 }
8419
developera3511852023-06-14 14:12:59 +08008420 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008421
developera3511852023-06-14 14:12:59 +08008422 if(strcmp(buf,"0")==0)
8423 {
8424 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
developere40952c2023-06-15 18:46:43 +08008425 res = snprintf(output_string, 32, "None");
8426 if (os_snprintf_error(32, res)) {
8427 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8428 return RETURN_ERR;
8429 }
developera3511852023-06-14 14:12:59 +08008430 return RETURN_OK;
8431 }
8432 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
8433 param_name = "rsn_pairwise";
8434 else if((strcmp(buf,"1")==0))
8435 param_name = "wpa_pairwise";
8436 else
8437 return RETURN_ERR;
8438 memset(output_string,'\0',32);
8439 wifi_hostapdRead(config_file,param_name,output_string,32);
8440 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
8441 param_name = "wpa_pairwise";
8442 memset(output_string, '\0', 32);
8443 wifi_hostapdRead(config_file, param_name, output_string, 32);
8444 }
8445 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
developer72fb0bb2023-01-11 09:46:29 +08008446
developera3511852023-06-14 14:12:59 +08008447 if(strcmp(output_string,"TKIP CCMP") == 0) {
developerc79e9172023-06-06 19:48:03 +08008448 len = strlen("TKIPandAESEncryption");
8449 memcpy(output_string,"TKIPandAESEncryption", len);
8450 output_string[len] = '\0';
8451 } else if(strcmp(output_string,"TKIP") == 0) {
8452 len = strlen("TKIPEncryption");
8453 memcpy(output_string,"TKIPEncryption", len);
8454 output_string[len] = '\0';
8455 } else if(strcmp(output_string,"CCMP") == 0) {
8456 len = strlen("AESEncryption");
8457 memcpy(output_string,"AESEncryption", len);
8458 output_string[len] = '\0';
8459 }
developer72fb0bb2023-01-11 09:46:29 +08008460
developera3511852023-06-14 14:12:59 +08008461 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8462 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008463}
8464
8465// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8466INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
8467{
developera3511852023-06-14 14:12:59 +08008468 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8469 struct params params={'\0'};
8470 char output_string[32];
8471 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008472 int res;
developer72fb0bb2023-01-11 09:46:29 +08008473
developera3511852023-06-14 14:12:59 +08008474 memset(output_string,'\0',32);
8475 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08008476
developera3511852023-06-14 14:12:59 +08008477 if(strcmp(encMode, "TKIPEncryption") == 0)
8478 params.value = "TKIP";
8479 else if(strcmp(encMode,"AESEncryption") == 0)
8480 params.value = "CCMP";
8481 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
8482 params.value = "TKIP CCMP";
developer72fb0bb2023-01-11 09:46:29 +08008483
developera3511852023-06-14 14:12:59 +08008484 if((strcmp(output_string,"WPAand11i")==0))
8485 {
8486 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008487 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8488 if (os_snprintf_error(sizeof(config_file), res)) {
8489 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8490 return RETURN_ERR;
8491 }
developera3511852023-06-14 14:12:59 +08008492 wifi_hostapdWrite(config_file, &params, 1);
8493 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08008494
developera3511852023-06-14 14:12:59 +08008495 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008496 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8497 if (os_snprintf_error(sizeof(config_file), res)) {
8498 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8499 return RETURN_ERR;
8500 }
developera3511852023-06-14 14:12:59 +08008501 wifi_hostapdWrite(config_file, &params, 1);
8502 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08008503
developera3511852023-06-14 14:12:59 +08008504 return RETURN_OK;
8505 }
8506 else if((strcmp(output_string,"11i")==0))
8507 {
8508 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008509 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8510 if (os_snprintf_error(sizeof(config_file), res)) {
8511 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8512 return RETURN_ERR;
8513 }
developera3511852023-06-14 14:12:59 +08008514 wifi_hostapdWrite(config_file, &params, 1);
8515 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8516 return RETURN_OK;
8517 }
8518 else if((strcmp(output_string,"WPA")==0))
8519 {
8520 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008521 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8522 if (os_snprintf_error(sizeof(config_file), res)) {
8523 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8524 return RETURN_ERR;
8525 }
developera3511852023-06-14 14:12:59 +08008526 wifi_hostapdWrite(config_file, &params, 1);
8527 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8528 return RETURN_OK;
8529 }
developer72fb0bb2023-01-11 09:46:29 +08008530
developera3511852023-06-14 14:12:59 +08008531 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8532 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008533}
8534
8535// deletes internal security varable settings for this ap
8536INT wifi_removeApSecVaribles(INT apIndex)
8537{
developer0155a502023-06-19 20:33:57 +08008538 char config_file[MAX_BUF_SIZE] = {0};
8539 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008540 int res;
developer0155a502023-06-19 20:33:57 +08008541
8542 list.name = "wpa";
8543 list.value = "0";
8544
developer75bd10c2023-06-27 11:34:08 +08008545 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8546 if (os_snprintf_error(sizeof(config_file), res)) {
8547 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8548 return RETURN_ERR;
8549 }
developer0155a502023-06-19 20:33:57 +08008550 wifi_hostapdWrite(config_file, &list, 1);
8551
8552 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008553}
8554
8555// changes the hardware settings to disable encryption on this ap
8556INT wifi_disableApEncryption(INT apIndex)
8557{
developer0155a502023-06-19 20:33:57 +08008558 char config_file[MAX_BUF_SIZE] = {0};
8559 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008560 int res;
developer0155a502023-06-19 20:33:57 +08008561
8562 list.name = "wpa";
8563 list.value = "0";
8564
developer75bd10c2023-06-27 11:34:08 +08008565 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8566 if (os_snprintf_error(sizeof(config_file), res)) {
8567 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8568 return RETURN_ERR;
8569 }
developer0155a502023-06-19 20:33:57 +08008570 wifi_hostapdWrite(config_file, &list, 1);
8571 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8572 wifi_reloadAp(apIndex);
8573
8574 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008575}
8576
8577// set the authorization mode on this ap
8578// mode mapping as: 1: open, 2: shared, 4:auto
8579INT wifi_setApAuthMode(INT apIndex, INT mode)
8580{
developera3511852023-06-14 14:12:59 +08008581 struct params params={0};
8582 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +08008583 int res;
developer72fb0bb2023-01-11 09:46:29 +08008584
developera3511852023-06-14 14:12:59 +08008585 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008586
developera3511852023-06-14 14:12:59 +08008587 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
8588 params.name = "auth_algs";
developer72fb0bb2023-01-11 09:46:29 +08008589
developere5750452023-05-15 16:46:42 +08008590 if ((mode & 1 && mode & 2) || mode & 4)
developera3511852023-06-14 14:12:59 +08008591 params.value = "3";
8592 else if (mode & 2)
8593 params.value = "2";
8594 else if (mode & 1)
8595 params.value = "1";
8596 else
8597 params.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08008598
developer75bd10c2023-06-27 11:34:08 +08008599 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8600 if (os_snprintf_error(sizeof(config_file), res)) {
8601 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8602 return RETURN_ERR;
8603 }
developera3511852023-06-14 14:12:59 +08008604 wifi_hostapdWrite(config_file, &params, 1);
8605 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008606 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +08008607 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008608
developera3511852023-06-14 14:12:59 +08008609 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008610}
8611
8612// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
8613INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
8614{
developera3511852023-06-14 14:12:59 +08008615 //save to wifi config, and wait for wifi restart to apply
8616 struct params params={'\0'};
8617 char config_file[MAX_BUF_SIZE] = {0};
8618 int ret;
developer72fb0bb2023-01-11 09:46:29 +08008619
developera3511852023-06-14 14:12:59 +08008620 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8621 if(authMode == NULL)
8622 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008623
developera3511852023-06-14 14:12:59 +08008624 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
8625 params.name = "wpa_key_mgmt";
developer72fb0bb2023-01-11 09:46:29 +08008626
developera3511852023-06-14 14:12:59 +08008627 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
8628 params.value = "WPA-PSK";
8629 else if(strcmp(authMode,"EAPAuthentication") == 0)
8630 params.value = "WPA-EAP";
8631 else if (strcmp(authMode, "SAEAuthentication") == 0)
8632 params.value = "SAE";
8633 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
8634 params.value = "WPA-EAP-SUITE-B-192";
8635 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
8636 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
8637 else if (strcmp(authMode, "Enhanced_Open") == 0)
8638 params.value = "OWE";
8639 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
8640 return RETURN_OK; //This is taken careof in beaconType
developer72fb0bb2023-01-11 09:46:29 +08008641
developer32f2a182023-06-27 19:50:41 +08008642 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
8643 if (os_snprintf_error(sizeof(config_file), ret)) {
8644 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8645 return RETURN_ERR;
8646 }
developera3511852023-06-14 14:12:59 +08008647 ret=wifi_hostapdWrite(config_file,&params,1);
8648 if(!ret)
8649 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
8650 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008651
developera3511852023-06-14 14:12:59 +08008652 return ret;
developer72fb0bb2023-01-11 09:46:29 +08008653}
8654
8655// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
8656INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
8657{
developera3511852023-06-14 14:12:59 +08008658 //save to wifi config, and wait for wifi restart to apply
8659 char BeaconType[50] = {0};
8660 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008661 int res;
developer32f2a182023-06-27 19:50:41 +08008662 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08008663
developera3511852023-06-14 14:12:59 +08008664 *authMode = 0;
8665 wifi_getApBeaconType(apIndex,BeaconType);
8666 printf("%s____%s \n",__FUNCTION__,BeaconType);
developer72fb0bb2023-01-11 09:46:29 +08008667
developer32f2a182023-06-27 19:50:41 +08008668 if(strcmp(BeaconType,"None") == 0) {
8669 memcpy(authMode, "None", 4);
8670 authMode[4] = '\0';
8671 } else {
8672 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
developer75bd10c2023-06-27 11:34:08 +08008673 if (os_snprintf_error(sizeof(config_file), res)) {
8674 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8675 return RETURN_ERR;
8676 }
developera3511852023-06-14 14:12:59 +08008677 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
8678 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
developer32f2a182023-06-27 19:50:41 +08008679 if(strcmp(authMode,"WPA-PSK") == 0) {
8680 len = strlen("SharedAuthentication");
8681 memcpy(authMode, "SharedAuthentication", len);
8682 authMode[len] = '\0';
8683 } else if(strcmp(authMode,"WPA-EAP") == 0) {
8684 len = strlen("EAPAuthentication");
8685 memcpy(authMode, "EAPAuthentication", len);
8686 authMode[len] = '\0';
8687 }
developera3511852023-06-14 14:12:59 +08008688 }
developer72fb0bb2023-01-11 09:46:29 +08008689
developera3511852023-06-14 14:12:59 +08008690 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008691}
8692
8693// Outputs the number of stations associated per AP
8694INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
8695{
developera3511852023-06-14 14:12:59 +08008696 char interface_name[16] = {0};
8697 char cmd[128]={0};
8698 char buf[128]={0};
8699 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +08008700 int res;
developer72fb0bb2023-01-11 09:46:29 +08008701
developera3511852023-06-14 14:12:59 +08008702 if(apIndex > MAX_APS)
8703 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008704
developera3511852023-06-14 14:12:59 +08008705 wifi_getApEnable(apIndex,&status);
8706 if (!status)
8707 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008708
developera3511852023-06-14 14:12:59 +08008709 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
8710 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8711 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08008712 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta | wc -l", interface_name);
8713 if (os_snprintf_error(sizeof(cmd), res)) {
8714 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8715 return RETURN_ERR;
8716 }
developera3511852023-06-14 14:12:59 +08008717 _syscmd(cmd, buf, sizeof(buf));
8718 sscanf(buf,"%lu", output_ulong);
developer72fb0bb2023-01-11 09:46:29 +08008719
developera3511852023-06-14 14:12:59 +08008720 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008721}
8722
8723// manually removes any active wi-fi association with the device specified on this ap
8724INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
8725{
developera3511852023-06-14 14:12:59 +08008726 char inf_name[16] = {0};
8727 char cmd[MAX_CMD_SIZE] = {0};
8728 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08008729 int res;
developer72fb0bb2023-01-11 09:46:29 +08008730
developera3511852023-06-14 14:12:59 +08008731 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8732 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008733
8734 res = snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
8735 if (os_snprintf_error(sizeof(cmd), res)) {
8736 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8737 return RETURN_ERR;
8738 }
developer7e4a2a62023-04-06 19:56:03 +08008739
developera3511852023-06-14 14:12:59 +08008740 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008741
developera3511852023-06-14 14:12:59 +08008742 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008743}
8744
8745// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
8746INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
8747{
developer7e4a2a62023-04-06 19:56:03 +08008748 int max_radio_num = 0;
8749
8750 if(NULL == output_int)
8751 return RETURN_ERR;
8752
8753 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08008754 if(max_radio_num == 0){
8755 return RETURN_ERR;
8756 }
developer7e4a2a62023-04-06 19:56:03 +08008757 *output_int = apIndex % max_radio_num;
8758
8759 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008760}
8761
8762// sets the radio index for the specific ap
8763INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
8764{
developera3511852023-06-14 14:12:59 +08008765 //set to config only and wait for wifi reset to apply settings
8766 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008767}
8768
developer0155a502023-06-19 20:33:57 +08008769int mtk_get_ap_metrics(struct nl_msg *msg, void *cb)
8770{
8771 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8772 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX + 1];
8773 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8774 wdev_ap_metric ap_metric;
8775 wdev_ap_metric *p_ap_metric = &ap_metric;
8776 int err = 0;
8777 struct mtk_nl80211_cb_data *cb_data = cb;
8778
8779 if (!msg || !cb_data) {
8780 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
8781 return NL_SKIP;
8782 }
8783
8784 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8785 genlmsg_attrlen(gnlh, 0), NULL);
8786 if (err < 0) {
8787 wifi_debug(DEBUG_ERROR, "nla_parse ap_metrics nl80211 msg fails,error.\n");
8788 return err;
8789 }
8790
8791 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8792 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX,
8793 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8794 if (err < 0) {
8795 wifi_debug(DEBUG_ERROR, "GET_STATISTIC_MAX fails,error.\n");
8796 return err;
8797 }
8798
8799 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]) {
8800 p_ap_metric = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]);
8801 if (p_ap_metric) {
8802 memcpy(cb_data->out_buf , &p_ap_metric->cu, sizeof(unsigned char));
8803 }
8804 }
8805 }
8806
8807 return NL_OK;
8808}
8809
developer121a8e72023-05-22 09:19:39 +08008810
8811#define MAX_ACL_DUMP_LEN 4096
8812int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
8813{
8814 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8815 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
8816 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8817 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08008818 int err = 0;
developer121a8e72023-05-22 09:19:39 +08008819 unsigned short acl_result_len = 0;
8820 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08008821 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08008822 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08008823 return NL_SKIP;
8824 }
developer121a8e72023-05-22 09:19:39 +08008825 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8826 genlmsg_attrlen(gnlh, 0), NULL);
8827 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08008828 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08008829 return NL_SKIP;
8830 }
developer121a8e72023-05-22 09:19:39 +08008831 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8832 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
8833 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8834 if (err < 0)
8835 return NL_SKIP;
8836 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
8837 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
8838 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
8839 if (acl_result_len > MAX_ACL_DUMP_LEN) {
8840 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
8841 return NL_SKIP;
8842 } else if (*(show_str + acl_result_len - 1) != '\0') {
8843 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
8844 *(show_str + acl_result_len - 1) = '\0';
8845 }
8846 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08008847
8848 if (cb_data->out_len >= acl_result_len) {
8849 memset(cb_data->out_buf, 0, cb_data->out_len);
8850 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
8851 memmove(cb_data->out_buf, show_str, acl_result_len);
8852 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
8853 } else {
8854 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08008855 }
developer121a8e72023-05-22 09:19:39 +08008856 } else
8857 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
8858 } else
8859 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
8860 return NL_OK;
8861}
developer72fb0bb2023-01-11 09:46:29 +08008862// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08008863INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08008864{
developer7e4a2a62023-04-06 19:56:03 +08008865 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08008866 unsigned int if_idx = 0;
8867 int ret = -1;
8868 struct unl unl_ins;
8869 struct nl_msg *msg = NULL;
8870 struct nlattr * msg_data = NULL;
8871 struct mtk_nl80211_param param;
8872 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08008873 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8874 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08008875 if_idx = if_nametoindex(inf_name);
8876 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08008877 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08008878 return RETURN_ERR;
8879 }
8880 /*init mtk nl80211 vendor cmd*/
8881 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
8882 param.if_type = NL80211_ATTR_IFINDEX;
8883 param.if_idx = if_idx;
8884
8885 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8886 if (ret) {
8887 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8888 return RETURN_ERR;
8889 }
developer121a8e72023-05-22 09:19:39 +08008890 /*add mtk vendor cmd data*/
8891 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08008892 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08008893 nlmsg_free(msg);
8894 goto err;
8895 }
developer72fb0bb2023-01-11 09:46:29 +08008896
developer121a8e72023-05-22 09:19:39 +08008897 /*send mtk nl80211 vendor msg*/
8898 cb_data.out_buf = macArray;
8899 cb_data.out_len = buf_size;
8900
8901 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
8902 if (ret) {
8903 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8904 goto err;
8905 }
8906 /*deinit mtk nl80211 vendor msg*/
8907 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08008908 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developera3511852023-06-14 14:12:59 +08008909 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08008910err:
8911 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08008912 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08008913 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008914}
8915
developer2edaf012023-05-24 14:24:53 +08008916INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
8917{
8918 char *mac_arry_buf = NULL;
8919
8920 mac_arry_buf = malloc(buf_size);
8921 if (!mac_arry_buf) {
8922 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
8923 return RETURN_ERR;
8924 }
8925 memset(mac_arry_buf, 0, buf_size);
8926 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
8927 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
8928 free(mac_arry_buf);
8929 mac_arry_buf = NULL;
8930 return RETURN_ERR;
8931 }
8932 /*
8933 mtk format to wifi hal format:
8934 "policy=1
8935 00:11:22:33:44:55
8936 00:11:22:33:44:66
8937 "
8938 -->
8939 "00:11:22:33:44:55
8940 00:11:22:33:44:66
8941 "
8942 */
8943 memset(macArray, 0, buf_size);
8944 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
8945 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
8946 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
8947 }
8948 free(mac_arry_buf);
8949 mac_arry_buf = NULL;
8950 return RETURN_OK;
8951}
8952
developer72fb0bb2023-01-11 09:46:29 +08008953INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
8954{
developer72fb0bb2023-01-11 09:46:29 +08008955
developer7e4a2a62023-04-06 19:56:03 +08008956 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08008957
developera3511852023-06-14 14:12:59 +08008958 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008959}
8960
8961
8962// Get the list of stations associated per AP
8963INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
8964{
developer7e4a2a62023-04-06 19:56:03 +08008965 char interface_name[IF_NAME_SIZE] = {0};
8966 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08008967 int res;
developer72fb0bb2023-01-11 09:46:29 +08008968
developer7e4a2a62023-04-06 19:56:03 +08008969 if(apIndex > 3) //Currently supporting apIndex upto 3
developera3511852023-06-14 14:12:59 +08008970 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008971
developer7e4a2a62023-04-06 19:56:03 +08008972 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08008973 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08008974
developere40952c2023-06-15 18:46:43 +08008975 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
8976 if (os_snprintf_error(sizeof(cmd), res)) {
8977 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8978 return RETURN_ERR;
8979 }
developer7e4a2a62023-04-06 19:56:03 +08008980 _syscmd(cmd, macArray, buf_size);
8981 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008982}
8983
developer8dd72532023-05-17 19:58:35 +08008984int hex2num(char c)
8985{
8986 if (c >= '0' && c <= '9')
8987 return c - '0';
8988 if (c >= 'a' && c <= 'f')
8989 return c - 'a' + 10;
8990 if (c >= 'A' && c <= 'F')
8991 return c - 'A' + 10;
8992 return -1;
8993}
8994
8995/**
8996 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
8997 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
8998 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
8999 * Returns: Characters used (> 0) on success, -1 on failure
9000 */
9001int hwaddr_aton2(const char *txt, unsigned char *addr)
9002{
9003 int i;
9004 const char *pos = txt;
9005
9006 for (i = 0; i < 6; i++) {
9007 int a, b;
9008
9009 while (*pos == ':' || *pos == '.' || *pos == '-')
9010 pos++;
9011
9012 a = hex2num(*pos++);
9013 if (a < 0)
9014 return -1;
9015 b = hex2num(*pos++);
9016 if (b < 0)
9017 return -1;
9018 *addr++ = (a << 4) | b;
9019 }
9020
9021 return pos - txt;
9022}
9023
developer72fb0bb2023-01-11 09:46:29 +08009024// adds the mac address to the filter list
9025//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
9026INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
9027{
developer7e4a2a62023-04-06 19:56:03 +08009028 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08009029 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08009030 struct nl_msg *msg = NULL;
9031 struct nlattr * msg_data = NULL;
9032 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08009033 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
9034 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08009035 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9036 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08009037 if (!DeviceMacAddress)
9038 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08009039 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08009040 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08009041 return RETURN_ERR;
9042 }
developer8dd72532023-05-17 19:58:35 +08009043 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08009044 if (!if_idx) {
9045 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9046 return RETURN_ERR;
9047 }
developer49b17232023-05-19 16:35:19 +08009048 /*init mtk nl80211 vendor cmd*/
9049 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9050 param.if_type = NL80211_ATTR_IFINDEX;
9051 param.if_idx = if_idx;
9052 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9053 if (ret) {
9054 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08009055 return RETURN_ERR;
9056 }
developer49b17232023-05-19 16:35:19 +08009057 /*add mtk vendor cmd data*/
9058 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08009059 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08009060 nlmsg_free(msg);
9061 goto err;
9062 }
developer49b17232023-05-19 16:35:19 +08009063 /*send mtk nl80211 vendor msg*/
9064 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9065 if (ret) {
9066 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08009067 goto err;
9068 }
developer49b17232023-05-19 16:35:19 +08009069 /*deinit mtk nl80211 vendor msg*/
9070 mtk_nl80211_deint(&unl_ins);
9071 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08009072 return RETURN_OK;
9073err:
developer49b17232023-05-19 16:35:19 +08009074 mtk_nl80211_deint(&unl_ins);
9075 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08009076 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009077}
9078
9079// deletes the mac address from the filter list
9080//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
9081INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
9082{
developer2edaf012023-05-24 14:24:53 +08009083 struct unl unl_ins;
9084 int if_idx = 0, ret = 0;
9085 struct nl_msg *msg = NULL;
9086 struct nlattr * msg_data = NULL;
9087 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08009088 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08009089 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009090
developer7e4a2a62023-04-06 19:56:03 +08009091 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9092 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009093
developer7e4a2a62023-04-06 19:56:03 +08009094 if (!DeviceMacAddress)
9095 return RETURN_ERR;
9096
developer2edaf012023-05-24 14:24:53 +08009097 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
9098 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
9099 return RETURN_ERR;
9100 }
developer72fb0bb2023-01-11 09:46:29 +08009101
developer2edaf012023-05-24 14:24:53 +08009102 if_idx = if_nametoindex(inf_name);
9103 if (!if_idx) {
9104 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9105 return RETURN_ERR;
9106 }
9107 /*init mtk nl80211 vendor cmd*/
9108 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9109 param.if_type = NL80211_ATTR_IFINDEX;
9110 param.if_idx = if_idx;
9111 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9112 if (ret) {
9113 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9114 return RETURN_ERR;
9115 }
9116 /*add mtk vendor cmd data*/
9117 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
9118 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9119 nlmsg_free(msg);
9120 goto err;
9121 }
9122 /*send mtk nl80211 vendor msg*/
9123 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9124 if (ret) {
9125 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9126 goto err;
9127 }
9128 /*deinit mtk nl80211 vendor msg*/
9129 mtk_nl80211_deint(&unl_ins);
9130 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
9131 return RETURN_OK;
9132err:
9133 mtk_nl80211_deint(&unl_ins);
9134 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9135 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009136}
9137
9138// outputs the number of devices in the filter list
9139INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
9140{
developer2edaf012023-05-24 14:24:53 +08009141 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
9142 UINT buf_size = 1024;
9143 UINT sta_num = 0;
9144 unsigned char mac[ETH_ALEN] = {0};
developera3511852023-06-14 14:12:59 +08009145 if(output_uint == NULL)
developerdaf24792023-06-06 11:40:04 +08009146 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009147
developer2edaf012023-05-24 14:24:53 +08009148 mac_arry = (char *)malloc(buf_size);
9149 if (mac_arry == NULL) {
9150 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08009151 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08009152 }
developerdaf24792023-06-06 11:40:04 +08009153 memset(mac_arry, 0, buf_size);
developer2edaf012023-05-24 14:24:53 +08009154 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
9155 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
9156 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
developer9ce44382023-06-28 11:09:37 +08009157 free(mac_arry);
developer2edaf012023-05-24 14:24:53 +08009158 return RETURN_ERR;
9159 }
9160 /*count the acl str nums:*/
9161 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08009162
developer2edaf012023-05-24 14:24:53 +08009163 /*mac addr string format:
9164 exp1: 00:11:22:33:44:55\0
9165 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
9166 */
9167 ptr = mac_arry;
9168 while (sscanf(ptr, "%17s", mac_str) == 1) {
9169 if (hwaddr_aton2(mac_str, mac) >= 0)
9170 sta_num++;
9171 ptr = strstr(ptr, mac_str) + strlen(mac_str);
9172 }
9173 *output_uint = sta_num;
9174 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
9175 free(mac_arry);
9176 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08009177 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009178}
9179
9180INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
9181{
developera3511852023-06-14 14:12:59 +08009182 char buf[128]={'\0'};
developer75bd10c2023-06-27 11:34:08 +08009183 int res;
developer72fb0bb2023-01-11 09:46:29 +08009184
developera3511852023-06-14 14:12:59 +08009185 if(strcmp(action,"DENY")==0)
9186 {
developer32f2a182023-06-27 19:50:41 +08009187 res = snprintf(buf, sizeof(buf),
9188 "iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",
9189 apIndex, interface, client_mac);
developer75bd10c2023-06-27 11:34:08 +08009190 if (os_snprintf_error(sizeof(buf), res)) {
9191 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9192 return RETURN_ERR;
9193 }
developera3511852023-06-14 14:12:59 +08009194 system(buf);
9195 return RETURN_OK;
9196 }
developer72fb0bb2023-01-11 09:46:29 +08009197
developera3511852023-06-14 14:12:59 +08009198 if(strcmp(action,"ALLOW")==0)
9199 {
developer32f2a182023-06-27 19:50:41 +08009200 res = snprintf(buf, sizeof(buf),
9201 "iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",
9202 apIndex, interface, client_mac);
developer75bd10c2023-06-27 11:34:08 +08009203 if (os_snprintf_error(sizeof(buf), res)) {
9204 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9205 return RETURN_ERR;
9206 }
developera3511852023-06-14 14:12:59 +08009207 system(buf);
9208 return RETURN_OK;
9209 }
developer72fb0bb2023-01-11 09:46:29 +08009210
developera3511852023-06-14 14:12:59 +08009211 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009212
9213}
9214
9215// enable kick for devices on acl black list
9216INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
9217{
developera3511852023-06-14 14:12:59 +08009218 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
9219 char assocArray[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009220
developera3511852023-06-14 14:12:59 +08009221 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
9222 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
developer72fb0bb2023-01-11 09:46:29 +08009223
developera3511852023-06-14 14:12:59 +08009224 /* if there are no devices connected there is nothing to do */
9225 if (strlen(assocArray) < 17)
9226 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009227
developera3511852023-06-14 14:12:59 +08009228 if (enable == TRUE) {
9229 /* kick off the MAC which is in ACL array (deny list) */
9230 acl = strtok(aclArray, "\n");
9231 while (acl != NULL) {
9232 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
9233 wifi_kickApAssociatedDevice(apIndex, acl);
developer72fb0bb2023-01-11 09:46:29 +08009234
developera3511852023-06-14 14:12:59 +08009235 acl = strtok(NULL, "\n");
9236 }
developer72fb0bb2023-01-11 09:46:29 +08009237 wifi_setApMacAddressControlMode(apIndex, 2);
developera3511852023-06-14 14:12:59 +08009238 } else
developer72fb0bb2023-01-11 09:46:29 +08009239 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08009240
developera3511852023-06-14 14:12:59 +08009241 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009242}
9243
9244INT wifi_setPreferPrivateConnection(BOOL enable)
9245{
developera3511852023-06-14 14:12:59 +08009246 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009247}
9248
9249// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
9250INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
9251{
developer2edaf012023-05-24 14:24:53 +08009252 int if_idx = 0, ret = 0;
9253 struct unl unl_ins;
9254 struct nl_msg *msg = NULL;
9255 struct nlattr * msg_data = NULL;
9256 struct mtk_nl80211_param param;
9257 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08009258 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009259
developer7e4a2a62023-04-06 19:56:03 +08009260 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9261 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08009262 if_idx = if_nametoindex(inf_name);
9263 if (!if_idx) {
9264 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9265 return RETURN_ERR;
9266 }
9267 /*init mtk nl80211 vendor cmd*/
9268 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9269 param.if_type = NL80211_ATTR_IFINDEX;
9270 param.if_idx = if_idx;
9271 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9272 if (ret) {
9273 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9274 return RETURN_ERR;
9275 }
9276 /*add mtk vendor cmd data*/
9277 if (filterMode == 0) {
9278 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
9279 } else if (filterMode == 1) {
9280 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
9281 } else if (filterMode == 2) {
9282 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
9283 } else {
9284 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
9285 nlmsg_free(msg);
9286 goto err;
9287 }
9288 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
9289 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9290 nlmsg_free(msg);
9291 goto err;
9292 }
9293 /*send mtk nl80211 vendor msg*/
9294 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9295 if (ret) {
9296 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9297 goto err;
9298 }
9299 /*deinit mtk nl80211 vendor msg*/
9300 mtk_nl80211_deint(&unl_ins);
9301 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08009302 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08009303err:
9304 mtk_nl80211_deint(&unl_ins);
9305 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9306 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009307}
9308
9309// 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.
9310INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
9311{
developera3511852023-06-14 14:12:59 +08009312 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009313}
9314
9315// gets the vlan ID for this ap from an internal enviornment variable
9316INT wifi_getApVlanID(INT apIndex, INT *output_int)
9317{
developera3511852023-06-14 14:12:59 +08009318 if(apIndex==0)
9319 {
9320 *output_int=100;
9321 return RETURN_OK;
9322 }
developer72fb0bb2023-01-11 09:46:29 +08009323
developera3511852023-06-14 14:12:59 +08009324 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009325}
9326
9327// sets the vlan ID for this ap to an internal enviornment variable
9328INT wifi_setApVlanID(INT apIndex, INT vlanId)
9329{
developera3511852023-06-14 14:12:59 +08009330 //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 +08009331 char interface_name[16] = {0};
9332 int if_idx, ret = 0;
9333 struct nl_msg *msg = NULL;
9334 struct nlattr * msg_data = NULL;
9335 struct mtk_nl80211_param param;
9336 struct unl unl_ins;
9337
9338 if (apIndex > MAX_APS) {
9339 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9340 return RETURN_ERR;
9341 }
9342 if (vlanId > 4095 || vlanId < 1) {
9343 wifi_debug(DEBUG_ERROR, "Invalid vlanId %d\n", vlanId);
9344 return RETURN_ERR;
9345 }
9346 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9347 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9348 return RETURN_ERR;
9349 /*step 1. mwctl dev %s set vlan_tag 0*/
9350 if_idx = if_nametoindex(interface_name);
9351 /*init mtk nl80211 vendor cmd*/
9352 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
9353 param.if_type = NL80211_ATTR_IFINDEX;
9354 param.if_idx = if_idx;
9355 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9356 if (ret) {
9357 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9358 return RETURN_ERR;
9359 }
9360 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, vlanId)) {
9361 printf("Nla put attribute error\n");
9362 nlmsg_free(msg);
9363 goto err;
9364 }
9365 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9366 if (ret) {
9367 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9368 goto err;
9369 }
9370 mtk_nl80211_deint(&unl_ins);
9371 //wifi_debug(DEBUG_NOTICE, "set vlanId cmd success.\n", vlanId);
9372 printf("set vlanId=%d cmd success.\n", vlanId);
9373 return RETURN_OK;
9374err:
9375 mtk_nl80211_deint(&unl_ins);
9376 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08009377 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009378}
9379
developercc5cbfb2023-06-13 18:29:52 +08009380char br_name[IFNAMSIZ] = "brlan0";
9381
developer72fb0bb2023-01-11 09:46:29 +08009382// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
9383INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
9384{
developercc5cbfb2023-06-13 18:29:52 +08009385 int sock = socket(AF_INET, SOCK_DGRAM, 0);
9386 struct ifreq ifr;
9387 struct sockaddr_in *sin;
9388
9389 memcpy(bridgeName, br_name, strlen(br_name));
9390
9391 if (sock == -1) {
9392 wifi_debug(DEBUG_ERROR, "socket failed");
9393 return RETURN_ERR;
9394 }
9395
9396 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
9397 ifr.ifr_addr.sa_family = AF_INET;
9398 if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
9399 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFADDR) failed, %s, bridge_name=%s\n",
9400 strerror(errno), br_name);
developer9ce44382023-06-28 11:09:37 +08009401 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009402 return RETURN_ERR;
9403 }
9404
9405 sin = (struct sockaddr_in *)&ifr.ifr_addr;
9406 wifi_debug(DEBUG_ERROR, "Bridge device %s has IP address: %s\n", br_name, inet_ntoa(sin->sin_addr));
9407 memcpy(IP, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
9408
9409 if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0) {
9410 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFNETMASK) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009411 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009412 return RETURN_ERR;
9413 }
9414
9415 wifi_debug(DEBUG_ERROR, "Bridge device %s has subnet mask: %s\n", br_name, inet_ntoa(sin->sin_addr));
9416 memcpy(subnet, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
9417 close(sock);
developer72fb0bb2023-01-11 09:46:29 +08009418
developera3511852023-06-14 14:12:59 +08009419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009420}
9421
9422//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
9423INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
9424{
developera3511852023-06-14 14:12:59 +08009425 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
developercc5cbfb2023-06-13 18:29:52 +08009426 struct ifreq ifr;
9427 struct sockaddr_in sin;
9428 int sock = socket(AF_INET, SOCK_DGRAM, 0);
9429
9430 if (strlen(bridgeName) >= IFNAMSIZ) {
9431 wifi_debug(DEBUG_ERROR, "invalide bridgeName length=%ld\n", strlen(bridgeName));
developer9ce44382023-06-28 11:09:37 +08009432 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009433 return RETURN_ERR;
9434 }
9435
9436 if (strlen(br_name) >= IFNAMSIZ) {
9437 wifi_debug(DEBUG_ERROR, "invalide br_name length=%ld in strorage\n", strlen(br_name));
developer9ce44382023-06-28 11:09:37 +08009438 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009439 return RETURN_ERR;
9440 }
9441
9442 if (sock == -1) {
developera3511852023-06-14 14:12:59 +08009443 wifi_debug(DEBUG_ERROR, "socket failed");
developercc5cbfb2023-06-13 18:29:52 +08009444 return RETURN_ERR;
9445 }
9446
9447 memset(&ifr, 0, sizeof(ifr));
9448 strncpy(ifr.ifr_name, br_name, strlen(br_name));
9449 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
9450 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009451 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009452 return RETURN_ERR;
9453 }
9454
9455 ifr.ifr_flags = (short)(ifr.ifr_flags & ~IFF_UP);
9456 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
9457 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009458 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009459 return RETURN_ERR;
9460 }
9461
9462 memset(&ifr, 0, sizeof(ifr));
9463 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
9464 strncpy(ifr.ifr_newname, bridgeName, IFNAMSIZ);
9465 if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
9466 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNAME) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009467 close(sock);
developera3511852023-06-14 14:12:59 +08009468 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009469 }
9470
9471 memset(br_name, 0, sizeof(br_name));
9472 memcpy(br_name, bridgeName, strlen(bridgeName));
9473
9474 memset(&ifr, 0, sizeof(ifr));
9475 strncpy(ifr.ifr_name, bridgeName, IFNAMSIZ);
9476 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
9477 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009478 close(sock);
developera3511852023-06-14 14:12:59 +08009479 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009480 }
9481 ifr.ifr_flags = (short)(ifr.ifr_flags | IFF_UP);
9482 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
9483 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009484 close(sock);
developera3511852023-06-14 14:12:59 +08009485 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009486 }
9487
9488 memset(&ifr, 0, sizeof(ifr));
9489 memcpy(ifr.ifr_name, bridgeName, strlen(bridgeName));
9490
9491 memset(&sin, 0, sizeof(struct sockaddr_in));
9492 sin.sin_family = AF_INET;
9493 if (inet_aton(IP, &(sin.sin_addr)) == 0) {
9494 wifi_debug(DEBUG_ERROR, "inet_aton failed");
developer9ce44382023-06-28 11:09:37 +08009495 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009496 return RETURN_ERR;
9497 }
9498 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in));
9499 if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
9500 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFADDR) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009501 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009502 return RETURN_ERR;
9503 }
9504
9505 if (inet_aton(subnet, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr) == 0) {
9506 wifi_debug(DEBUG_ERROR, "inet_aton failed");
9507 return RETURN_ERR;
9508 }
9509 if (ioctl(sock, SIOCSIFNETMASK, &ifr) < -1) {
9510 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNETMASK) failed, %s", strerror(errno));
9511 return RETURN_ERR;
9512 }
9513
9514 close(sock);
developera3511852023-06-14 14:12:59 +08009515 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009516}
9517
9518// reset the vlan configuration for this ap
9519INT wifi_resetApVlanCfg(INT apIndex)
9520{
developera1255e42023-05-13 17:45:02 +08009521 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08009522 int if_idx, ret = 0;
9523 struct nl_msg *msg = NULL;
9524 struct nlattr * msg_data = NULL;
9525 struct mtk_nl80211_param param;
9526 struct unl unl_ins;
9527 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08009528
developer2202b332023-05-24 16:23:22 +08009529 if (apIndex > MAX_APS) {
9530 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9531 return RETURN_ERR;
9532 }
developer72fb0bb2023-01-11 09:46:29 +08009533
developer2202b332023-05-24 16:23:22 +08009534 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9535 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9536 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009537
developer2202b332023-05-24 16:23:22 +08009538 /*step 1. mwctl dev %s set vlan_tag 0*/
9539 if_idx = if_nametoindex(interface_name);
9540 /*init mtk nl80211 vendor cmd*/
9541 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
9542 param.if_type = NL80211_ATTR_IFINDEX;
9543 param.if_idx = if_idx;
9544 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08009545
developer2202b332023-05-24 16:23:22 +08009546 if (ret) {
9547 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9548 return RETURN_ERR;
9549 }
developer72fb0bb2023-01-11 09:46:29 +08009550
developer2202b332023-05-24 16:23:22 +08009551 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
9552 printf("Nla put attribute error\n");
9553 nlmsg_free(msg);
9554 goto err;
9555 }
developer72fb0bb2023-01-11 09:46:29 +08009556
developer2202b332023-05-24 16:23:22 +08009557 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9558 if (ret) {
9559 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9560 goto err;
9561 }
9562 mtk_nl80211_deint(&unl_ins);
9563 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08009564
developer2202b332023-05-24 16:23:22 +08009565 /*step 2. mwctl dev %s set vlan_priority 0*/
9566 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9567 if (ret) {
9568 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9569 return RETURN_ERR;
9570 }
developer72fb0bb2023-01-11 09:46:29 +08009571
developer2202b332023-05-24 16:23:22 +08009572 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
9573 printf("Nla put attribute error\n");
9574 nlmsg_free(msg);
9575 goto err;
9576 }
developer72fb0bb2023-01-11 09:46:29 +08009577
developer2202b332023-05-24 16:23:22 +08009578 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9579 if (ret) {
9580 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9581 goto err;
9582 }
9583 mtk_nl80211_deint(&unl_ins);
9584 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
9585
9586 /*step 3. mwctl dev %s set vlan_id 0*/
9587 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9588 if (ret) {
9589 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08009590 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08009591 }
developer72fb0bb2023-01-11 09:46:29 +08009592
developer2202b332023-05-24 16:23:22 +08009593 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
9594 printf("Nla put attribute error\n");
9595 nlmsg_free(msg);
9596 goto err;
9597 }
9598
9599 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9600 if (ret) {
9601 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9602 goto err;
9603 }
9604 mtk_nl80211_deint(&unl_ins);
9605 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
9606
9607 /*step 4. mwctl dev %s set vlan_en 0*/
9608 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9609 if (ret) {
9610 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9611 return RETURN_ERR;
9612 }
9613
9614 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
9615 printf("Nla put attribute error\n");
9616 nlmsg_free(msg);
9617 goto err;
9618 }
9619
9620 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9621 if (ret) {
9622 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9623 goto err;
9624 }
9625 mtk_nl80211_deint(&unl_ins);
9626 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
9627
9628 /*step 5. mwctl dev %s set vlan_policy 0:4*/
9629 vlan_param.direction = 0;
9630 vlan_param.policy = 4;
9631 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9632 if (ret) {
9633 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9634 return RETURN_ERR;
9635 }
9636 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
9637 printf("Nla put attribute error\n");
9638 nlmsg_free(msg);
9639 goto err;
9640 }
9641
9642 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9643 if (ret) {
9644 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9645 goto err;
9646 }
9647 mtk_nl80211_deint(&unl_ins);
9648 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
9649
9650 /*step 6. mwctl dev %s set vlan_policy 1:0*/
9651 vlan_param.direction = 1;
9652 vlan_param.policy = 0;
9653 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9654 if (ret) {
9655 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9656 return RETURN_ERR;
9657 }
9658
9659 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
9660 printf("Nla put attribute error\n");
9661 nlmsg_free(msg);
9662 goto err;
9663 }
9664
9665 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9666 if (ret) {
9667 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9668 goto err;
9669 }
9670 /*deinit mtk nl80211 vendor msg*/
9671 mtk_nl80211_deint(&unl_ins);
9672 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
9673
9674 /*TODO need to modify VLAN config in dat file*/
9675 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9676
9677 return RETURN_OK;
9678err:
9679 mtk_nl80211_deint(&unl_ins);
9680 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9681 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009682}
9683
9684// 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.
9685INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
9686{
developera3511852023-06-14 14:12:59 +08009687 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009688}
9689
9690// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
9691INT wifi_startHostApd()
9692{
developera3511852023-06-14 14:12:59 +08009693 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9694 system("systemctl start hostapd.service");
9695 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9696 return RETURN_OK;
9697 //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 +08009698}
9699
9700// stops hostapd
developer69b61b02023-03-07 17:17:44 +08009701INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08009702{
developera3511852023-06-14 14:12:59 +08009703 char cmd[128] = {0};
9704 char buf[128] = {0};
developer75bd10c2023-06-27 11:34:08 +08009705 int res;
developer72fb0bb2023-01-11 09:46:29 +08009706
developer75bd10c2023-06-27 11:34:08 +08009707 res = snprintf(cmd, sizeof(cmd), "systemctl stop hostapd");
9708 if (os_snprintf_error(sizeof(cmd), res)) {
9709 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9710 return RETURN_ERR;
9711 }
developera3511852023-06-14 14:12:59 +08009712 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009713
developera3511852023-06-14 14:12:59 +08009714 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009715}
9716
9717// restart hostapd dummy function
9718INT wifi_restartHostApd()
9719{
developera3511852023-06-14 14:12:59 +08009720 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9721 system("systemctl restart hostapd-global");
9722 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009723
developera3511852023-06-14 14:12:59 +08009724 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009725}
9726
9727// sets the AP enable status variable for the specified ap.
9728INT wifi_setApEnable(INT apIndex, BOOL enable)
9729{
developer7e4a2a62023-04-06 19:56:03 +08009730 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +08009731 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +08009732 char cmd[MAX_CMD_SIZE] = {0};
9733 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08009734 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08009735 int max_radio_num = 0;
9736 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08009737 int res;
developer72fb0bb2023-01-11 09:46:29 +08009738
developer7e4a2a62023-04-06 19:56:03 +08009739 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08009740
developer7e4a2a62023-04-06 19:56:03 +08009741 wifi_getMaxRadioNumber(&max_radio_num);
9742 if (enable == status)
9743 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009744
developer7e4a2a62023-04-06 19:56:03 +08009745 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9746 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009747
developer7e4a2a62023-04-06 19:56:03 +08009748 if (enable == TRUE) {
9749 int radioIndex = apIndex % max_radio_num;
9750 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08009751 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
9752 if (os_snprintf_error(sizeof(cmd), res)) {
9753 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9754 return RETURN_ERR;
9755 }
developerf3c7d292023-05-29 17:57:16 +08009756 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08009757
developere40952c2023-06-15 18:46:43 +08009758 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
9759 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
9760 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9761 return RETURN_ERR;
9762 }
9763 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
9764 if (os_snprintf_error(sizeof(cmd), res)) {
9765 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9766 return RETURN_ERR;
9767 }
developer7e4a2a62023-04-06 19:56:03 +08009768 _syscmd(cmd, buf, sizeof(buf));
9769 } else {
developere40952c2023-06-15 18:46:43 +08009770 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
9771 if (os_snprintf_error(sizeof(cmd), res)) {
9772 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9773 return RETURN_ERR;
9774 }
developer7e4a2a62023-04-06 19:56:03 +08009775 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08009776 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
9777 if (os_snprintf_error(sizeof(cmd), res)) {
9778 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9779 return RETURN_ERR;
9780 }
developerf3c7d292023-05-29 17:57:16 +08009781 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +08009782 }
developere40952c2023-06-15 18:46:43 +08009783 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer7e4a2a62023-04-06 19:56:03 +08009784 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +08009785 if (os_snprintf_error(sizeof(cmd), res)) {
9786 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9787 return RETURN_ERR;
9788 }
developer7e4a2a62023-04-06 19:56:03 +08009789 _syscmd(cmd, buf, sizeof(buf));
9790 //Wait for wifi up/down to apply
9791 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009792}
9793
9794// Outputs the setting of the internal variable that is set by wifi_setApEnable().
9795INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
9796{
developer7e4a2a62023-04-06 19:56:03 +08009797 char interface_name[IF_NAME_SIZE] = {0};
9798 char cmd[MAX_CMD_SIZE] = {0};
developerc1aa6532023-06-09 09:37:01 +08009799 char buf[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08009800 int res;
developer72fb0bb2023-01-11 09:46:29 +08009801
developer7e4a2a62023-04-06 19:56:03 +08009802 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
9803 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009804
developer7e4a2a62023-04-06 19:56:03 +08009805 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08009806
developer7e4a2a62023-04-06 19:56:03 +08009807 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
9808 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
9809 *output_bool = FALSE;
9810 return RETURN_OK;
9811 }
developerc1aa6532023-06-09 09:37:01 +08009812
developer75bd10c2023-06-27 11:34:08 +08009813 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
9814 if (os_snprintf_error(sizeof(cmd), res)) {
9815 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9816 return RETURN_ERR;
9817 }
developerc1aa6532023-06-09 09:37:01 +08009818 _syscmd(cmd, buf, sizeof(buf));
9819
9820 if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 ||
9821 strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) {
9822 *output_bool = TRUE;
9823 }
developer7e4a2a62023-04-06 19:56:03 +08009824 }
developer72fb0bb2023-01-11 09:46:29 +08009825
developer7e4a2a62023-04-06 19:56:03 +08009826 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009827}
9828
developer69b61b02023-03-07 17:17:44 +08009829// Outputs the AP "Enabled" "Disabled" status from driver
9830INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08009831{
developer9ce44382023-06-28 11:09:37 +08009832 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +08009833 int res;
developer72fb0bb2023-01-11 09:46:29 +08009834
developer7e4a2a62023-04-06 19:56:03 +08009835 if (!output_string) {
9836 printf("%s: null pointer!", __func__);
9837 return RETURN_ERR;
9838 }
developer72fb0bb2023-01-11 09:46:29 +08009839
developer7e4a2a62023-04-06 19:56:03 +08009840 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08009841
developer7e4a2a62023-04-06 19:56:03 +08009842 if(output_bool == 1)
developere40952c2023-06-15 18:46:43 +08009843 res = snprintf(output_string, 32, "Up");
developer7e4a2a62023-04-06 19:56:03 +08009844 else
developere40952c2023-06-15 18:46:43 +08009845 res = snprintf(output_string, 32, "Disable");
9846 if (os_snprintf_error(32, res)) {
9847 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9848 return RETURN_ERR;
9849 }
developer7e4a2a62023-04-06 19:56:03 +08009850
9851 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009852}
9853
9854//Indicates whether or not beacons include the SSID name.
9855// outputs a 1 if SSID on the AP is enabled, else outputs 0
9856INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
9857{
developera3511852023-06-14 14:12:59 +08009858 //get the running status
9859 char config_file[MAX_BUF_SIZE] = {0};
9860 char buf[16] = {0};
developer75bd10c2023-06-27 11:34:08 +08009861 int res;
developer72fb0bb2023-01-11 09:46:29 +08009862
developera3511852023-06-14 14:12:59 +08009863 if (!output)
9864 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009865
developer32f2a182023-06-27 19:50:41 +08009866 res = snprintf(config_file, sizeof(config_file),
9867 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +08009868 if (os_snprintf_error(sizeof(config_file), res)) {
9869 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9870 return RETURN_ERR;
9871 }
developera3511852023-06-14 14:12:59 +08009872 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
9873 // default is enable
9874 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
9875 *output = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08009876
developera3511852023-06-14 14:12:59 +08009877 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009878}
9879
9880// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
9881INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
9882{
developera3511852023-06-14 14:12:59 +08009883 //store the config, apply instantly
9884 char config_file[MAX_BUF_SIZE] = {0};
9885 struct params list;
developer75bd10c2023-06-27 11:34:08 +08009886 int res;
developer72fb0bb2023-01-11 09:46:29 +08009887
developera3511852023-06-14 14:12:59 +08009888 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9889 list.name = "ignore_broadcast_ssid";
9890 list.value = enable?"0":"1";
developer72fb0bb2023-01-11 09:46:29 +08009891
developer32f2a182023-06-27 19:50:41 +08009892 res = snprintf(config_file, sizeof(config_file),
9893 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +08009894 if (os_snprintf_error(sizeof(config_file), res)) {
9895 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9896 return RETURN_ERR;
9897 }
developera3511852023-06-14 14:12:59 +08009898 wifi_hostapdWrite(config_file, &list, 1);
9899 wifi_hostapdProcessUpdate(apIndex, &list, 1);
9900 //TODO: call hostapd_cli for dynamic_config_control
9901 wifi_reloadAp(apIndex);
9902 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009903
developera3511852023-06-14 14:12:59 +08009904 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009905}
9906
9907//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
9908INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
9909{
developer47cc27a2023-05-17 23:09:58 +08009910 /* get the running status */
9911 if(!output_uint)
developera3511852023-06-14 14:12:59 +08009912 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08009913
9914 *output_uint = 15;
9915 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009916}
9917
developer47cc27a2023-05-17 23:09:58 +08009918/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +08009919INT wifi_setApRetryLimit(INT apIndex, UINT number)
9920{
developer47cc27a2023-05-17 23:09:58 +08009921 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009922}
9923
developer95c045d2023-05-24 19:26:28 +08009924int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
9925{
9926 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9927 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
9928 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developer2f79c922023-06-02 17:33:42 +08009929 unsigned char *status = (unsigned char *)data;
developer95c045d2023-05-24 19:26:28 +08009930 int err = 0;
developer95c045d2023-05-24 19:26:28 +08009931
9932 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9933 genlmsg_attrlen(gnlh, 0), NULL);
9934 if (err < 0)
9935 return err;
9936
9937 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9938 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
9939 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9940 if (err < 0)
9941 return err;
9942
9943 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
developer95c045d2023-05-24 19:26:28 +08009944 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
9945 }
9946 }
9947
9948 return 0;
9949}
9950
developer72fb0bb2023-01-11 09:46:29 +08009951//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
9952INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
9953{
developer95c045d2023-05-24 19:26:28 +08009954 int if_idx, ret = 0;
developera3511852023-06-14 14:12:59 +08009955 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08009956 unsigned char status = 0;
9957 struct nl_msg *msg = NULL;
9958 struct nlattr * msg_data = NULL;
9959 struct mtk_nl80211_param param;
9960 struct unl unl_ins;
developer8e6583c2023-05-23 13:36:06 +08009961
developera3511852023-06-14 14:12:59 +08009962 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9963 if(!output)
developerdaf24792023-06-06 11:40:04 +08009964 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08009965
developer95c045d2023-05-24 19:26:28 +08009966 if (apIndex > MAX_APS) {
9967 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9968 return RETURN_ERR;
9969 }
9970
developera3511852023-06-14 14:12:59 +08009971 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developerdaf24792023-06-06 11:40:04 +08009972 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +08009973
9974 if_idx = if_nametoindex(interface_name);
9975 /*init mtk nl80211 vendor cmd*/
9976 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
9977 param.if_type = NL80211_ATTR_IFINDEX;
9978 param.if_idx = if_idx;
9979 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9980
9981 if (ret) {
9982 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9983 return RETURN_ERR;
9984 }
9985
9986 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
9987 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9988 nlmsg_free(msg);
9989 goto err;
9990 }
9991
9992 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
9993 (void *)&status);
9994 if (ret) {
9995 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9996 goto err;
9997 }
9998 mtk_nl80211_deint(&unl_ins);
9999
10000 *output = status == 0 ? FALSE : TRUE;
10001 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +080010002
developera3511852023-06-14 14:12:59 +080010003 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10004 return RETURN_OK;
10005err:
developer95c045d2023-05-24 19:26:28 +080010006 mtk_nl80211_deint(&unl_ins);
10007 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
10008 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010009}
10010
10011//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
10012INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
10013{
developera3511852023-06-14 14:12:59 +080010014 //get the running status from driver
10015 char cmd[128] = {0};
10016 char buf[128] = {0};
10017 int max_radio_num = 0, radioIndex = 0;
10018 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080010019 int res;
developer72fb0bb2023-01-11 09:46:29 +080010020
developera3511852023-06-14 14:12:59 +080010021 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010022
developera3511852023-06-14 14:12:59 +080010023 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080010024 if(max_radio_num == 0){
10025 return RETURN_ERR;
10026 }
developera3511852023-06-14 14:12:59 +080010027 radioIndex = apIndex % max_radio_num;
10028 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +080010029 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
10030 if (os_snprintf_error(sizeof(cmd), res)) {
10031 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10032 return RETURN_ERR;
10033 }
developera3511852023-06-14 14:12:59 +080010034 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010035
developera3511852023-06-14 14:12:59 +080010036 if (strlen(buf) > 0)
10037 *output = true;
developer72fb0bb2023-01-11 09:46:29 +080010038
developera3511852023-06-14 14:12:59 +080010039 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010040
developera3511852023-06-14 14:12:59 +080010041 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010042}
10043
10044//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
10045INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
10046{
developera3511852023-06-14 14:12:59 +080010047 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +080010048}
10049
10050// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
10051INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
10052{
developer95c045d2023-05-24 19:26:28 +080010053 int if_idx, ret = 0;
10054 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080010055 struct nl_msg *msg = NULL;
10056 struct nlattr * msg_data = NULL;
10057 struct mtk_nl80211_param param;
10058 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +080010059
developer95c045d2023-05-24 19:26:28 +080010060 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010061
developer95c045d2023-05-24 19:26:28 +080010062 if (apIndex > MAX_APS) {
10063 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
10064 return RETURN_ERR;
10065 }
developer72fb0bb2023-01-11 09:46:29 +080010066
developer95c045d2023-05-24 19:26:28 +080010067 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10068 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080010069
developer95c045d2023-05-24 19:26:28 +080010070 if_idx = if_nametoindex(interface_name);
10071 /*init mtk nl80211 vendor cmd*/
10072 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
10073 param.if_type = NL80211_ATTR_IFINDEX;
10074 param.if_idx = if_idx;
10075 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10076
10077 if (ret) {
10078 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10079 return RETURN_ERR;
10080 }
10081
10082 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
10083 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
10084 nlmsg_free(msg);
10085 goto err;
10086 }
10087
10088 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
10089 if (ret) {
10090 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
10091 goto err;
10092 }
10093 mtk_nl80211_deint(&unl_ins);
10094
10095 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10096 return RETURN_OK;
10097err:
10098 mtk_nl80211_deint(&unl_ins);
10099 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
10100 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010101}
10102
developer95c045d2023-05-24 19:26:28 +080010103
developer72fb0bb2023-01-11 09:46:29 +080010104//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.
10105INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
10106{
developer75bd10c2023-06-27 11:34:08 +080010107 int res;
10108
developera3511852023-06-14 14:12:59 +080010109 //get the running status from driver
10110 if(!output)
10111 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010112
developera3511852023-06-14 14:12:59 +080010113 char config_file[128] = {0};
10114 char buf[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010115
developer75bd10c2023-06-27 11:34:08 +080010116 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10117 if (os_snprintf_error(sizeof(config_file), res)) {
10118 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10119 return RETURN_ERR;
10120 }
developera3511852023-06-14 14:12:59 +080010121 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
10122 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
10123 *output = TRUE;
10124 else
10125 *output = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010126
developera3511852023-06-14 14:12:59 +080010127 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010128}
10129
10130// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
10131INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
10132{
developera3511852023-06-14 14:12:59 +080010133 //save config and apply instantly.
10134 char config_file[MAX_BUF_SIZE] = {0};
10135 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010136 int res;
developer72fb0bb2023-01-11 09:46:29 +080010137
developera3511852023-06-14 14:12:59 +080010138 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10139 list.name = "uapsd_advertisement_enabled";
10140 list.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080010141
developer75bd10c2023-06-27 11:34:08 +080010142 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10143 if (os_snprintf_error(sizeof(config_file), res)) {
10144 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10145 return RETURN_ERR;
10146 }
developera3511852023-06-14 14:12:59 +080010147 wifi_hostapdWrite(config_file, &list, 1);
10148 wifi_hostapdProcessUpdate(apIndex, &list, 1);
10149 wifi_quick_reload_ap(apIndex);
10150 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010151
developera3511852023-06-14 14:12:59 +080010152 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010153}
10154
10155// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
10156INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
10157{
developera3511852023-06-14 14:12:59 +080010158 char interface_name[16] = {0};
10159 // assume class 0->BE, 1->BK, 2->VI, 3->VO
10160 char cmd[MAX_CMD_SIZE] = {0};
10161 char buf[128] = {0};
10162 char ack_filepath[128] = {0};
10163 uint16_t bitmap = 0;
10164 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
10165 FILE *f = NULL;
developere40952c2023-06-15 18:46:43 +080010166 int res;
developer72fb0bb2023-01-11 09:46:29 +080010167
developera3511852023-06-14 14:12:59 +080010168 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010169
developera3511852023-06-14 14:12:59 +080010170 // Get current setting
developere40952c2023-06-15 18:46:43 +080010171 res = snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
10172 if (os_snprintf_error(sizeof(ack_filepath), res)) {
10173 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10174 return RETURN_ERR;
10175 }
10176 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
10177 if (os_snprintf_error(sizeof(cmd), res)) {
10178 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10179 return RETURN_ERR;
10180 }
developera3511852023-06-14 14:12:59 +080010181 _syscmd(cmd, buf, sizeof(buf));
10182 if (strlen(buf) > 0)
10183 bitmap = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080010184
developer9ce44382023-06-28 11:09:37 +080010185 //bitmap = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080010186
developera3511852023-06-14 14:12:59 +080010187 if (ackPolicy == TRUE) { // True, unset this class
10188 bitmap &= ~class_map[class];
10189 } else { // False, set this class
10190 bitmap |= class_map[class];
10191 }
developer72fb0bb2023-01-11 09:46:29 +080010192
developera3511852023-06-14 14:12:59 +080010193 f = fopen(ack_filepath, "w");
10194 if (f == NULL) {
10195 fprintf(stderr, "%s: fopen failed\n", __func__);
10196 return RETURN_ERR;
10197 }
10198 fprintf(f, "%hu", bitmap);
10199 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080010200
developera3511852023-06-14 14:12:59 +080010201 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10202 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010203 res = snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
10204 if (os_snprintf_error(sizeof(cmd), res)) {
10205 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10206 return RETURN_ERR;
10207 }
developera3511852023-06-14 14:12:59 +080010208 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010209
developera3511852023-06-14 14:12:59 +080010210 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10211 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010212}
10213
10214//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.
10215INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
10216{
developer75bd10c2023-06-27 11:34:08 +080010217 int res;
10218
developera3511852023-06-14 14:12:59 +080010219 //get the running status from driver
10220 if(!output_uint)
10221 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010222
developera3511852023-06-14 14:12:59 +080010223 char output[16]={'\0'};
10224 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010225
developer75bd10c2023-06-27 11:34:08 +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, "max_num_sta", output, sizeof(output));
10232 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
10233 else {
10234 int device_num = atoi(output);
10235 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
10236 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
10237 return RETURN_ERR;
10238 }
10239 else {
10240 *output_uint = device_num;
10241 }
10242 }
developer72fb0bb2023-01-11 09:46:29 +080010243
developera3511852023-06-14 14:12:59 +080010244 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010245}
10246
10247INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
10248{
developera3511852023-06-14 14:12:59 +080010249 //store to wifi config, apply instantly
10250 char str[MAX_BUF_SIZE]={'\0'};
10251 struct params params;
10252 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080010253 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080010254
developera3511852023-06-14 14:12:59 +080010255 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10256 if (number > MAX_ASSOCIATED_STA_NUM) {
10257 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
10258 return RETURN_ERR;
10259 }
developer75bd10c2023-06-27 11:34:08 +080010260 res = snprintf(str, sizeof(str), "%d", number);
10261 if (os_snprintf_error(sizeof(str), res)) {
10262 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10263 return RETURN_ERR;
10264 }
developera3511852023-06-14 14:12:59 +080010265 params.name = "max_num_sta";
10266 params.value = str;
developer72fb0bb2023-01-11 09:46:29 +080010267
developer32f2a182023-06-27 19:50:41 +080010268 res = snprintf(config_file,
10269 sizeof(config_file), "%s%d.conf",CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010270 if (os_snprintf_error(sizeof(config_file), res)) {
10271 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10272 return RETURN_ERR;
10273 }
developer32f2a182023-06-27 19:50:41 +080010274 ret = wifi_hostapdWrite(config_file, &params, 1);
developera3511852023-06-14 14:12:59 +080010275 if (ret) {
10276 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
10277 ,__func__, ret);
10278 }
developer72fb0bb2023-01-11 09:46:29 +080010279
developera3511852023-06-14 14:12:59 +080010280 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
10281 if (ret) {
10282 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
10283 ,__func__, ret);
10284 }
10285 wifi_reloadAp(apIndex);
10286 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010287
developera3511852023-06-14 14:12:59 +080010288 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010289}
10290
10291//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.
10292INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
10293{
developera3511852023-06-14 14:12:59 +080010294 //get the current threshold
10295 if(!output_uint)
10296 return RETURN_ERR;
10297 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
10298 if (*output_uint == 0)
10299 *output_uint = 50;
10300 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010301}
10302
10303INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
10304{
developera3511852023-06-14 14:12:59 +080010305 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
10306 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
10307 return RETURN_OK;
10308 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010309}
10310
10311//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.
10312INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
10313{
developera3511852023-06-14 14:12:59 +080010314 if(!output_uint)
10315 return RETURN_ERR;
10316 *output_uint = 3;
10317 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010318}
10319
10320//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
10321INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
10322{
developera3511852023-06-14 14:12:59 +080010323 if(!output_uint)
10324 return RETURN_ERR;
10325 *output_uint = 3;
10326 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010327}
10328
10329//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.
10330INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
10331{
developera3511852023-06-14 14:12:59 +080010332 if(!output_in_seconds)
10333 return RETURN_ERR;
10334 *output_in_seconds = 0;
10335 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010336}
10337
10338//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
10339INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
10340{
developere40952c2023-06-15 18:46:43 +080010341 int res;
10342
developera3511852023-06-14 14:12:59 +080010343 if(!output || apIndex>=MAX_APS)
10344 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010345 //res = snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
10346 res = snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
10347 if (os_snprintf_error(128, res)) {
10348 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10349 return RETURN_ERR;
10350 }
developera3511852023-06-14 14:12:59 +080010351 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080010352}
developer72fb0bb2023-01-11 09:46:29 +080010353
10354//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
10355INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
10356{
developera3511852023-06-14 14:12:59 +080010357 char config_file[128] = {0};
10358 char wpa[16] = {0};
10359 char key_mgmt[64] = {0};
developer9ce44382023-06-28 11:09:37 +080010360 int res = -1;
developere40952c2023-06-15 18:46:43 +080010361
developera3511852023-06-14 14:12:59 +080010362 if (!output)
10363 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010364
developer75bd10c2023-06-27 11:34:08 +080010365 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10366 if (os_snprintf_error(sizeof(config_file), res)) {
10367 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10368 return RETURN_ERR;
10369 }
developera3511852023-06-14 14:12:59 +080010370 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
developer72fb0bb2023-01-11 09:46:29 +080010371
developer32f2a182023-06-27 19:50:41 +080010372 memcpy(output, "None", 4);//Copying "None" to output string for default case
10373 output[4] = '\0';
developera3511852023-06-14 14:12:59 +080010374 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
10375 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
10376 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080010377 res = snprintf(output, 32, "WPA-Personal");
developera3511852023-06-14 14:12:59 +080010378 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080010379 res = snprintf(output, 32, "WPA2-Personal");
developera3511852023-06-14 14:12:59 +080010380 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080010381 res = snprintf(output, 32, "WPA-WPA2-Personal");
developer72fb0bb2023-01-11 09:46:29 +080010382
developera3511852023-06-14 14:12:59 +080010383 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
developere40952c2023-06-15 18:46:43 +080010384 res = snprintf(output, 32, "WPA3-Enterprise");
developera3511852023-06-14 14:12:59 +080010385 } else if (strstr(key_mgmt, "WPA-EAP")) {
10386 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080010387 res = snprintf(output, 32, "WPA-Enterprise");
developera3511852023-06-14 14:12:59 +080010388 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080010389 res = snprintf(output, 32, "WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080010390 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080010391 res = snprintf(output, 32, "WPA-WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080010392 } else if (strstr(key_mgmt, "SAE")) {
10393 if (strstr(key_mgmt, "WPA-PSK") == NULL)
developere40952c2023-06-15 18:46:43 +080010394 res = snprintf(output, 32, "WPA3-Personal");
developera3511852023-06-14 14:12:59 +080010395 else
developere40952c2023-06-15 18:46:43 +080010396 res = snprintf(output, 32, "WPA3-Personal-Transition");
10397 }
10398 if (os_snprintf_error(32, res)) {
10399 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10400 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080010401 }
developer72fb0bb2023-01-11 09:46:29 +080010402
developera3511852023-06-14 14:12:59 +080010403 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
10404 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010405}
developer69b61b02023-03-07 17:17:44 +080010406
developer72fb0bb2023-01-11 09:46:29 +080010407INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
10408{
developer32f2a182023-06-27 19:50:41 +080010409 char securityType[32] = {0};
10410 char authMode[32] = {0};
10411 unsigned long len_sec, len_auth;
developera3511852023-06-14 14:12:59 +080010412 //store settings and wait for wifi up to apply
10413 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10414 if(!encMode)
10415 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010416
developera3511852023-06-14 14:12:59 +080010417 if (strcmp(encMode, "None")==0)
10418 {
developer32f2a182023-06-27 19:50:41 +080010419 len_sec = strlen("None");
10420 len_auth = strlen("None");
10421 memcpy(securityType, "None", len_sec);
10422 memcpy(authMode, "None", len_auth);
10423 } else if (strcmp(encMode, "WPA-WPA2-Personal")==0) {
10424 len_sec = strlen("WPAand11i");
10425 memcpy(securityType, "WPAand11i", len_sec);
10426 len_auth = strlen("PSKAuthentication");
10427 memcpy(authMode, "PSKAuthentication", len_auth);
10428 } else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) {
10429 len_sec = strlen("WPAand11i");
10430 memcpy(securityType, "WPAand11i", len_sec);
10431 len_auth = strlen("EAPAuthentication");
10432 memcpy(authMode, "EAPAuthentication", len_auth);
10433 } else if (strcmp(encMode, "WPA-Personal")==0) {
10434 len_sec = strlen("WPA");
10435 memcpy(securityType, "WPA", len_sec);
10436 len_auth = strlen("PSKAuthentication");
10437 memcpy(authMode, "PSKAuthentication", len_auth);
10438 } else if (strcmp(encMode, "WPA-Enterprise")==0) {
10439 len_sec = strlen("WPA");
10440 memcpy(securityType, "WPA", len_sec);
10441 len_auth = strlen("EAPAuthentication");
10442 memcpy(authMode, "EAPAuthentication", len_auth);
10443 } else if (strcmp(encMode, "WPA2-Personal")==0) {
10444 len_sec = strlen("11i");
10445 memcpy(securityType, "11i", len_sec);
10446 len_auth = strlen("PSKAuthentication");
10447 memcpy(authMode, "PSKAuthentication", len_auth);
10448 } else if (strcmp(encMode, "WPA2-Enterprise")==0) {
10449 len_sec = strlen("11i");
10450 memcpy(securityType, "11i", len_sec);
10451 len_auth = strlen("EAPAuthentication");
10452 memcpy(authMode, "EAPAuthentication", len_auth);
10453 } else if (strcmp(encMode, "WPA3-Personal") == 0) {
10454 len_sec = strlen("11i");
10455 memcpy(securityType, "11i", len_sec);
10456 len_auth = strlen("SAEAuthentication");
10457 memcpy(authMode, "SAEAuthentication", len_auth);
10458 } else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) {
10459 len_sec = strlen("11i");
10460 memcpy(securityType, "11i", len_sec);
10461 len_auth = strlen("PSK-SAEAuthentication");
10462 memcpy(authMode, "PSK-SAEAuthentication", len_auth);
10463 } else if (strcmp(encMode, "WPA3-Enterprise") == 0) {
10464 len_sec = strlen("11i");
10465 memcpy(securityType, "11i", len_sec);
10466 len_auth = strlen("EAP_192-bit_Authentication");
10467 memcpy(authMode, "EAP_192-bit_Authentication", len_auth);
10468 } else if (strcmp(encMode, "OWE") == 0) {
10469 len_sec = strlen("11i");
10470 memcpy(securityType, "11i", len_sec);
10471 len_auth = strlen("Enhanced_Open");
10472 memcpy(authMode, "Enhanced_Open", len_auth);
10473 } else {
10474 len_sec = strlen("None");
10475 memcpy(securityType, "None", len_sec);
10476 len_auth = strlen("None");
10477 memcpy(authMode, "None", len_auth);
developera3511852023-06-14 14:12:59 +080010478 }
developer32f2a182023-06-27 19:50:41 +080010479 securityType[len_sec] = '\0';
10480 authMode[len_auth] = '\0';
developera3511852023-06-14 14:12:59 +080010481 wifi_setApBeaconType(apIndex, securityType);
10482 wifi_setApBasicAuthenticationMode(apIndex, authMode);
10483 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010484
developera3511852023-06-14 14:12:59 +080010485 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080010486}
developer72fb0bb2023-01-11 09:46:29 +080010487
10488
10489//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
10490// output_string must be pre-allocated as 64 character string by caller
10491// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
10492INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
10493{
developera3511852023-06-14 14:12:59 +080010494 char buf[16] = {0};
10495 char config_file[MAX_BUF_SIZE] = {0};
10496 int res;
developer72fb0bb2023-01-11 09:46:29 +080010497
developera3511852023-06-14 14:12:59 +080010498 if(output_string==NULL)
10499 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010500
developera3511852023-06-14 14:12:59 +080010501 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10502 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010503 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10504 return RETURN_ERR;
10505 }
developera3511852023-06-14 14:12:59 +080010506 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010507
developera3511852023-06-14 14:12:59 +080010508 if(strcmp(buf,"0")==0)
10509 {
10510 printf("wpa_mode is %s ......... \n",buf);
10511 return RETURN_ERR;
10512 }
developer72fb0bb2023-01-11 09:46:29 +080010513
developera3511852023-06-14 14:12:59 +080010514 wifi_dbg_printf("\nFunc=%s\n",__func__);
10515 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10516 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010517 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10518 return RETURN_ERR;
10519 }
developere5750452023-05-15 16:46:42 +080010520 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developera3511852023-06-14 14:12:59 +080010521 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080010522
developera3511852023-06-14 14:12:59 +080010523 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010524}
10525
10526// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
10527// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
10528INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
10529{
developera3511852023-06-14 14:12:59 +080010530 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
10531 struct params params={'\0'};
developer32f2a182023-06-27 19:50:41 +080010532 int ret;
developera3511852023-06-14 14:12:59 +080010533 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010534
developera3511852023-06-14 14:12:59 +080010535 if(NULL == preSharedKey)
10536 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010537
developera3511852023-06-14 14:12:59 +080010538 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +080010539
developera3511852023-06-14 14:12:59 +080010540 if(strlen(preSharedKey) != 64)
10541 {
10542 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
10543 return RETURN_ERR;
10544 }
10545 params.value = preSharedKey;
developer32f2a182023-06-27 19:50:41 +080010546 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10547 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080010548 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10549 return RETURN_ERR;
10550 }
developera3511852023-06-14 14:12:59 +080010551 ret = wifi_hostapdWrite(config_file, &params, 1);
10552 if(!ret) {
10553 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
10554 wifi_reloadAp(apIndex);
10555 }
10556 return ret;
10557 //TODO: call hostapd_cli for dynamic_config_control
developer72fb0bb2023-01-11 09:46:29 +080010558}
10559
10560//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
10561// outputs the passphrase, maximum 63 characters
10562INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
10563{
developera3511852023-06-14 14:12:59 +080010564 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
developer75bd10c2023-06-27 11:34:08 +080010565 int res;
developer72fb0bb2023-01-11 09:46:29 +080010566
developera3511852023-06-14 14:12:59 +080010567 wifi_dbg_printf("\nFunc=%s\n",__func__);
10568 if (NULL == output_string)
10569 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010570
developer75bd10c2023-06-27 11:34:08 +080010571 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10572 if (os_snprintf_error(sizeof(config_file), res)) {
10573 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10574 return RETURN_ERR;
10575 }
10576
developera3511852023-06-14 14:12:59 +080010577 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
10578 if(strcmp(buf,"0")==0)
10579 {
10580 printf("wpa_mode is %s ......... \n",buf);
10581 return RETURN_ERR;
10582 }
developer72fb0bb2023-01-11 09:46:29 +080010583
developera3511852023-06-14 14:12:59 +080010584 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
10585 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080010586
developera3511852023-06-14 14:12:59 +080010587 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010588}
10589
10590// sets the passphrase enviornment variable, max 63 characters
10591INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
10592{
developera3511852023-06-14 14:12:59 +080010593 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
10594 struct params params={'\0'};
10595 char config_file[MAX_BUF_SIZE] = {0};
10596 int ret;
developer72fb0bb2023-01-11 09:46:29 +080010597
developera3511852023-06-14 14:12:59 +080010598 if(NULL == passPhrase)
10599 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010600
developera3511852023-06-14 14:12:59 +080010601 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
10602 {
10603 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
10604 return RETURN_ERR;
10605 }
10606 params.name = "wpa_passphrase";
10607 params.value = passPhrase;
developer32f2a182023-06-27 19:50:41 +080010608 ret = snprintf(config_file, sizeof(config_file),
10609 "%s%d.conf", CONFIG_PREFIX, apIndex);
10610 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080010611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10612 return RETURN_ERR;
10613 }
developera3511852023-06-14 14:12:59 +080010614 ret=wifi_hostapdWrite(config_file,&params,1);
10615 if(!ret) {
10616 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +080010617 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +080010618 }
developer72fb0bb2023-01-11 09:46:29 +080010619
developera3511852023-06-14 14:12:59 +080010620 return ret;
developer72fb0bb2023-01-11 09:46:29 +080010621}
10622
10623//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.
10624INT wifi_setApSecurityReset(INT apIndex)
10625{
developera3511852023-06-14 14:12:59 +080010626 char original_config_file[64] = {0};
10627 char current_config_file[64] = {0};
10628 char buf[64] = {0};
10629 char cmd[64] = {0};
10630 char wpa[4] = {0};
10631 char wpa_psk[64] = {0};
10632 char wpa_passphrase[64] = {0};
10633 char wpa_psk_file[128] = {0};
10634 char wpa_key_mgmt[64] = {0};
10635 char wpa_pairwise[32] = {0};
10636 wifi_band band;
10637 struct params list[6];
developere40952c2023-06-15 18:46:43 +080010638 int res;
developer72fb0bb2023-01-11 09:46:29 +080010639
developera3511852023-06-14 14:12:59 +080010640 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010641
developera3511852023-06-14 14:12:59 +080010642 band = wifi_index_to_band(apIndex);
10643 if (band == band_2_4)
10644 sprintf(original_config_file, "/etc/hostapd-2G.conf");
10645 else if (band == band_5)
10646 sprintf(original_config_file, "/etc/hostapd-5G.conf");
10647 else if (band == band_6)
10648 sprintf(original_config_file, "/etc/hostapd-6G.conf");
10649 else
10650 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010651
developera3511852023-06-14 14:12:59 +080010652 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
10653 list[0].name = "wpa";
10654 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +080010655
developera3511852023-06-14 14:12:59 +080010656 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
10657 list[1].name = "wpa_psk";
10658 list[1].value = wpa_psk;
developer72fb0bb2023-01-11 09:46:29 +080010659
developera3511852023-06-14 14:12:59 +080010660 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
10661 list[2].name = "wpa_passphrase";
10662 list[2].value = wpa_passphrase;
developer72fb0bb2023-01-11 09:46:29 +080010663
developera3511852023-06-14 14:12:59 +080010664 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
developer72fb0bb2023-01-11 09:46:29 +080010665
developera3511852023-06-14 14:12:59 +080010666 if (strlen(wpa_psk_file) == 0)
developer32f2a182023-06-27 19:50:41 +080010667 memcpy(wpa_psk_file, PSK_FILE, strlen(PSK_FILE));
developer72fb0bb2023-01-11 09:46:29 +080010668
developera3511852023-06-14 14:12:59 +080010669 if (access(wpa_psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +080010670 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", wpa_psk_file);
10671 if (os_snprintf_error(sizeof(cmd), res)) {
10672 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10673 return RETURN_ERR;
10674 }
developera3511852023-06-14 14:12:59 +080010675 _syscmd(cmd, buf, sizeof(buf));
10676 }
10677 list[3].name = "wpa_psk_file";
10678 list[3].value = wpa_psk_file;
developer72fb0bb2023-01-11 09:46:29 +080010679
developera3511852023-06-14 14:12:59 +080010680 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
10681 list[4].name = "wpa_key_mgmt";
10682 list[4].value = wpa_key_mgmt;
developer72fb0bb2023-01-11 09:46:29 +080010683
developera3511852023-06-14 14:12:59 +080010684 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
10685 list[5].name = "wpa_pairwise";
10686 list[5].value = wpa_pairwise;
developer72fb0bb2023-01-11 09:46:29 +080010687
developer32f2a182023-06-27 19:50:41 +080010688 res = snprintf(current_config_file, sizeof(current_config_file),
10689 "%s%d.conf", CONFIG_PREFIX, apIndex);
10690 if (os_snprintf_error(sizeof(current_config_file), res)) {
10691 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10692 return RETURN_ERR;
10693 }
developera3511852023-06-14 14:12:59 +080010694 wifi_hostapdWrite(current_config_file, list, 6);
developer72fb0bb2023-01-11 09:46:29 +080010695
developera3511852023-06-14 14:12:59 +080010696 wifi_setApEnable(apIndex, FALSE);
10697 wifi_setApEnable(apIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +080010698
developera3511852023-06-14 14:12:59 +080010699 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10700 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010701}
10702
10703//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).
10704INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
10705{
developera3511852023-06-14 14:12:59 +080010706 char config_file[64] = {0};
10707 char buf[64] = {0};
10708 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +080010709 int res;
developer72fb0bb2023-01-11 09:46:29 +080010710
developera3511852023-06-14 14:12:59 +080010711 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010712
developera3511852023-06-14 14:12:59 +080010713 if(!IP_output || !Port_output || !RadiusSecret_output)
10714 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010715
developera3511852023-06-14 14:12:59 +080010716 // Read the first matched config
developere40952c2023-06-15 18:46:43 +080010717 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10718 if (os_snprintf_error(sizeof(config_file), res)) {
10719 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10720 return RETURN_ERR;
10721 }
developer32f2a182023-06-27 19:50:41 +080010722 res = snprintf(cmd, sizeof(cmd),
10723 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
developer75bd10c2023-06-27 11:34:08 +080010724 if (os_snprintf_error(sizeof(cmd), res)) {
10725 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10726 return RETURN_ERR;
10727 }
developera3511852023-06-14 14:12:59 +080010728 _syscmd(cmd, buf, sizeof(buf));
10729 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080010730
developera3511852023-06-14 14:12:59 +080010731 memset(buf, 0, sizeof(buf));
developer75bd10c2023-06-27 11:34:08 +080010732 res = snprintf(cmd, sizeof(cmd), "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
10733 if (os_snprintf_error(sizeof(cmd), res)) {
10734 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10735 return RETURN_ERR;
10736 }
developera3511852023-06-14 14:12:59 +080010737 _syscmd(cmd, buf, sizeof(buf));
10738 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080010739
developera3511852023-06-14 14:12:59 +080010740 memset(buf, 0, sizeof(buf));
developer75bd10c2023-06-27 11:34:08 +080010741 res = snprintf(cmd, sizeof(cmd), "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
10742 if (os_snprintf_error(sizeof(cmd), res)) {
10743 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10744 return RETURN_ERR;
10745 }
developera3511852023-06-14 14:12:59 +080010746 _syscmd(cmd, buf, sizeof(buf));
10747 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080010748
developera3511852023-06-14 14:12:59 +080010749 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10750 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010751}
10752
10753INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
10754{
developera3511852023-06-14 14:12:59 +080010755 char config_file[64] = {0};
10756 char port_str[8] = {0};
10757 char cmd[256] = {0};
10758 char buf[128] = {0};
10759 int res;
developer72fb0bb2023-01-11 09:46:29 +080010760
developera3511852023-06-14 14:12:59 +080010761 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010762
developere5750452023-05-15 16:46:42 +080010763 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080010764 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080010765
developera3511852023-06-14 14:12:59 +080010766 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
10767 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080010768
developera3511852023-06-14 14:12:59 +080010769 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10770 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010771 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10772 return RETURN_ERR;
10773 }
developer72fb0bb2023-01-11 09:46:29 +080010774
developera3511852023-06-14 14:12:59 +080010775 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
10776 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080010777 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10778 return RETURN_ERR;
10779 }
developera3511852023-06-14 14:12:59 +080010780 _syscmd(cmd, buf, sizeof(buf));
10781 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080010782
developere40952c2023-06-15 18:46:43 +080010783 res = snprintf(port_str, sizeof(port_str), "%d", port);
developera3511852023-06-14 14:12:59 +080010784 if (strlen(buf) == 0) {
10785 // Append
10786 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
10787 "auth_server_addr=%s\\n"
10788 "auth_server_port=%s\\n"
10789 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
10790 if (os_snprintf_error(sizeof(cmd), res)) {
10791 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10792 return RETURN_ERR;
10793 }
10794 } else {
10795 // Delete the three lines setting after the "# radius 1" comment
10796 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
10797 if (os_snprintf_error(sizeof(cmd), res)) {
10798 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10799 return RETURN_ERR;
10800 }
10801 _syscmd(cmd, buf, sizeof(buf));
10802 memset(cmd, 0, sizeof(cmd));
10803 // Use "# radius 1" comment to find the location to insert the radius setting
10804 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
10805 "# radius 1\\n"
10806 "auth_server_addr=%s\\n"
10807 "auth_server_port=%s\\n"
10808 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
10809 if (os_snprintf_error(sizeof(cmd), res)) {
10810 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10811 return RETURN_ERR;
10812 }
10813 }
10814 if(_syscmd(cmd, buf, sizeof(buf))) {
10815 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
10816 return RETURN_ERR;
10817 }
developer72fb0bb2023-01-11 09:46:29 +080010818
developera3511852023-06-14 14:12:59 +080010819 wifi_reloadAp(apIndex);
10820 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10821 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010822}
10823
10824INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
10825{
developera3511852023-06-14 14:12:59 +080010826 char config_file[64] = {0};
10827 char buf[64] = {0};
10828 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +080010829 int res;
developer72fb0bb2023-01-11 09:46:29 +080010830
developera3511852023-06-14 14:12:59 +080010831 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010832
developera3511852023-06-14 14:12:59 +080010833 if(!IP_output || !Port_output || !RadiusSecret_output)
10834 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010835
developera3511852023-06-14 14:12:59 +080010836 // Read the second matched config
developere40952c2023-06-15 18:46:43 +080010837 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10838 if (os_snprintf_error(sizeof(config_file), res)) {
10839 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10840 return RETURN_ERR;
10841 }
10842
developer32f2a182023-06-27 19:50:41 +080010843 res = snprintf(cmd, sizeof(cmd),
10844 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
10845 config_file);
developer75bd10c2023-06-27 11:34:08 +080010846 if (os_snprintf_error(sizeof(cmd), res)) {
10847 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10848 return RETURN_ERR;
10849 }
developera3511852023-06-14 14:12:59 +080010850 _syscmd(cmd, buf, sizeof(buf));
10851 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080010852
developera3511852023-06-14 14:12:59 +080010853 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080010854 res = snprintf(cmd, sizeof(cmd),
10855 "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
10856 config_file);
developer75bd10c2023-06-27 11:34:08 +080010857 if (os_snprintf_error(sizeof(cmd), res)) {
10858 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10859 return RETURN_ERR;
10860 }
developera3511852023-06-14 14:12:59 +080010861 _syscmd(cmd, buf, sizeof(buf));
10862 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080010863
developera3511852023-06-14 14:12:59 +080010864 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080010865 res = snprintf(cmd, sizeof(cmd),
10866 "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
10867 config_file);
developer75bd10c2023-06-27 11:34:08 +080010868 if (os_snprintf_error(sizeof(cmd), res)) {
10869 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10870 return RETURN_ERR;
10871 }
10872
developera3511852023-06-14 14:12:59 +080010873 _syscmd(cmd, buf, sizeof(buf));
10874 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080010875
developera3511852023-06-14 14:12:59 +080010876 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10877 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010878}
10879
10880INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
10881{
developera3511852023-06-14 14:12:59 +080010882 char config_file[64] = {0};
10883 char port_str[8] = {0};
10884 char cmd[256] = {0};
10885 char buf[128] = {0};
10886 int res;
developer72fb0bb2023-01-11 09:46:29 +080010887
developera3511852023-06-14 14:12:59 +080010888 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010889
developere5750452023-05-15 16:46:42 +080010890 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080010891 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080010892
developera3511852023-06-14 14:12:59 +080010893 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
10894 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080010895
developera3511852023-06-14 14:12:59 +080010896 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10897 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010898 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10899 return RETURN_ERR;
10900 }
developer72fb0bb2023-01-11 09:46:29 +080010901
developera3511852023-06-14 14:12:59 +080010902 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
10903 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080010904 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10905 return RETURN_ERR;
10906 }
developera3511852023-06-14 14:12:59 +080010907 _syscmd(cmd, buf, sizeof(buf));
10908 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080010909
developera3511852023-06-14 14:12:59 +080010910 res = snprintf(port_str, sizeof(port_str), "%d", port);
10911 if (os_snprintf_error(sizeof(port_str), res)) {
developer46506162023-06-12 10:09:39 +080010912 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10913 return RETURN_ERR;
10914 }
developera3511852023-06-14 14:12:59 +080010915 if (strlen(buf) == 0) {
10916 // Append
10917 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
10918 "auth_server_addr=%s\\n"
10919 "auth_server_port=%s\\n"
10920 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
10921 if (os_snprintf_error(sizeof(cmd), res)) {
10922 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10923 return RETURN_ERR;
10924 }
10925 } else {
10926 // Delete the three lines setting after the "# radius 2" comment
10927 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
10928 if (os_snprintf_error(sizeof(cmd), res)) {
10929 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10930 return RETURN_ERR;
10931 }
10932 _syscmd(cmd, buf, sizeof(buf));
10933 memset(cmd, 0, sizeof(cmd));
10934 // Use "# radius 2" comment to find the location to insert the radius setting
10935 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
10936 "# radius 2\\n"
10937 "auth_server_addr=%s\\n"
10938 "auth_server_port=%s\\n"
10939 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
10940 if (os_snprintf_error(sizeof(cmd), res)) {
10941 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10942 return RETURN_ERR;
10943 }
10944 }
10945 if(_syscmd(cmd, buf, sizeof(buf))) {
10946 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
10947 return RETURN_ERR;
10948 }
developer72fb0bb2023-01-11 09:46:29 +080010949
developera3511852023-06-14 14:12:59 +080010950 wifi_reloadAp(apIndex);
10951 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10952 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010953}
10954
10955//RadiusSettings
10956INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
10957{
developera3511852023-06-14 14:12:59 +080010958 if(!output)
10959 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010960
developera3511852023-06-14 14:12:59 +080010961 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
10962 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
10963 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
10964 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
10965 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
10966 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.
10967 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
10968 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
10969 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 +080010970 //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 +080010971
developera3511852023-06-14 14:12:59 +080010972 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010973}
10974
10975INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
10976{
developera3511852023-06-14 14:12:59 +080010977 //store the paramters, and apply instantly
10978 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010979}
10980
10981//Device.WiFi.AccessPoint.{i}.WPS.Enable
10982//Enables or disables WPS functionality for this access point.
10983// outputs the WPS enable state of this ap in output_bool
10984INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
10985{
developera3511852023-06-14 14:12:59 +080010986 char interface_name[16] = {0};
10987 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080010988 int res;
10989
developera3511852023-06-14 14:12:59 +080010990 if(!output_bool)
10991 return RETURN_ERR;
10992 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10993 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080010994 res = snprintf(cmd, sizeof(cmd),
10995 "hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2",
10996 interface_name);
developer75bd10c2023-06-27 11:34:08 +080010997 if (os_snprintf_error(sizeof(cmd), res)) {
10998 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10999 return RETURN_ERR;
11000 }
developera3511852023-06-14 14:12:59 +080011001 _syscmd(cmd, buf, sizeof(buf));
11002 if(strstr(buf, "configured"))
11003 *output_bool=TRUE;
11004 else
11005 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +080011006
developera3511852023-06-14 14:12:59 +080011007 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080011008}
developer72fb0bb2023-01-11 09:46:29 +080011009
11010//Device.WiFi.AccessPoint.{i}.WPS.Enable
11011// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
11012INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
11013{
developera3511852023-06-14 14:12:59 +080011014 char config_file[MAX_BUF_SIZE] = {0};
11015 char buf[128] = {0};
11016 struct params params;
developere40952c2023-06-15 18:46:43 +080011017 int res;
developer72fb0bb2023-01-11 09:46:29 +080011018
developera3511852023-06-14 14:12:59 +080011019 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11020 //store the paramters, and wait for wifi up to apply
11021 params.name = "wps_state";
11022 if (enable == TRUE) {
11023 wifi_getApBeaconType(apIndex, buf);
11024 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
11025 params.value = "1";
11026 else // If ap set encryption
11027 params.value = "2";
11028 } else {
11029 params.value = "0";
11030 }
developer72fb0bb2023-01-11 09:46:29 +080011031
developere40952c2023-06-15 18:46:43 +080011032 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11033 if (os_snprintf_error(sizeof(config_file), res)) {
11034 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11035 return RETURN_ERR;
11036 }
developera3511852023-06-14 14:12:59 +080011037 wifi_hostapdWrite(config_file, &params, 1);
11038 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11039 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080011040
developera3511852023-06-14 14:12:59 +080011041 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11042 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011043}
11044
11045//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
11046INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
11047{
developere40952c2023-06-15 18:46:43 +080011048 int res;
developera3511852023-06-14 14:12:59 +080011049 if(!output)
11050 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011051 res = snprintf(output, 128, "PushButton,PIN");
11052 if (os_snprintf_error(128, res)) {
11053 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11054 return RETURN_ERR;
11055 }
11056
developera3511852023-06-14 14:12:59 +080011057 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011058}
11059
11060//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
11061//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.
11062// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
11063INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
11064{
developere40952c2023-06-15 18:46:43 +080011065 int res;
developera3511852023-06-14 14:12:59 +080011066 if(!output)
11067 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011068 res = snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
11069 if (os_snprintf_error(64, res)) {
11070 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11071 return RETURN_ERR;
11072 }
developer72fb0bb2023-01-11 09:46:29 +080011073
developera3511852023-06-14 14:12:59 +080011074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011075}
11076
11077//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
11078// 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
11079INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
11080{
developera3511852023-06-14 14:12:59 +080011081 //apply instantly. No setting need to be stored.
11082 char methods[MAX_BUF_SIZE], *token, *next_token;
11083 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
11084 struct params params;
developere40952c2023-06-15 18:46:43 +080011085 int res;
developer72fb0bb2023-01-11 09:46:29 +080011086
developera3511852023-06-14 14:12:59 +080011087 if(!methodString)
11088 return RETURN_ERR;
11089 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11090 //store the paramters, and wait for wifi up to apply
developer72fb0bb2023-01-11 09:46:29 +080011091
developere40952c2023-06-15 18:46:43 +080011092 res = snprintf(methods, sizeof(methods), "%s", methodString);
11093 if (os_snprintf_error(sizeof(methods), res)) {
11094 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11095 return RETURN_ERR;
11096 }
developera3511852023-06-14 14:12:59 +080011097 for(token=methods; *token; token=next_token) {
11098 strtok_r(token, ",", &next_token);
11099 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
developere40952c2023-06-15 18:46:43 +080011100 res = snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
developera3511852023-06-14 14:12:59 +080011101 else if(*token=='E')
11102 {
11103 if(!strcmp(methods, "Ethernet"))
developere40952c2023-06-15 18:46:43 +080011104 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
developera3511852023-06-14 14:12:59 +080011105 else if(!strcmp(methods, "ExternalNFCToken"))
developere40952c2023-06-15 18:46:43 +080011106 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
developera3511852023-06-14 14:12:59 +080011107 else
11108 printf("%s: Unknown WpsConfigMethod\n", __func__);
11109 }
11110 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
developere40952c2023-06-15 18:46:43 +080011111 res = snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
developera3511852023-06-14 14:12:59 +080011112 else if(*token=='N' && !strcmp(token, "NFCInterface"))
developere40952c2023-06-15 18:46:43 +080011113 res = snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
developera3511852023-06-14 14:12:59 +080011114 else if(*token=='P' )
11115 {
11116 if(!strcmp(token, "PushButton"))
developere40952c2023-06-15 18:46:43 +080011117 res = snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developera3511852023-06-14 14:12:59 +080011118 else if(!strcmp(token, "PIN"))
developere40952c2023-06-15 18:46:43 +080011119 res = snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
developera3511852023-06-14 14:12:59 +080011120 else
11121 printf("%s: Unknown WpsConfigMethod\n", __func__);
11122 }
11123 else
11124 printf("%s: Unknown WpsConfigMethod\n", __func__);
11125 }
developere40952c2023-06-15 18:46:43 +080011126 if (os_snprintf_error(sizeof(config_methods), res)) {
11127 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11128 return RETURN_ERR;
11129 }
11130
developera3511852023-06-14 14:12:59 +080011131 params.name = "config_methods";
11132 params.value = config_methods;
developere40952c2023-06-15 18:46:43 +080011133 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11134 if (os_snprintf_error(sizeof(config_file), res)) {
11135 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11136 return RETURN_ERR;
11137 }
developera3511852023-06-14 14:12:59 +080011138 wifi_hostapdWrite(config_file, &params, 1);
11139 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11140 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011141
developera3511852023-06-14 14:12:59 +080011142 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011143}
11144
11145// outputs the pin value, ulong_pin must be allocated by the caller
11146INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
11147{
developera3511852023-06-14 14:12:59 +080011148 char buf[MAX_BUF_SIZE] = {0};
11149 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011150 int res;
developer72fb0bb2023-01-11 09:46:29 +080011151
developera3511852023-06-14 14:12:59 +080011152 if(!output_ulong)
11153 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011154 res = snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
11155 if (os_snprintf_error(sizeof(cmd), res)) {
11156 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11157 return RETURN_ERR;
11158 }
developera3511852023-06-14 14:12:59 +080011159 _syscmd(cmd, buf, sizeof(buf));
11160 if(strlen(buf) > 0)
11161 *output_ulong=strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080011162
developera3511852023-06-14 14:12:59 +080011163 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011164}
11165
11166// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
11167INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
11168{
developera3511852023-06-14 14:12:59 +080011169 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
11170 char ap_pin[16] = {0};
11171 char config_file[MAX_BUF_SIZE] = {0};
11172 struct params params;
developere40952c2023-06-15 18:46:43 +080011173 int res;
developer72fb0bb2023-01-11 09:46:29 +080011174
developera3511852023-06-14 14:12:59 +080011175 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080011176 res = snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
11177 if (os_snprintf_error(sizeof(ap_pin), res)) {
11178 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11179 return RETURN_ERR;
11180 }
developera3511852023-06-14 14:12:59 +080011181 params.name = "ap_pin";
11182 params.value = ap_pin;
developere40952c2023-06-15 18:46:43 +080011183 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11184 if (os_snprintf_error(sizeof(config_file), res)) {
11185 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11186 return RETURN_ERR;
11187 }
developera3511852023-06-14 14:12:59 +080011188 wifi_hostapdWrite(config_file, &params, 1);
11189 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11190 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011191
developera3511852023-06-14 14:12:59 +080011192 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011193}
11194
11195// Output string is either Not configured or Configured, max 32 characters
11196INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
11197{
developera3511852023-06-14 14:12:59 +080011198 char interface_name[16] = {0};
11199 char cmd[MAX_CMD_SIZE];
11200 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080011201 int res;
developer72fb0bb2023-01-11 09:46:29 +080011202
developera3511852023-06-14 14:12:59 +080011203 if(!output_string)
11204 return RETURN_ERR;
11205 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080011206 res = snprintf(output_string, 32, "Not configured");
11207 if (os_snprintf_error(32, res)) {
11208 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11209 return RETURN_ERR;
11210 }
developera3511852023-06-14 14:12:59 +080011211 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11212 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011213 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
11214 if (os_snprintf_error(sizeof(cmd), res)) {
11215 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11216 return RETURN_ERR;
11217 }
developera3511852023-06-14 14:12:59 +080011218 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011219
developera3511852023-06-14 14:12:59 +080011220 if(!strncmp(buf, "configured", 10))
developere40952c2023-06-15 18:46:43 +080011221 res = snprintf(output_string, 32, "Configured");
developera3511852023-06-14 14:12:59 +080011222 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011223
developera3511852023-06-14 14:12:59 +080011224 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011225}
11226
11227// sets the WPS pin for this AP
11228INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
11229{
developera3511852023-06-14 14:12:59 +080011230 char interface_name[16] = {0};
11231 char cmd[MAX_CMD_SIZE];
11232 char buf[MAX_BUF_SIZE]={0};
developer9ce44382023-06-28 11:09:37 +080011233 BOOL enable = 0;
developere40952c2023-06-15 18:46:43 +080011234 int res;
developer72fb0bb2023-01-11 09:46:29 +080011235
developera3511852023-06-14 14:12:59 +080011236 wifi_getApEnable(apIndex, &enable);
11237 if (!enable)
11238 return RETURN_ERR;
11239 wifi_getApWpsEnable(apIndex, &enable);
11240 if (!enable)
11241 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011242
developera3511852023-06-14 14:12:59 +080011243 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11244 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011245 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
11246 if (os_snprintf_error(sizeof(cmd), res)) {
11247 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11248 return RETURN_ERR;
11249 }
developera3511852023-06-14 14:12:59 +080011250 _syscmd(cmd, buf, sizeof(buf));
11251 if((strstr(buf, "OK"))!=NULL)
11252 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011253
developera3511852023-06-14 14:12:59 +080011254 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011255}
11256
11257// This function is called when the WPS push button has been pressed for this AP
11258INT wifi_setApWpsButtonPush(INT apIndex)
11259{
developera3511852023-06-14 14:12:59 +080011260 char cmd[MAX_CMD_SIZE];
11261 char buf[MAX_BUF_SIZE]={0};
11262 char interface_name[16] = {0};
11263 BOOL enable=FALSE;
developere40952c2023-06-15 18:46:43 +080011264 int res;
developer72fb0bb2023-01-11 09:46:29 +080011265
developera3511852023-06-14 14:12:59 +080011266 wifi_getApEnable(apIndex, &enable);
11267 if (!enable)
11268 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011269
developera3511852023-06-14 14:12:59 +080011270 wifi_getApWpsEnable(apIndex, &enable);
11271 if (!enable)
11272 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011273
developera3511852023-06-14 14:12:59 +080011274 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11275 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011276
developere40952c2023-06-15 18:46:43 +080011277 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
11278 if (os_snprintf_error(sizeof(cmd), res)) {
11279 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11280 return RETURN_ERR;
11281 }
developera3511852023-06-14 14:12:59 +080011282 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011283
developera3511852023-06-14 14:12:59 +080011284 if((strstr(buf, "OK"))!=NULL)
11285 return RETURN_OK;
11286 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011287}
11288
11289// cancels WPS mode for this AP
11290INT wifi_cancelApWPS(INT apIndex)
11291{
developera3511852023-06-14 14:12:59 +080011292 char interface_name[16] = {0};
11293 char cmd[MAX_CMD_SIZE];
11294 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080011295 int res;
developer72fb0bb2023-01-11 09:46:29 +080011296
developera3511852023-06-14 14:12:59 +080011297 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11298 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011299 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
11300 if (os_snprintf_error(sizeof(cmd), res)) {
11301 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11302 return RETURN_ERR;
11303 }
developera3511852023-06-14 14:12:59 +080011304 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011305
developera3511852023-06-14 14:12:59 +080011306 if((strstr(buf, "OK"))!=NULL)
11307 return RETURN_OK;
11308 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011309}
11310
11311//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
11312//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
11313INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
11314{
developera3511852023-06-14 14:12:59 +080011315 char interface_name[16] = {0};
11316 FILE *f = NULL;
11317 int read_flag=0, auth_temp=0, mac_temp=0;
11318 char cmd[256] = {0}, buf[2048] = {0};
11319 char *param = NULL, *value = NULL, *line=NULL;
11320 size_t len = 0;
11321 wifi_associated_dev_t *dev=NULL;
11322 int res;
developer72fb0bb2023-01-11 09:46:29 +080011323
developera3511852023-06-14 14:12:59 +080011324 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11325 *associated_dev_array = NULL;
11326 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11327 return RETURN_ERR;
11328 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
11329 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011330 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11331 return RETURN_ERR;
11332 }
developera3511852023-06-14 14:12:59 +080011333 _syscmd(cmd,buf,sizeof(buf));
11334 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011335
developera3511852023-06-14 14:12:59 +080011336 if (*output_array_size <= 0)
11337 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011338
developera3511852023-06-14 14:12:59 +080011339 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
11340 *associated_dev_array = dev;
11341 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
11342 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011343 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11344 return RETURN_ERR;
11345 }
developera3511852023-06-14 14:12:59 +080011346 _syscmd(cmd,buf,sizeof(buf));
11347 f = fopen("/tmp/connected_devices.txt", "r");
11348 if (f==NULL)
11349 {
11350 *output_array_size=0;
11351 return RETURN_ERR;
11352 }
11353 while ((getline(&line, &len, f)) != -1)
11354 {
11355 param = strtok(line,"=");
11356 value = strtok(NULL,"=");
developer72fb0bb2023-01-11 09:46:29 +080011357
developera3511852023-06-14 14:12:59 +080011358 if( strcmp("flags",param) == 0 )
11359 {
11360 value[strlen(value)-1]='\0';
11361 if(strstr (value,"AUTHORIZED") != NULL )
11362 {
11363 dev[auth_temp].cli_AuthenticationState = 1;
11364 dev[auth_temp].cli_Active = 1;
11365 auth_temp++;
11366 read_flag=1;
11367 }
11368 }
11369 if(read_flag==1)
11370 {
11371 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
11372 {
11373 value[strlen(value)-1]='\0';
11374 sscanf(value, "%x:%x:%x:%x:%x:%x",
11375 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
11376 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
11377 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
11378 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
11379 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
11380 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
11381 mac_temp++;
11382 read_flag=0;
11383 }
11384 }
11385 }
11386 *output_array_size = auth_temp;
11387 auth_temp=0;
11388 mac_temp=0;
11389 free(line);
11390 fclose(f);
11391 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11392 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011393}
11394
11395#define MACADDRESS_SIZE 6
11396
11397INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
11398{
developera3511852023-06-14 14:12:59 +080011399 FILE *fp = NULL;
11400 char str[MAX_BUF_SIZE] = {0};
11401 int wificlientindex = 0 ;
11402 int count = 0;
11403 int signalstrength = 0;
11404 int arr[MACADDRESS_SIZE] = {0};
11405 unsigned char mac[MACADDRESS_SIZE] = {0};
11406 UINT wifi_count = 0;
11407 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011408 int res;
developer72fb0bb2023-01-11 09:46:29 +080011409
developera3511852023-06-14 14:12:59 +080011410 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11411 *output_array_size = 0;
11412 *associated_dev_array = NULL;
developer72fb0bb2023-01-11 09:46:29 +080011413
developer32f2a182023-06-27 19:50:41 +080011414 res = snprintf(pipeCmd, sizeof(pipeCmd),
11415 "iw dev %s station dump | grep %s | wc -l", interface_name,
11416 interface_name);
developer75bd10c2023-06-27 11:34:08 +080011417 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11418 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11419 return RETURN_ERR;
11420 }
developera3511852023-06-14 14:12:59 +080011421 fp = popen(pipeCmd, "r");
11422 if (fp == NULL)
11423 {
11424 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11425 return RETURN_ERR;
11426 }
developer72fb0bb2023-01-11 09:46:29 +080011427
developera3511852023-06-14 14:12:59 +080011428 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080011429 if (fgets(str, sizeof(str)-1, fp) == NULL) {
11430 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11431 pclose(fp);
11432 return RETURN_ERR;
11433 }
developera3511852023-06-14 14:12:59 +080011434 wifi_count = (unsigned int) atoi ( str );
11435 *output_array_size = wifi_count;
11436 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11437 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080011438
developera3511852023-06-14 14:12:59 +080011439 if(wifi_count == 0)
11440 {
11441 return RETURN_OK;
11442 }
11443 else
11444 {
11445 wifi_associated_dev3_t* temp = NULL;
developer9ce44382023-06-28 11:09:37 +080011446 if(wifi_count <= 0 || wifi_count > MAX_ASSOCIATED_STA_NUM){
11447 return RETURN_ERR;
11448 }
developera3511852023-06-14 14:12:59 +080011449 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
11450 if(temp == NULL)
11451 {
11452 printf("Error Statement. Insufficient memory \n");
11453 return RETURN_ERR;
11454 }
developer72fb0bb2023-01-11 09:46:29 +080011455
developere40952c2023-06-15 18:46:43 +080011456 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11457 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11458 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080011459 free(temp);
developere40952c2023-06-15 18:46:43 +080011460 return RETURN_ERR;
11461 }
developera3511852023-06-14 14:12:59 +080011462 system(pipeCmd);
11463 memset(pipeCmd,0,sizeof(pipeCmd));
11464 if(apIndex == 0)
developere40952c2023-06-15 18:46:43 +080011465 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
developera3511852023-06-14 14:12:59 +080011466 else if(apIndex == 1)
developere40952c2023-06-15 18:46:43 +080011467 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
11468 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11469 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080011470 free(temp);
developere40952c2023-06-15 18:46:43 +080011471 return RETURN_ERR;
11472 }
developera3511852023-06-14 14:12:59 +080011473 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080011474
developera3511852023-06-14 14:12:59 +080011475 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11476 if(fp == NULL)
11477 {
11478 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11479 free(temp);
11480 return RETURN_ERR;
11481 }
11482 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080011483
developer86035662023-06-28 19:21:12 +080011484 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11485 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11486 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11487 return RETURN_ERR;
11488 }
11489
developera3511852023-06-14 14:12:59 +080011490 fp = popen(pipeCmd, "r");
11491 if(fp)
11492 {
11493 for(count =0 ; count < wifi_count; count++)
11494 {
developer86035662023-06-28 19:21:12 +080011495 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11496 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11497 pclose(fp);
11498 return RETURN_ERR;
11499 }
developera3511852023-06-14 14:12:59 +080011500 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11501 {
11502 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11503 {
11504 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080011505
developera3511852023-06-14 14:12:59 +080011506 }
11507 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11508 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]);
11509 }
11510 temp[count].cli_AuthenticationState = 1; //TODO
11511 temp[count].cli_Active = 1; //TODO
11512 }
11513 pclose(fp);
11514 }
developer72fb0bb2023-01-11 09:46:29 +080011515
developer86035662023-06-28 19:21:12 +080011516 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11517 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11518 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11519 return RETURN_ERR;
11520 }
11521
developera3511852023-06-14 14:12:59 +080011522 fp = popen(pipeCmd, "r");
11523 if(fp)
11524 {
11525 pclose(fp);
11526 }
11527 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11528 if(fp)
11529 {
11530 for(count =0 ; count < wifi_count ;count++)
11531 {
developer86035662023-06-28 19:21:12 +080011532 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11533 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11534 pclose(fp);
11535 return RETURN_ERR;
11536 }
developera3511852023-06-14 14:12:59 +080011537 signalstrength = atoi(str);
11538 temp[count].cli_SignalStrength = signalstrength;
11539 temp[count].cli_RSSI = signalstrength;
11540 temp[count].cli_SNR = signalstrength + 95;
11541 }
11542 pclose(fp);
11543 }
developer72fb0bb2023-01-11 09:46:29 +080011544
11545
developera3511852023-06-14 14:12:59 +080011546 if((apIndex == 0) || (apIndex == 4))
11547 {
11548 for(count =0 ; count < wifi_count ;count++)
11549 {
developer32f2a182023-06-27 19:50:41 +080011550 memcpy(temp[count].cli_OperatingStandard,"g", 1);
11551 temp[count].cli_OperatingStandard[1] = '\0';
11552 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
11553 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080011554 }
developer72fb0bb2023-01-11 09:46:29 +080011555
developera3511852023-06-14 14:12:59 +080011556 //BytesSent
developer86035662023-06-28 19:21:12 +080011557 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
11558 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11559 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11560 return RETURN_ERR;
11561 }
11562
developera3511852023-06-14 14:12:59 +080011563 fp = popen(pipeCmd, "r");
11564 if(fp)
11565 {
11566 pclose(fp);
11567 }
11568 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
11569 if(fp)
11570 {
11571 for (count = 0; count < wifi_count; count++)
11572 {
developer86035662023-06-28 19:21:12 +080011573 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11574 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11575 pclose(fp);
11576 return RETURN_ERR;
11577 }
developera3511852023-06-14 14:12:59 +080011578 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
11579 }
11580 pclose(fp);
11581 }
developer72fb0bb2023-01-11 09:46:29 +080011582
developera3511852023-06-14 14:12:59 +080011583 //BytesReceived
developer86035662023-06-28 19:21:12 +080011584 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
11585 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11586 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11587 return RETURN_ERR;
11588 }
11589
developera3511852023-06-14 14:12:59 +080011590 fp = popen(pipeCmd, "r");
11591 if (fp)
11592 {
11593 pclose(fp);
11594 }
11595 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
11596 if (fp)
11597 {
11598 for (count = 0; count < wifi_count; count++)
11599 {
developer86035662023-06-28 19:21:12 +080011600 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11601 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11602 pclose(fp);
11603 return RETURN_ERR;
11604 }
developera3511852023-06-14 14:12:59 +080011605 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
11606 }
11607 pclose(fp);
11608 }
developer72fb0bb2023-01-11 09:46:29 +080011609
developera3511852023-06-14 14:12:59 +080011610 //PacketsSent
developer86035662023-06-28 19:21:12 +080011611 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
11612 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11613 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11614 return RETURN_ERR;
11615 }
11616
developera3511852023-06-14 14:12:59 +080011617 fp = popen(pipeCmd, "r");
11618 if (fp)
11619 {
11620 pclose(fp);
11621 }
developer72fb0bb2023-01-11 09:46:29 +080011622
developera3511852023-06-14 14:12:59 +080011623 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
11624 if (fp)
11625 {
11626 for (count = 0; count < wifi_count; count++)
11627 {
developer86035662023-06-28 19:21:12 +080011628 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11629 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11630 pclose(fp);
11631 return RETURN_ERR;
11632 }
developera3511852023-06-14 14:12:59 +080011633 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
11634 }
11635 pclose(fp);
11636 }
developer72fb0bb2023-01-11 09:46:29 +080011637
developera3511852023-06-14 14:12:59 +080011638 //PacketsReceived
developer86035662023-06-28 19:21:12 +080011639 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
11640 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11641 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11642 return RETURN_ERR;
11643 }
11644
developera3511852023-06-14 14:12:59 +080011645 fp = popen(pipeCmd, "r");
11646 if (fp)
11647 {
11648 pclose(fp);
11649 }
11650 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
11651 if (fp)
11652 {
11653 for (count = 0; count < wifi_count; count++)
11654 {
developer86035662023-06-28 19:21:12 +080011655 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11656 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11657 pclose(fp);
11658 return RETURN_ERR;
11659 }
developera3511852023-06-14 14:12:59 +080011660 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
11661 }
11662 pclose(fp);
11663 }
developer72fb0bb2023-01-11 09:46:29 +080011664
developera3511852023-06-14 14:12:59 +080011665 //ErrorsSent
developer86035662023-06-28 19:21:12 +080011666 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
11667 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11668 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11669 return RETURN_ERR;
11670 }
11671
developera3511852023-06-14 14:12:59 +080011672 fp = popen(pipeCmd, "r");
11673 if (fp)
11674 {
11675 pclose(fp);
11676 }
11677 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
11678 if (fp)
11679 {
11680 for (count = 0; count < wifi_count; count++)
11681 {
developer86035662023-06-28 19:21:12 +080011682 if (fgets(str, MAX_BUF_SIZE, fp) == NULL){
11683 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11684 pclose(fp);
11685 return RETURN_ERR;
11686 }
developera3511852023-06-14 14:12:59 +080011687 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
11688 }
11689 pclose(fp);
11690 }
developer72fb0bb2023-01-11 09:46:29 +080011691
developera3511852023-06-14 14:12:59 +080011692 //ErrorsSent
developer86035662023-06-28 19:21:12 +080011693 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
11694 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11695 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11696 return RETURN_ERR;
11697 }
11698
developera3511852023-06-14 14:12:59 +080011699 fp = popen(pipeCmd, "r");
11700 if (fp)
11701 {
11702 pclose(fp);
11703 }
11704 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
11705 if (fp)
11706 {
11707 for (count = 0; count < wifi_count; count++)
11708 {
developer86035662023-06-28 19:21:12 +080011709 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11710 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11711 pclose(fp);
11712 return RETURN_ERR;
11713 }
developera3511852023-06-14 14:12:59 +080011714 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
11715 }
11716 pclose(fp);
11717 }
developer72fb0bb2023-01-11 09:46:29 +080011718
developera3511852023-06-14 14:12:59 +080011719 //LastDataDownlinkRate
developer86035662023-06-28 19:21:12 +080011720 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
11721 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11722 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11723 return RETURN_ERR;
11724 }
11725
developera3511852023-06-14 14:12:59 +080011726 fp = popen(pipeCmd, "r");
11727 if (fp)
11728 {
11729 pclose(fp);
11730 }
11731 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
11732 if (fp)
11733 {
11734 for (count = 0; count < wifi_count; count++)
11735 {
developer86035662023-06-28 19:21:12 +080011736 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11737 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11738 pclose(fp);
11739 return RETURN_ERR;
11740 }
developera3511852023-06-14 14:12:59 +080011741 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
11742 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
11743 }
11744 pclose(fp);
11745 }
developer72fb0bb2023-01-11 09:46:29 +080011746
developera3511852023-06-14 14:12:59 +080011747 //LastDataUplinkRate
developer86035662023-06-28 19:21:12 +080011748 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
11749 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11750 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11751 return RETURN_ERR;
11752 }
11753
developera3511852023-06-14 14:12:59 +080011754 fp = popen(pipeCmd, "r");
11755 if (fp)
11756 {
11757 pclose(fp);
11758 }
11759 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
11760 if (fp)
11761 {
11762 for (count = 0; count < wifi_count; count++)
11763 {
developer86035662023-06-28 19:21:12 +080011764 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11765 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11766 pclose(fp);
11767 return RETURN_ERR;
11768 }
developera3511852023-06-14 14:12:59 +080011769 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
11770 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
11771 }
11772 pclose(fp);
11773 }
developer72fb0bb2023-01-11 09:46:29 +080011774
developera3511852023-06-14 14:12:59 +080011775 }
11776 else if ((apIndex == 1) || (apIndex == 5))
11777 {
11778 for (count = 0; count < wifi_count; count++)
11779 {
developer32f2a182023-06-27 19:50:41 +080011780 memcpy(temp[count].cli_OperatingStandard, "a", 1);
11781 temp[count].cli_OperatingStandard[1] = '\0';
11782 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
11783 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080011784 temp[count].cli_BytesSent = 0;
11785 temp[count].cli_BytesReceived = 0;
11786 temp[count].cli_LastDataUplinkRate = 0;
11787 temp[count].cli_LastDataDownlinkRate = 0;
11788 temp[count].cli_PacketsSent = 0;
11789 temp[count].cli_PacketsReceived = 0;
11790 temp[count].cli_ErrorsSent = 0;
11791 }
11792 }
developer72fb0bb2023-01-11 09:46:29 +080011793
developera3511852023-06-14 14:12:59 +080011794 for (count = 0; count < wifi_count; count++)
11795 {
11796 temp[count].cli_Retransmissions = 0;
11797 temp[count].cli_DataFramesSentAck = 0;
11798 temp[count].cli_DataFramesSentNoAck = 0;
11799 temp[count].cli_MinRSSI = 0;
11800 temp[count].cli_MaxRSSI = 0;
11801 strncpy(temp[count].cli_InterferenceSources, "", 64);
11802 memset(temp[count].cli_IPAddress, 0, 64);
11803 temp[count].cli_RetransCount = 0;
11804 temp[count].cli_FailedRetransCount = 0;
11805 temp[count].cli_RetryCount = 0;
11806 temp[count].cli_MultipleRetryCount = 0;
11807 }
11808 *associated_dev_array = temp;
11809 }
11810 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11811 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011812}
11813
developer7e4a2a62023-04-06 19:56:03 +080011814int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +080011815{
developera3511852023-06-14 14:12:59 +080011816 char cmd[MAX_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +080011817 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011818 int res;
developer32f2a182023-06-27 19:50:41 +080011819 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080011820
developera3511852023-06-14 14:12:59 +080011821 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080011822
developere40952c2023-06-15 18:46:43 +080011823 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +080011824 interface_name);
developere40952c2023-06-15 18:46:43 +080011825 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
11826 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11827 return RETURN_ERR;
11828 }
11829
developera3511852023-06-14 14:12:59 +080011830 _syscmd(cmd, buf, MAX_BUF_SIZE);
developer7e4a2a62023-04-06 19:56:03 +080011831
developer32f2a182023-06-27 19:50:41 +080011832 len = strlen(buf);
11833 if (len >= sizeof(buf)) {
11834 wifi_debug(DEBUG_ERROR, "Unexpected buf size\n");
11835 return RETURN_ERR;
11836 }
11837 strncpy(wifi_status, buf, len); /* TBD: check wifi_status mem lenth and replace with strcpy later */
11838 wifi_status[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080011839
developera3511852023-06-14 14:12:59 +080011840 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
11841 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011842}
11843
developer72fb0bb2023-01-11 09:46:29 +080011844static const char *get_line_from_str_buf(const char *buf, char *line)
11845{
developera3511852023-06-14 14:12:59 +080011846 int i;
11847 int n = strlen(buf);
developer72fb0bb2023-01-11 09:46:29 +080011848
developera3511852023-06-14 14:12:59 +080011849 for (i = 0; i < n; i++) {
11850 line[i] = buf[i];
11851 if (buf[i] == '\n') {
11852 line[i] = '\0';
11853 return &buf[i + 1];
11854 }
11855 }
developer72fb0bb2023-01-11 09:46:29 +080011856
developera3511852023-06-14 14:12:59 +080011857 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080011858}
11859
11860INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
11861{
developera3511852023-06-14 14:12:59 +080011862 char interface_name[16] = {0};
11863 FILE *f = NULL;
11864 int auth_temp= -1;
11865 char cmd[256] = {0}, buf[2048] = {0};
11866 char *param = NULL, *value = NULL, *line=NULL;
11867 size_t len = 0;
11868 wifi_associated_dev3_t *dev=NULL;
developer75bd10c2023-06-27 11:34:08 +080011869 int res;
developer72fb0bb2023-01-11 09:46:29 +080011870
developera3511852023-06-14 14:12:59 +080011871 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11872 *associated_dev_array = NULL;
11873 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11874 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080011875
11876 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
11877 if (os_snprintf_error(sizeof(cmd), res)) {
11878 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11879 return RETURN_ERR;
11880 }
11881
developera3511852023-06-14 14:12:59 +080011882 _syscmd(cmd, buf, sizeof(buf));
11883 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011884
developera3511852023-06-14 14:12:59 +080011885 if (*output_array_size <= 0)
11886 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011887
developera3511852023-06-14 14:12:59 +080011888 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
developer86035662023-06-28 19:21:12 +080011889
11890 if (dev == NULL) {
11891 wifi_debug(DEBUG_ERROR, "calloc fail\n");
11892 return RETURN_ERR;
11893 }
developera3511852023-06-14 14:12:59 +080011894 *associated_dev_array = dev;
developer32f2a182023-06-27 19:50:41 +080011895 res = snprintf(cmd, sizeof(cmd),
11896 "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
developer75bd10c2023-06-27 11:34:08 +080011897 if (os_snprintf_error(sizeof(cmd), res)) {
11898 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11899 return RETURN_ERR;
11900 }
11901
developera3511852023-06-14 14:12:59 +080011902 _syscmd(cmd,buf,sizeof(buf));
11903 f = fopen("/tmp/diagnostic3_devices.txt", "r");
11904 if (f == NULL)
11905 {
11906 *output_array_size=0;
11907 return RETURN_ERR;
11908 }
11909 while ((getline(&line, &len, f)) != -1)
11910 {
11911 param = strtok(line, "=");
11912 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +080011913
developera3511852023-06-14 14:12:59 +080011914 if( strcmp("flags",param) == 0 )
11915 {
11916 value[strlen(value)-1]='\0';
11917 if(strstr (value,"AUTHORIZED") != NULL )
11918 {
11919 auth_temp++;
11920 dev[auth_temp].cli_AuthenticationState = 1;
11921 dev[auth_temp].cli_Active = 1;
11922 }
11923 } else if (auth_temp < 0) {
11924 continue;
11925 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
11926 {
11927 value[strlen(value)-1]='\0';
11928 sscanf(value, "%x:%x:%x:%x:%x:%x",
11929 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
11930 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
11931 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
11932 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
11933 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
11934 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
11935 } else if (strcmp("signal", param) == 0) {
11936 value[strlen(value)-1]='\0';
11937 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
11938 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
11939 }
11940 }
developer0d26f2c2023-05-25 19:46:36 +080011941 if (line)
developera3511852023-06-14 14:12:59 +080011942 free(line);
11943 fclose(f);
11944 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11945 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011946}
developer72fb0bb2023-01-11 09:46:29 +080011947
11948/* getIPAddress function */
11949/**
11950* @description Returning IpAddress of the Matched String
11951*
developer69b61b02023-03-07 17:17:44 +080011952* @param
developer72fb0bb2023-01-11 09:46:29 +080011953* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080011954* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080011955* @return The status of the operation
11956* @retval RETURN_OK if successful
11957* @retval RETURN_ERR if any error is detected
11958*
11959*/
11960
11961INT getIPAddress(char *str,char *ipaddr)
11962{
developera3511852023-06-14 14:12:59 +080011963 FILE *fp = NULL;
11964 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
11965 int LeaseTime = 0,ret = 0;
developer32f2a182023-06-27 19:50:41 +080011966 unsigned long len;
11967
developera3511852023-06-14 14:12:59 +080011968 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
11969 {
11970 return RETURN_ERR;
11971 }
developer72fb0bb2023-01-11 09:46:29 +080011972
developera3511852023-06-14 14:12:59 +080011973 while ( fgets(buf, sizeof(buf), fp)!= NULL )
11974 {
11975 /*
11976 Sample:sss
11977 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
11978 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
11979 */
11980 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
11981 &(LeaseTime),
11982 phyAddr,
11983 ipAddr,
11984 hostName
11985 );
11986 if(ret != 4)
11987 continue;
developer32f2a182023-06-27 19:50:41 +080011988 if (strcmp(str,phyAddr) == 0) {
11989 len = strlen(ipAddr);
11990 strncpy(ipaddr, ipAddr, len);
11991 ipaddr[len] = '\0';
11992 }
developera3511852023-06-14 14:12:59 +080011993 }
11994 fclose(fp);
11995 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011996}
11997
11998/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
11999/**
12000* @description Returning Inactive wireless connected clients informations
12001*
developer69b61b02023-03-07 17:17:44 +080012002* @param
developer72fb0bb2023-01-11 09:46:29 +080012003* @filename Holding private_wifi 2g/5g content files
12004* @associated_dev_array Having inactiv wireless clients informations
12005* @output_array_size Returning Inactive wireless counts
12006* @return The status of the operation
12007* @retval RETURN_OK if successful
12008* @retval RETURN_ERR if any error is detected
12009*
12010*/
12011
12012INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
12013{
developera3511852023-06-14 14:12:59 +080012014 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12015 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
12016 FILE *fp = NULL;
12017 int arr[MACADDRESS_SIZE] = {0};
12018 unsigned char mac[MACADDRESS_SIZE] = {0};
12019 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
developer86035662023-06-28 19:21:12 +080012020 int res;
12021
12022 res = snprintf(buf, sizeof(buf), "cat %s | grep Station | sort | uniq | wc -l",filename);
12023 if (os_snprintf_error(sizeof(buf), res)) {
12024 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12025 return RETURN_ERR;
12026 }
developera3511852023-06-14 14:12:59 +080012027 fp = popen(buf,"r");
12028 if(fp == NULL)
12029 return RETURN_ERR;
12030 else
12031 {
12032 fgets(path,sizeof(path),fp);
12033 maccount = atoi(path);
12034 }
12035 pclose(fp);
12036 *output_array_size = maccount;
12037 wifi_associated_dev3_t* temp = NULL;
developer9ce44382023-06-28 11:09:37 +080012038 if(*output_array_size > 0 && *output_array_size < MAX_ASSOCIATED_STA_NUM){
12039 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
12040 } else {
12041 return RETURN_ERR;
12042 }
12043
developera3511852023-06-14 14:12:59 +080012044 *associated_dev_array = temp;
12045 if(temp == NULL)
12046 {
12047 printf("Error Statement. Insufficient memory \n");
12048 return RETURN_ERR;
12049 }
12050 memset(buf,0,sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080012051 res = snprintf(buf, sizeof(buf),
12052 "cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
12053 if (os_snprintf_error(sizeof(buf), res)) {
12054 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12055 return RETURN_ERR;
12056 }
developera3511852023-06-14 14:12:59 +080012057 fp = popen(buf,"r");
12058 if (fp == NULL) {
12059 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
12060 return RETURN_ERR;
12061 }
12062 for(count = 0; count < maccount ; count++)
12063 {
12064 fgets(path,sizeof(path),fp);
12065 for(i = 0; path[i]!='\n';i++)
12066 str[i]=path[i];
12067 str[i]='\0';
12068 getIPAddress(str,ipaddr);
12069 memset(buf,0,sizeof(buf));
12070 if(strlen(ipaddr) > 0)
12071 {
developer32f2a182023-06-27 19:50:41 +080012072 res = snprintf(buf, sizeof(buf), "ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1", ipaddr);
12073 if (os_snprintf_error(sizeof(buf), res)) {
12074 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12075 return RETURN_ERR;
12076 }
developera3511852023-06-14 14:12:59 +080012077 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
12078 {
12079 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12080 {
12081 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12082 {
12083 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012084
developera3511852023-06-14 14:12:59 +080012085 }
12086 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
12087 fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]);
12088 }
12089 temp[count].cli_AuthenticationState = 0; //TODO
12090 temp[count].cli_Active = 0; //TODO
12091 temp[count].cli_SignalStrength = 0;
12092 }
12093 else //Active wireless clients info
12094 {
12095 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12096 {
12097 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12098 {
12099 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012100
developera3511852023-06-14 14:12:59 +080012101 }
12102 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
12103 fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]);
12104 }
12105 temp[count].cli_Active = 1;
12106 }
12107 }
12108 memset(ipaddr,0,sizeof(ipaddr));
12109 }
12110 pclose(fp);
12111 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12112 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012113}
12114//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
12115//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
12116//To get Band Steering Capability
12117INT wifi_getBandSteeringCapability(BOOL *support)
12118{
developera3511852023-06-14 14:12:59 +080012119 *support = FALSE;
12120 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012121}
12122
12123
12124//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
12125//To get Band Steering enable status
12126INT wifi_getBandSteeringEnable(BOOL *enable)
12127{
developera3511852023-06-14 14:12:59 +080012128 *enable = FALSE;
12129 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012130}
12131
12132//To turn on/off Band steering
12133INT wifi_setBandSteeringEnable(BOOL enable)
12134{
developera3511852023-06-14 14:12:59 +080012135 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012136}
12137
12138//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
12139//To get Band Steering AP group
12140INT wifi_getBandSteeringApGroup(char *output_ApGroup)
12141{
developera3511852023-06-14 14:12:59 +080012142 if (NULL == output_ApGroup)
12143 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012144
developer32f2a182023-06-27 19:50:41 +080012145 memcpy(output_ApGroup, "1,2", 3);
12146 output_ApGroup[3] = '\0';
developera3511852023-06-14 14:12:59 +080012147 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012148}
12149
12150//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
12151//to set and read the band steering BandUtilizationThreshold parameters
12152INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
12153{
developera3511852023-06-14 14:12:59 +080012154 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012155}
12156
12157INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
12158{
developera3511852023-06-14 14:12:59 +080012159 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012160}
12161
12162//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
12163//to set and read the band steering RSSIThreshold parameters
12164INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
12165{
developera3511852023-06-14 14:12:59 +080012166 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012167}
12168
12169INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
12170{
developera3511852023-06-14 14:12:59 +080012171 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012172}
12173
12174
12175//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
12176//to set and read the band steering physical modulation rate threshold parameters
12177INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
12178{
developera3511852023-06-14 14:12:59 +080012179 //If chip is not support, return -1
12180 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012181}
12182
12183INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
12184{
developera3511852023-06-14 14:12:59 +080012185 //If chip is not support, return -1
12186 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012187}
12188
12189//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
12190//to set and read the inactivity time (in seconds) for steering under overload condition
12191INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
12192{
developera3511852023-06-14 14:12:59 +080012193 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012194}
12195
12196INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
12197{
developera3511852023-06-14 14:12:59 +080012198 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012199}
12200
12201//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
12202//to set and read the inactivity time (in seconds) for steering under Idle condition
12203INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
12204{
developera3511852023-06-14 14:12:59 +080012205 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012206}
12207
12208INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
12209{
developera3511852023-06-14 14:12:59 +080012210 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012211}
12212
12213//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
12214//pClientMAC[64]
12215//pSourceSSIDIndex[64]
12216//pDestSSIDIndex[64]
12217//pSteeringReason[256]
12218INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
12219{
developera3511852023-06-14 14:12:59 +080012220 //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
12221 *pSteeringTime=time(NULL);
12222 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
12223 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012224}
12225
12226INT wifi_ifConfigDown(INT apIndex)
12227{
developera3511852023-06-14 14:12:59 +080012228 INT status = RETURN_OK;
12229 char cmd[64];
developere40952c2023-06-15 18:46:43 +080012230 int res;
developer72fb0bb2023-01-11 09:46:29 +080012231
developere40952c2023-06-15 18:46:43 +080012232 res = snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
12233 if (os_snprintf_error(sizeof(cmd), res)) {
12234 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12235 return RETURN_ERR;
12236 }
developera3511852023-06-14 14:12:59 +080012237 printf("%s: %s\n", __func__, cmd);
12238 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080012239
developera3511852023-06-14 14:12:59 +080012240 return status;
developer72fb0bb2023-01-11 09:46:29 +080012241}
12242
12243INT wifi_ifConfigUp(INT apIndex)
12244{
developera3511852023-06-14 14:12:59 +080012245 char interface_name[16] = {0};
12246 char cmd[128];
12247 char buf[1024];
developere40952c2023-06-15 18:46:43 +080012248 int res;
developer72fb0bb2023-01-11 09:46:29 +080012249
developera3511852023-06-14 14:12:59 +080012250 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12251 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012252 res = snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
12253 if (os_snprintf_error(sizeof(cmd), res)) {
12254 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12255 return RETURN_ERR;
12256 }
developera3511852023-06-14 14:12:59 +080012257 _syscmd(cmd, buf, sizeof(buf));
12258 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012259}
12260
12261//>> Deprecated. Replace with wifi_applyRadioSettings
12262INT wifi_pushBridgeInfo(INT apIndex)
12263{
developerb2977562023-05-24 17:54:12 +080012264 char ip[32] = {0};
12265 char subnet[32] = {0};
12266 char bridge[32] = {0};
12267 char cmd[128] = {0};
12268 char buf[1024] = {0};
developere40952c2023-06-15 18:46:43 +080012269 int res;
developer72fb0bb2023-01-11 09:46:29 +080012270
developerb2977562023-05-24 17:54:12 +080012271 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080012272
developere40952c2023-06-15 18:46:43 +080012273 res = snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
12274 if (os_snprintf_error(sizeof(cmd), res)) {
12275 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12276 return RETURN_ERR;
12277 }
developerb2977562023-05-24 17:54:12 +080012278 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012279
developerb2977562023-05-24 17:54:12 +080012280 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012281}
12282
12283INT wifi_pushChannel(INT radioIndex, UINT channel)
12284{
developera3511852023-06-14 14:12:59 +080012285 char interface_name[16] = {0};
12286 char cmd[128];
12287 char buf[1024];
developere40952c2023-06-15 18:46:43 +080012288 int res;
developer72fb0bb2023-01-11 09:46:29 +080012289
developera3511852023-06-14 14:12:59 +080012290 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12291 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012292 res = snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
12293 if (os_snprintf_error(sizeof(cmd), res)) {
12294 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12295 return RETURN_ERR;
12296 }
developera3511852023-06-14 14:12:59 +080012297 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012298
developera3511852023-06-14 14:12:59 +080012299 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012300}
12301
12302INT wifi_pushChannelMode(INT radioIndex)
12303{
developera3511852023-06-14 14:12:59 +080012304 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
12305 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012306}
12307
12308INT wifi_pushDefaultValues(INT radioIndex)
12309{
developera3511852023-06-14 14:12:59 +080012310 //Apply Comcast specified default radio settings instantly
12311 //AMPDU=1
12312 //AMPDUFrames=32
12313 //AMPDULim=50000
12314 //txqueuelen=1000
developer72fb0bb2023-01-11 09:46:29 +080012315
developera3511852023-06-14 14:12:59 +080012316 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012317}
12318
12319INT wifi_pushTxChainMask(INT radioIndex)
12320{
developera3511852023-06-14 14:12:59 +080012321 //Apply default TxChainMask instantly
12322 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012323}
12324
12325INT wifi_pushRxChainMask(INT radioIndex)
12326{
developera3511852023-06-14 14:12:59 +080012327 //Apply default RxChainMask instantly
12328 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012329}
12330
12331INT wifi_pushSSID(INT apIndex, CHAR *ssid)
12332{
developer7e4a2a62023-04-06 19:56:03 +080012333 INT status;
developer72fb0bb2023-01-11 09:46:29 +080012334
developer7e4a2a62023-04-06 19:56:03 +080012335 status = wifi_setSSIDName(apIndex, ssid);
12336 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080012337
developer7e4a2a62023-04-06 19:56:03 +080012338 return status;
developer72fb0bb2023-01-11 09:46:29 +080012339}
12340
12341INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
12342{
developera3511852023-06-14 14:12:59 +080012343 int ret;
developerc1aa6532023-06-09 09:37:01 +080012344 ret = wifi_setApSsidAdvertisementEnable(apIndex, enable);
12345
12346 return ret;
developer72fb0bb2023-01-11 09:46:29 +080012347}
12348
12349INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
12350{
developera3511852023-06-14 14:12:59 +080012351 time_t now;
developere82c0ca2023-05-10 16:25:35 +080012352
12353 time(&now);
12354 if (now > radio_up_time[radioIndex])
12355 *output = now - radio_up_time[radioIndex];
12356 else {
12357 *output = 0;
12358 return RETURN_ERR;
12359 }
12360
developera3511852023-06-14 14:12:59 +080012361 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012362}
12363
12364INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
12365{
developera3511852023-06-14 14:12:59 +080012366 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012367}
12368
12369INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
12370{
developera3511852023-06-14 14:12:59 +080012371 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012372}
12373
12374//To-do
12375INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
12376{
developera3511852023-06-14 14:12:59 +080012377 char output[16]={'\0'};
12378 char config_file[MAX_BUF_SIZE] = {0};
12379 int res;
developer72fb0bb2023-01-11 09:46:29 +080012380
developera3511852023-06-14 14:12:59 +080012381 if (!output_string)
12382 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012383
developera3511852023-06-14 14:12:59 +080012384 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12385 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012386 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12387 return RETURN_ERR;
12388 }
developera3511852023-06-14 14:12:59 +080012389 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080012390
developera3511852023-06-14 14:12:59 +080012391 if (strlen(output) == 0)
developere40952c2023-06-15 18:46:43 +080012392 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080012393 else if (strncmp(output, "0", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012394 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080012395 else if (strncmp(output, "1", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012396 res = snprintf(output_string, 64, "Optional");
developera3511852023-06-14 14:12:59 +080012397 else if (strncmp(output, "2", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012398 res = snprintf(output_string, 64, "Required");
developera3511852023-06-14 14:12:59 +080012399 else {
12400 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
12401 return RETURN_ERR;
12402 }
developere40952c2023-06-15 18:46:43 +080012403 if (os_snprintf_error(64, res)) {
12404 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12405 return RETURN_ERR;
12406 }
developer72fb0bb2023-01-11 09:46:29 +080012407
developera3511852023-06-14 14:12:59 +080012408 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
12409 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012410}
12411INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
12412{
developera3511852023-06-14 14:12:59 +080012413 struct params params;
12414 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080012415 int res;
developer72fb0bb2023-01-11 09:46:29 +080012416
developera3511852023-06-14 14:12:59 +080012417 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12418 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
12419 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012420
developera3511852023-06-14 14:12:59 +080012421 params.name = "ieee80211w";
12422 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
12423 params.value = "0";
12424 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
12425 params.value = "1";
12426 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
12427 params.value = "2";
12428 else{
12429 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
12430 return RETURN_ERR;
12431 }
developer75bd10c2023-06-27 11:34:08 +080012432
12433 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12434 if (os_snprintf_error(sizeof(config_file), res)) {
12435 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12436 return RETURN_ERR;
12437 }
12438
developera3511852023-06-14 14:12:59 +080012439 wifi_hostapdWrite(config_file, &params, 1);
12440 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
12441 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012442}
12443INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
12444{
developera3511852023-06-14 14:12:59 +080012445 char output[16]={'\0'};
12446 char config_file[MAX_BUF_SIZE] = {0};
12447 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080012448 int res;
developer72fb0bb2023-01-11 09:46:29 +080012449
developera3511852023-06-14 14:12:59 +080012450 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12451 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080012452 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
12453 if (os_snprintf_error(sizeof(config_file), res)) {
12454 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12455 return RETURN_ERR;
12456 }
developera3511852023-06-14 14:12:59 +080012457 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080012458
developera3511852023-06-14 14:12:59 +080012459 if (strncmp(output, "0", 1) == 0)
12460 *output_bool = FALSE;
12461 else if (strncmp(output, "1", 1) == 0)
12462 *output_bool = TRUE;
12463 else if (strncmp(output, "2", 1) == 0)
12464 *output_bool = TRUE;
12465 else if (strncmp(output, "3", 1) == 0)
12466 *output_bool = TRUE;
12467 else
12468 *output_bool = FALSE;
12469 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012470
developera3511852023-06-14 14:12:59 +080012471 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012472}
12473
12474INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
12475{
developera3511852023-06-14 14:12:59 +080012476 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012477}
12478
12479INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
12480{
developera3511852023-06-14 14:12:59 +080012481 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012482}
12483
12484INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
12485{
developera3511852023-06-14 14:12:59 +080012486 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012487}
12488
12489INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
12490{
developera3511852023-06-14 14:12:59 +080012491 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12492 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080012493 char tmp_output[MAX_BUF_SIZE] = {0};
developera3511852023-06-14 14:12:59 +080012494 int res;
developer72fb0bb2023-01-11 09:46:29 +080012495
developera3511852023-06-14 14:12:59 +080012496 if (NULL == output)
12497 return RETURN_ERR;
12498 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
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,"hw_mode",output,64);
developer72fb0bb2023-01-11 09:46:29 +080012504
developer32f2a182023-06-27 19:50:41 +080012505 if(strcmp(output,"b")==0) {
12506 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,11");
12507 if (os_snprintf_error(sizeof(tmp_output), res)) {
12508 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12509 return RETURN_ERR;
12510 }
12511 } else if (strcmp(output,"a")==0) {
12512 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "6,9,11,12,18,24,36,48,54");
12513 if (os_snprintf_error(sizeof(tmp_output), res)) {
12514 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12515 return RETURN_ERR;
12516 }
12517 } else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) {
12518 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
12519 if (os_snprintf_error(sizeof(tmp_output), res)) {
12520 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12521 return RETURN_ERR;
12522 }
developer75bd10c2023-06-27 11:34:08 +080012523 }
developer32f2a182023-06-27 19:50:41 +080012524 memcpy(output, tmp_output, strlen(tmp_output));
12525 output[strlen(tmp_output)] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012526
developera3511852023-06-14 14:12:59 +080012527 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12528 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012529}
12530
12531INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
12532{
developera3511852023-06-14 14:12:59 +080012533 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12534 char *temp;
developer32f2a182023-06-27 19:50:41 +080012535 char temp_output[128] = {0};
12536 char temp_TransmitRates[128] = {0};
developera3511852023-06-14 14:12:59 +080012537 char config_file[MAX_BUF_SIZE] = {0};
12538 int res;
developer32f2a182023-06-27 19:50:41 +080012539 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080012540
developera3511852023-06-14 14:12:59 +080012541 if (NULL == output)
12542 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012543
developera3511852023-06-14 14:12:59 +080012544 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12545 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012546 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12547 return RETURN_ERR;
12548 }
developera3511852023-06-14 14:12:59 +080012549 wifi_hostapdRead(config_file,"supported_rates",output,64);
developer72fb0bb2023-01-11 09:46:29 +080012550
developera3511852023-06-14 14:12:59 +080012551 if (strlen(output) == 0) {
12552 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
12553 return RETURN_OK;
12554 }
developer32f2a182023-06-27 19:50:41 +080012555 len = strlen(output);
12556 if (len >= sizeof(temp_TransmitRates)) {
12557 wifi_debug(DEBUG_ERROR, "Unexpected strlen(output)\n");
12558 return RETURN_ERR;
12559 }
12560 strncpy(temp_TransmitRates, output, len);
developera3511852023-06-14 14:12:59 +080012561 temp = strtok(temp_TransmitRates," ");
12562 while(temp!=NULL)
12563 {
12564 temp[strlen(temp)-1]=0;
12565 if((temp[0]=='5') && (temp[1]=='\0'))
12566 {
12567 temp="5.5";
12568 }
developer32f2a182023-06-27 19:50:41 +080012569 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp)) {
12570 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12571 return RETURN_ERR;
12572 }
12573 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012574 temp = strtok(NULL," ");
12575 if(temp!=NULL)
12576 {
developer32f2a182023-06-27 19:50:41 +080012577 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
12578 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12579 return RETURN_ERR;
12580 }
12581 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012582 }
12583 }
developer32f2a182023-06-27 19:50:41 +080012584 len = strlen(temp_output);
12585 strncpy(output, temp_output, len);
12586 output[len] = '\0';
developera3511852023-06-14 14:12:59 +080012587 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012588
developera3511852023-06-14 14:12:59 +080012589 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012590}
12591
12592INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
12593{
developera3511852023-06-14 14:12:59 +080012594 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012595}
12596
12597
12598INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
12599{
developera3511852023-06-14 14:12:59 +080012600 int i=0;
12601 char *temp;
12602 char temp1[128] = {0};
12603 char temp_output[128] = {0};
12604 char temp_TransmitRates[128] = {0};
12605 struct params params={'\0'};
12606 char config_file[MAX_BUF_SIZE] = {0};
12607 wifi_band band = wifi_index_to_band(wlanIndex);
developer32f2a182023-06-27 19:50:41 +080012608 unsigned long len;
12609 int res;
developer72fb0bb2023-01-11 09:46:29 +080012610
developera3511852023-06-14 14:12:59 +080012611 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12612 if(NULL == output)
12613 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080012614
12615 len = strlen(output);
12616 if (len >= sizeof(temp_TransmitRates)) {
12617 wifi_debug(DEBUG_ERROR, "not enough room in temp_TransmitRates\n");
12618 return RETURN_ERR;
12619 }
12620 strncpy(temp_TransmitRates, output, len);
12621 temp_TransmitRates[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012622
developera3511852023-06-14 14:12:59 +080012623 for(i=0;i<strlen(temp_TransmitRates);i++)
12624 {
12625 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
12626 {
12627 continue;
12628 }
12629 else
12630 {
12631 return RETURN_ERR;
12632 }
12633 }
developera3511852023-06-14 14:12:59 +080012634 temp = strtok(temp_TransmitRates,",");
12635 while(temp!=NULL)
12636 {
developer32f2a182023-06-27 19:50:41 +080012637 len = strlen(temp);
12638 if (len >= sizeof(temp1)) {
12639 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
12640 return RETURN_ERR;
12641 }
12642 strncpy(temp1, temp, len);
12643 temp1[len] = '\0';
developera3511852023-06-14 14:12:59 +080012644 if(band == band_5)
12645 {
12646 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
12647 {
12648 return RETURN_ERR;
12649 }
12650 }
developer72fb0bb2023-01-11 09:46:29 +080012651
developer32f2a182023-06-27 19:50:41 +080012652 if(strcmp(temp,"5.5")==0) {
12653 strncpy(temp1, "55", 2);
12654 temp1[2] = '\0';
12655 } else {
12656 if ((sizeof(temp1) - strlen(temp1)) <= 1) {
12657 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
12658 return RETURN_ERR;
12659 }
12660 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +080012661 }
developer32f2a182023-06-27 19:50:41 +080012662
12663 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp1)) {
12664 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12665 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080012666 }
developer32f2a182023-06-27 19:50:41 +080012667 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012668 temp = strtok(NULL,",");
12669 if(temp!=NULL)
12670 {
developer32f2a182023-06-27 19:50:41 +080012671 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
12672 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
12673 return RETURN_ERR;
12674 }
12675 strncat(temp_output, " ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012676 }
12677 }
developer32f2a182023-06-27 19:50:41 +080012678 len = strlen(temp_output);
12679 strncpy(output, temp_output, len);
12680 output[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012681
developera3511852023-06-14 14:12:59 +080012682 params.name = "supported_rates";
12683 params.value = output;
developer72fb0bb2023-01-11 09:46:29 +080012684
developera3511852023-06-14 14:12:59 +080012685 wifi_dbg_printf("\n%s:",__func__);
12686 wifi_dbg_printf("params.value=%s\n",params.value);
developer32f2a182023-06-27 19:50:41 +080012687 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12688 if (os_snprintf_error(sizeof(config_file), res)) {
12689 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12690 return RETURN_ERR;
12691 }
developera3511852023-06-14 14:12:59 +080012692 wifi_hostapdWrite(config_file,&params,1);
12693 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012694
developera3511852023-06-14 14:12:59 +080012695 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012696}
12697
12698
12699static char *sncopy(char *dst, int dst_sz, const char *src)
12700{
developera3511852023-06-14 14:12:59 +080012701 if (src && dst && dst_sz > 0) {
12702 strncpy(dst, src, dst_sz);
12703 dst[dst_sz - 1] = '\0';
12704 }
12705 return dst;
developer72fb0bb2023-01-11 09:46:29 +080012706}
12707
12708static int util_get_sec_chan_offset(int channel, const char* ht_mode)
12709{
developera3511852023-06-14 14:12:59 +080012710 if (0 == strcmp(ht_mode, "HT40") ||
12711 0 == strcmp(ht_mode, "HT80") ||
12712 0 == strcmp(ht_mode, "HT160")) {
12713 switch (channel) {
12714 case 1 ... 7:
12715 case 36:
12716 case 44:
12717 case 52:
12718 case 60:
12719 case 100:
12720 case 108:
12721 case 116:
12722 case 124:
12723 case 132:
12724 case 140:
12725 case 149:
12726 case 157:
12727 return 1;
12728 case 8 ... 13:
12729 case 40:
12730 case 48:
12731 case 56:
12732 case 64:
12733 case 104:
12734 case 112:
12735 case 120:
12736 case 128:
12737 case 136:
12738 case 144:
12739 case 153:
12740 case 161:
12741 return -1;
12742 default:
12743 return -EINVAL;
12744 }
12745 }
developer72fb0bb2023-01-11 09:46:29 +080012746
developera3511852023-06-14 14:12:59 +080012747 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080012748}
12749
12750static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
12751{
developera3511852023-06-14 14:12:59 +080012752 int idx = channel%8;
12753 if (0 == strcmp(ht_mode, "HT40") ||
12754 0 == strcmp(ht_mode, "HT80") ||
12755 0 == strcmp(ht_mode, "HT160")) {
12756 switch (idx) {
12757 case 1:
12758 return 1;
12759 case 5:
12760 return -1;
12761 default:
12762 return -EINVAL;
12763 }
12764 }
developer72fb0bb2023-01-11 09:46:29 +080012765
developera3511852023-06-14 14:12:59 +080012766 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080012767}
12768static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
12769{
developera3511852023-06-14 14:12:59 +080012770 if (NULL == hw_mode) return;
developer72fb0bb2023-01-11 09:46:29 +080012771
developera3511852023-06-14 14:12:59 +080012772 if (0 == strcmp(hw_mode, "ac"))
12773 sncopy(bw_mode, bw_mode_len, "ht vht");
developer72fb0bb2023-01-11 09:46:29 +080012774
developera3511852023-06-14 14:12:59 +080012775 if (0 == strcmp(hw_mode, "n"))
12776 sncopy(bw_mode, bw_mode_len, "ht");
developer72fb0bb2023-01-11 09:46:29 +080012777
developera3511852023-06-14 14:12:59 +080012778 return;
developer72fb0bb2023-01-11 09:46:29 +080012779}
12780
12781static int util_chan_to_freq(int chan)
12782{
developera3511852023-06-14 14:12:59 +080012783 if (chan == 14)
12784 return 2484;
12785 else if (chan < 14)
12786 return 2407 + chan * 5;
12787 else if (chan >= 182 && chan <= 196)
12788 return 4000 + chan * 5;
12789 else
12790 return 5000 + chan * 5;
12791 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012792}
12793
12794static int util_6G_chan_to_freq(int chan)
12795{
developera3511852023-06-14 14:12:59 +080012796 if (chan)
12797 return 5950 + chan * 5;
12798 else
12799 return 0;
developer69b61b02023-03-07 17:17:44 +080012800
developer72fb0bb2023-01-11 09:46:29 +080012801}
12802const int *util_unii_5g_chan2list(int chan, int width)
12803{
developera3511852023-06-14 14:12:59 +080012804 static const int lists[] = {
12805 // <width>, <chan1>, <chan2>..., 0,
12806 20, 36, 0,
12807 20, 40, 0,
12808 20, 44, 0,
12809 20, 48, 0,
12810 20, 52, 0,
12811 20, 56, 0,
12812 20, 60, 0,
12813 20, 64, 0,
12814 20, 100, 0,
12815 20, 104, 0,
12816 20, 108, 0,
12817 20, 112, 0,
12818 20, 116, 0,
12819 20, 120, 0,
12820 20, 124, 0,
12821 20, 128, 0,
12822 20, 132, 0,
12823 20, 136, 0,
12824 20, 140, 0,
12825 20, 144, 0,
12826 20, 149, 0,
12827 20, 153, 0,
12828 20, 157, 0,
12829 20, 161, 0,
12830 20, 165, 0,
12831 40, 36, 40, 0,
12832 40, 44, 48, 0,
12833 40, 52, 56, 0,
12834 40, 60, 64, 0,
12835 40, 100, 104, 0,
12836 40, 108, 112, 0,
12837 40, 116, 120, 0,
12838 40, 124, 128, 0,
12839 40, 132, 136, 0,
12840 40, 140, 144, 0,
12841 40, 149, 153, 0,
12842 40, 157, 161, 0,
12843 80, 36, 40, 44, 48, 0,
12844 80, 52, 56, 60, 64, 0,
12845 80, 100, 104, 108, 112, 0,
12846 80, 116, 120, 124, 128, 0,
12847 80, 132, 136, 140, 144, 0,
12848 80, 149, 153, 157, 161, 0,
12849 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
12850 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
12851 -1 // final delimiter
12852 };
12853 const int *start;
12854 const int *p;
developer72fb0bb2023-01-11 09:46:29 +080012855
developera3511852023-06-14 14:12:59 +080012856 for (p = lists; *p != -1; p++) {
12857 if (*p == width) {
12858 for (start = ++p; *p != 0; p++) {
12859 if (*p == chan)
12860 return start;
12861 }
12862 }
12863 // move to the end of channel list of given width
12864 while (*p != 0) {
12865 p++;
12866 }
12867 }
developer72fb0bb2023-01-11 09:46:29 +080012868
developera3511852023-06-14 14:12:59 +080012869 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080012870}
12871
12872static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
12873{
developera3511852023-06-14 14:12:59 +080012874 if (NULL == ht_mode)
12875 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012876
developera3511852023-06-14 14:12:59 +080012877 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
12878 const int *chans = util_unii_5g_chan2list(channel, width);
12879 int sum = 0;
12880 int cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080012881
developera3511852023-06-14 14:12:59 +080012882 if (NULL == chans)
12883 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012884
developera3511852023-06-14 14:12:59 +080012885 while (*chans) {
12886 sum += *chans;
12887 cnt++;
12888 chans++;
12889 }
12890 if (cnt == 0)
12891 return 0;
12892 return sum / cnt;
developer72fb0bb2023-01-11 09:46:29 +080012893}
12894
12895static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
12896{
developera3511852023-06-14 14:12:59 +080012897 if (NULL == ht_mode)
12898 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012899
developera3511852023-06-14 14:12:59 +080012900 int width = strtol((ht_mode + 2), NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080012901
developera3511852023-06-14 14:12:59 +080012902 int idx = 0 ;
12903 int centerchan = 0;
12904 int chan_ofs = 1;
developer72fb0bb2023-01-11 09:46:29 +080012905
developera3511852023-06-14 14:12:59 +080012906 if (width == 40){
12907 idx = ((channel/4) + chan_ofs)%2;
12908 switch (idx) {
12909 case 0:
12910 centerchan = (channel - 2);
12911 break;
12912 case 1:
12913 centerchan = (channel + 2);
12914 break;
12915 default:
12916 return -EINVAL;
12917 }
12918 }else if (width == 80){
12919 idx = ((channel/4) + chan_ofs)%4;
12920 switch (idx) {
12921 case 0:
12922 centerchan = (channel - 6);
12923 break;
12924 case 1:
12925 centerchan = (channel + 6);
12926 break;
12927 case 2:
12928 centerchan = (channel + 2);
12929 break;
12930 case 3:
12931 centerchan = (channel - 2);
12932 break;
12933 default:
12934 return -EINVAL;
12935 }
12936 }else if (width == 160){
12937 switch (channel) {
12938 case 1 ... 29:
12939 centerchan = 15;
12940 break;
12941 case 33 ... 61:
12942 centerchan = 47;
12943 break;
12944 case 65 ... 93:
12945 centerchan = 79;
12946 break;
12947 case 97 ... 125:
12948 centerchan = 111;
12949 break;
12950 case 129 ... 157:
12951 centerchan = 143;
12952 break;
12953 case 161 ... 189:
12954 centerchan = 175;
12955 break;
12956 case 193 ... 221:
12957 centerchan = 207;
12958 break;
12959 default:
12960 return -EINVAL;
12961 }
12962 }
12963 return centerchan;
developer72fb0bb2023-01-11 09:46:29 +080012964}
12965static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
12966{
developera3511852023-06-14 14:12:59 +080012967 BOOL onlyG, onlyN, onlyA;
12968 CHAR tmp[64];
12969 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
12970 if (ret == RETURN_OK) {
12971 sncopy(hw_mode, hw_mode_size, tmp);
12972 }
12973 return ret;
developer72fb0bb2023-01-11 09:46:29 +080012974}
12975
12976INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
12977{
developera3511852023-06-14 14:12:59 +080012978 // Sample commands:
12979 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
12980 // hostapd_cli -i wifi0 chan_switch 30 2437
12981 int ret = 0;
12982 char center_freq1_str[32] = ""; // center_freq1=%d
12983 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
12984 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
12985 char hw_mode[16] = ""; // n|ac
12986 char bw_mode[16] = ""; // ht|ht vht
12987 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
12988 char interface_name[16] = {0};
12989 int sec_chan_offset;
12990 int width;
12991 char config_file[64] = {0};
12992 char *ext_str = "None";
12993 wifi_band band = band_invalid;
12994 int center_chan = 0;
12995 int center_freq1 = 0;
developere40952c2023-06-15 18:46:43 +080012996 int res;
developer72fb0bb2023-01-11 09:46:29 +080012997
developere40952c2023-06-15 18:46:43 +080012998 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
12999 if (os_snprintf_error(sizeof(config_file), res)) {
13000 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13001 return RETURN_ERR;
13002 }
developer72fb0bb2023-01-11 09:46:29 +080013003
developera3511852023-06-14 14:12:59 +080013004 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
13005 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013006
developera3511852023-06-14 14:12:59 +080013007 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013008
developera3511852023-06-14 14:12:59 +080013009 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013010
developera3511852023-06-14 14:12:59 +080013011 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
developer72fb0bb2023-01-11 09:46:29 +080013012
developera3511852023-06-14 14:12:59 +080013013 // Get radio mode HT20|HT40|HT80 etc.
13014 if (channel){
developere40952c2023-06-15 18:46:43 +080013015 res = snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
13016 if (os_snprintf_error(sizeof(ht_mode), res)) {
13017 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13018 return RETURN_ERR;
13019 }
developer72fb0bb2023-01-11 09:46:29 +080013020
developera3511852023-06-14 14:12:59 +080013021 // Provide bandwith if specified
13022 if (channel_width_MHz > 20) {
13023 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
13024 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
13025 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
developer72fb0bb2023-01-11 09:46:29 +080013026
developere40952c2023-06-15 18:46:43 +080013027 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
developera3511852023-06-14 14:12:59 +080013028 }else if (channel_width_MHz == 20){
developere40952c2023-06-15 18:46:43 +080013029 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
developera3511852023-06-14 14:12:59 +080013030 }
developer72fb0bb2023-01-11 09:46:29 +080013031
developere40952c2023-06-15 18:46:43 +080013032 if (os_snprintf_error(sizeof(opt_chan_info_str), res)) {
13033 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13034 return RETURN_ERR;
13035 }
developer72fb0bb2023-01-11 09:46:29 +080013036
developera3511852023-06-14 14:12:59 +080013037 if (channel_width_MHz > 20) {
13038 if (band == band_6){
13039 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
13040 if(center_chan){
13041 center_freq1 = util_6G_chan_to_freq(center_chan);
13042 }
13043 }else{
13044 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
13045 if(center_chan){
13046 center_freq1 = util_chan_to_freq(center_chan);
13047 }
13048 }
developer69b61b02023-03-07 17:17:44 +080013049
developera3511852023-06-14 14:12:59 +080013050 if (center_freq1)
developere40952c2023-06-15 18:46:43 +080013051 res = snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080013052
developera3511852023-06-14 14:12:59 +080013053 }
developere40952c2023-06-15 18:46:43 +080013054 if (os_snprintf_error(sizeof(center_freq1_str), res)) {
13055 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13056 return RETURN_ERR;
13057 }
developer72fb0bb2023-01-11 09:46:29 +080013058
developera3511852023-06-14 14:12:59 +080013059 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
13060 if (band == band_6){
13061 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
13062 }else{
13063 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
13064 }
developere40952c2023-06-15 18:46:43 +080013065 if (sec_chan_offset != -EINVAL) {
13066 res = snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
13067 if (os_snprintf_error(sizeof(sec_chan_offset_str), res)) {
13068 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13069 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013070 }
developere40952c2023-06-15 18:46:43 +080013071 }
developera3511852023-06-14 14:12:59 +080013072 // Only the first AP, other are hanging on the same radio
13073 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
13074 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080013075 wifi_debug(DEBUG_ERROR,"wifi_setChannel return error.\n");
developera3511852023-06-14 14:12:59 +080013076 return RETURN_ERR;
13077 }
13078 /* wifi_dbg_printf("execute: '%s'\n", cmd);
13079 ret = _syscmd(cmd, buf, sizeof(buf));
13080 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080013081
developera3511852023-06-14 14:12:59 +080013082 ret = wifi_setRadioChannel(radioIndex, channel);
13083 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080013084 wifi_debug(DEBUG_ERROR,"wifi_setRadioChannel return error.\n");
developera3511852023-06-14 14:12:59 +080013085 return RETURN_ERR;
13086 }
developer72fb0bb2023-01-11 09:46:29 +080013087
developera3511852023-06-14 14:12:59 +080013088 if (sec_chan_offset == 1)
13089 ext_str = "Above";
13090 else if (sec_chan_offset == -1)
13091 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080013092
developera3511852023-06-14 14:12:59 +080013093 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080013094
developera3511852023-06-14 14:12:59 +080013095 } else {
13096 if (channel_width_MHz > 20)
13097 ext_str = "Above";
13098 }
developer72fb0bb2023-01-11 09:46:29 +080013099
developera3511852023-06-14 14:12:59 +080013100 wifi_setRadioExtChannel(radioIndex, ext_str);
developer72fb0bb2023-01-11 09:46:29 +080013101
developera3511852023-06-14 14:12:59 +080013102 char mhz_str[16];
developere40952c2023-06-15 18:46:43 +080013103 res = snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
13104 if (os_snprintf_error(sizeof(mhz_str), res)) {
13105 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13106 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013107 }
developera3511852023-06-14 14:12:59 +080013108 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
developer72fb0bb2023-01-11 09:46:29 +080013109
developera3511852023-06-14 14:12:59 +080013110 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013111
developera3511852023-06-14 14:12:59 +080013112 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013113}
13114
13115INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
13116{
developera3511852023-06-14 14:12:59 +080013117 int index = -1;
13118 wifi_neighbor_ap2_t *scan_array = NULL;
13119 char cmd[256]={0};
13120 char buf[128]={0};
13121 char file_name[32] = {0};
13122 char filter_SSID[32] = {0};
13123 char line[256] = {0};
13124 char interface_name[16] = {0};
13125 char *ret = NULL;
13126 int freq=0;
13127 FILE *f = NULL;
developer86035662023-06-28 19:21:12 +080013128 long int channels_num = 0;
developera3511852023-06-14 14:12:59 +080013129 int vht_channel_width = 0;
13130 int get_noise_ret = RETURN_ERR;
13131 bool filter_enable = false;
13132 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
13133 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080013134 int res;
developer32f2a182023-06-27 19:50:41 +080013135 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080013136
developera3511852023-06-14 14:12:59 +080013137 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013138
developere40952c2023-06-15 18:46:43 +080013139 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
13140 if (os_snprintf_error(sizeof(file_name), res)) {
13141 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13142 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080013143 }
developera3511852023-06-14 14:12:59 +080013144 f = fopen(file_name, "r");
13145 if (f != NULL) {
developer86035662023-06-28 19:21:12 +080013146 if (fgets(filter_SSID, sizeof(file_name), f) == NULL) {
13147 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13148 pclose(f);
13149 return RETURN_ERR;
13150 }
developera3511852023-06-14 14:12:59 +080013151 if (strlen(filter_SSID) != 0)
13152 filter_enable = true;
13153 fclose(f);
13154 }
developer72fb0bb2023-01-11 09:46:29 +080013155
developera3511852023-06-14 14:12:59 +080013156 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
13157 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013158
developera3511852023-06-14 14:12:59 +080013159 phyId = radio_index_to_phy(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013160
developere40952c2023-06-15 18:46:43 +080013161 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
13162 if (os_snprintf_error(sizeof(cmd), res)) {
13163 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13164 return RETURN_ERR;
13165 }
developera3511852023-06-14 14:12:59 +080013166 _syscmd(cmd, buf, sizeof(buf));
developer86035662023-06-28 19:21:12 +080013167 if (hal_strtol(buf, 10, &channels_num) < 0) {
13168 wifi_debug(DEBUG_ERROR, "strtol fail\n");
13169 return RETURN_ERR;
13170 }
developer72fb0bb2023-01-11 09:46:29 +080013171
developer32f2a182023-06-27 19:50:41 +080013172 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
developera3511852023-06-14 14:12:59 +080013173 // 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 +080013174 if (os_snprintf_error(sizeof(cmd), res)) {
13175 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13176 return RETURN_ERR;
13177 }
13178
developer86035662023-06-28 19:21:12 +080013179 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developera3511852023-06-14 14:12:59 +080013180 if ((f = popen(cmd, "r")) == NULL) {
13181 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
13182 return RETURN_ERR;
13183 }
developer69b61b02023-03-07 17:17:44 +080013184
developera3511852023-06-14 14:12:59 +080013185 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
developer86035662023-06-28 19:21:12 +080013186
13187 if (channels_noise_arr == NULL) {
13188 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13189 goto err;
developer9ce44382023-06-28 11:09:37 +080013190 }
developer86035662023-06-28 19:21:12 +080013191 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
13192
developera3511852023-06-14 14:12:59 +080013193 ret = fgets(line, sizeof(line), f);
13194 while (ret != NULL) {
13195 if(strstr(line, "BSS") != NULL) { // new neighbor info
13196 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
13197 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
13198 // 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 +080013199
developera3511852023-06-14 14:12:59 +080013200 if (!filter_BSS) {
13201 index++;
13202 wifi_neighbor_ap2_t *tmp;
13203 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
13204 if (tmp == NULL) { // no more memory to use
13205 index--;
13206 wifi_dbg_printf("%s: realloc failed\n", __func__);
13207 break;
13208 }
13209 scan_array = tmp;
13210 }
13211 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +080013212
developera3511852023-06-14 14:12:59 +080013213 filter_BSS = false;
developer86035662023-06-28 19:21:12 +080013214 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
13215 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13216 goto err;
13217 }
developerc79e9172023-06-06 19:48:03 +080013218 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +080013219 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +080013220 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +080013221 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +080013222 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +080013223 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
13224 } else if (strstr(line, "freq") != NULL) {
developer86035662023-06-28 19:21:12 +080013225 if (sscanf(line," freq: %d", &freq) != 1) {
13226 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13227 goto err;
13228 }
developera3511852023-06-14 14:12:59 +080013229 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080013230
developera3511852023-06-14 14:12:59 +080013231 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +080013232 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080013233 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +080013234 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080013235 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +080013236 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080013237 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
13238 }
13239 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +080013240 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080013241 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +080013242 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080013243 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +080013244 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080013245 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
13246 }
developer72fb0bb2023-01-11 09:46:29 +080013247
developera3511852023-06-14 14:12:59 +080013248 scan_array[index].ap_Noise = 0;
13249 if (get_noise_ret == RETURN_OK) {
13250 for (int i = 0; i < channels_num; i++) {
13251 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
13252 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
13253 break;
13254 }
13255 }
13256 }
13257 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +080013258 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
13259 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13260 goto err;
13261 }
developera3511852023-06-14 14:12:59 +080013262 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +080013263 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
13264 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13265 goto err;
13266 }
developera3511852023-06-14 14:12:59 +080013267 } else if (strstr(line,"SSID") != NULL) {
developer86035662023-06-28 19:21:12 +080013268 if (sscanf(line," SSID: %63s", scan_array[index].ap_SSID) != 1) {
13269 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13270 goto err;
13271 }
developera3511852023-06-14 14:12:59 +080013272 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
13273 filter_BSS = true;
13274 }
13275 } else if (strstr(line, "Supported rates") != NULL) {
13276 char SRate[80] = {0}, *tmp = NULL;
13277 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080013278 len = strlen(line);
13279 if (len >= sizeof(SRate)) {
13280 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013281 goto err;
developer32f2a182023-06-27 19:50:41 +080013282 }
13283 strncpy(SRate, line, len);
developera3511852023-06-14 14:12:59 +080013284 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +080013285 if (tmp == NULL)
13286 goto err;
developera3511852023-06-14 14:12:59 +080013287 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +080013288 if (tmp == NULL)
13289 goto err;
13290
developer32f2a182023-06-27 19:50:41 +080013291 len = strlen(tmp);
13292 if (len >= sizeof(buf)) {
13293 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
developer86035662023-06-28 19:21:12 +080013294 goto err;
developer32f2a182023-06-27 19:50:41 +080013295 }
13296 strncpy(buf, tmp, len);
developera3511852023-06-14 14:12:59 +080013297 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +080013298
developera3511852023-06-14 14:12:59 +080013299 tmp = strtok(buf, " \n");
13300 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +080013301 if ((sizeof(SRate) - strlen(SRate)) <= strlen(tmp)) {
13302 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013303 goto err;
developer32f2a182023-06-27 19:50:41 +080013304 }
13305 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +080013306 if (SRate[strlen(SRate) - 1] == '*') {
13307 SRate[strlen(SRate) - 1] = '\0';
13308 }
developer32f2a182023-06-27 19:50:41 +080013309 if ((sizeof(SRate) - strlen(SRate)) <= 1) {
13310 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013311 goto err;
developer32f2a182023-06-27 19:50:41 +080013312 }
13313 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +080013314
developera3511852023-06-14 14:12:59 +080013315 tmp = strtok(NULL, " \n");
13316 }
13317 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +080013318 len = strlen(SRate);
13319 if (len >= sizeof(scan_array[index].ap_SupportedDataTransferRates)) {
13320 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedDataTransferRates\n");
developer86035662023-06-28 19:21:12 +080013321 goto err;
developer32f2a182023-06-27 19:50:41 +080013322 }
13323 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, len);
13324 scan_array[index].ap_SupportedDataTransferRates[len] = '\0';
developera3511852023-06-14 14:12:59 +080013325 } else if (strstr(line, "DTIM") != NULL) {
developer86035662023-06-28 19:21:12 +080013326 if (sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod)) != 1) {
13327 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13328 goto err;
13329 }
developera3511852023-06-14 14:12:59 +080013330 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013331 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
13332 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013333 goto err;
developer32f2a182023-06-27 19:50:41 +080013334 }
13335 strncat(scan_array[index].ap_SupportedStandards, ",ac",
13336 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13337 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
13338 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +080013339 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013340 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 2) {
13341 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013342 goto err;
developer32f2a182023-06-27 19:50:41 +080013343 }
13344 strncat(scan_array[index].ap_SupportedStandards, ",n",
13345 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13346 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
13347 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +080013348 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080013349 if (fgets(line, sizeof(line), f) == NULL) {
13350 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13351 goto err;
13352 }
13353 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
13354 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13355 goto err;
13356 }
developera3511852023-06-14 14:12:59 +080013357 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +080013358 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +080013359 } else {
developere40952c2023-06-15 18:46:43 +080013360 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +080013361 }
developere40952c2023-06-15 18:46:43 +080013362 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
13363 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080013364 goto err;
developer32f2a182023-06-27 19:50:41 +080013365 }
developere40952c2023-06-15 18:46:43 +080013366
developera3511852023-06-14 14:12:59 +080013367 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
13368 continue;
13369 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080013370 if (fgets(line, sizeof(line), f) == NULL) {
13371 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13372 goto err;
13373 }
13374 goto err;
13375 if (sscanf(line," * secondary channel offset: %127s", buf) != 1) {
13376 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13377 goto err;
13378 }
developera3511852023-06-14 14:12:59 +080013379 if (!strcmp(buf, "above")) {
13380 //40Mhz +
developere40952c2023-06-15 18:46:43 +080013381 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 +080013382 }
13383 else if (!strcmp(buf, "below")) {
13384 //40Mhz -
developere40952c2023-06-15 18:46:43 +080013385 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 +080013386 } else {
13387 //20Mhz
developere40952c2023-06-15 18:46:43 +080013388 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 +080013389 }
developere40952c2023-06-15 18:46:43 +080013390 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
13391 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080013392 goto err;
developer32f2a182023-06-27 19:50:41 +080013393 }
developere40952c2023-06-15 18:46:43 +080013394
developera3511852023-06-14 14:12:59 +080013395 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
13396 continue;
13397 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013398 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
13399 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013400 goto err;
developer32f2a182023-06-27 19:50:41 +080013401 }
13402 strncat(scan_array[index].ap_SupportedStandards, ",ax",
13403 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13404 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
13405 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +080013406 ret = fgets(line, sizeof(line), f);
13407 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +080013408 if (strstr(line, "HE40/2.4GHz") != NULL) {
13409 len = strlen("11AXHE40PLUS");
13410 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
13411 } else {
13412 len = strlen("11AXHE20");
13413 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
13414 }
13415 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080013416 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
13417 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013418 len = strlen("11AXHE80");
13419 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
13420 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080013421 ret = fgets(line, sizeof(line), f);
13422 } else
13423 continue;
developer32f2a182023-06-27 19:50:41 +080013424 if (strstr(line, "HE160/5GHz") != NULL) {
13425 len = strlen("11AXHE160");
13426 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
13427 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
13428 }
developera3511852023-06-14 14:12:59 +080013429 }
13430 continue;
13431 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013432 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
13433 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080013434 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013435 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
13436 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080013437 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +080013438 if (sscanf(line, " * Group cipher: %63s", scan_array[index].ap_EncryptionMode) != 1) {
13439 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13440 goto err;
13441 }
developera3511852023-06-14 14:12:59 +080013442 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +080013443 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
13444 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +080013445 }
13446 }
13447 ret = fgets(line, sizeof(line), f);
13448 }
developer72fb0bb2023-01-11 09:46:29 +080013449
developera3511852023-06-14 14:12:59 +080013450 if (!filter_BSS) {
13451 *output_array_size = index + 1;
13452 } else {
13453 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
13454 *output_array_size = index;
13455 }
13456 *neighbor_ap_array = scan_array;
13457 pclose(f);
13458 free(channels_noise_arr);
13459 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13460 return RETURN_OK;
developer86035662023-06-28 19:21:12 +080013461err:
13462 fclose(f);
13463 free(channels_noise_arr);
13464 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013465}
13466
13467INT wifi_getApAssociatedDeviceStats(
developera3511852023-06-14 14:12:59 +080013468 INT apIndex,
13469 mac_address_t *clientMacAddress,
13470 wifi_associated_dev_stats_t *associated_dev_stats,
13471 u64 *handle)
developer72fb0bb2023-01-11 09:46:29 +080013472{
developera3511852023-06-14 14:12:59 +080013473 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
13474 char interface_name[50] = {0};
13475 char cmd[1024] = {0};
13476 char mac_str[18] = {0};
13477 char *key = NULL;
13478 char *val = NULL;
13479 FILE *f = NULL;
13480 char *line = NULL;
13481 size_t len = 0;
developer75bd10c2023-06-27 11:34:08 +080013482 int res;
developer72fb0bb2023-01-11 09:46:29 +080013483
developera3511852023-06-14 14:12:59 +080013484 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
13485 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
13486 return RETURN_ERR;
13487 }
developer72fb0bb2023-01-11 09:46:29 +080013488
developer32f2a182023-06-27 19:50:41 +080013489 res = snprintf(mac_str, sizeof(mac_str), "%x:%x:%x:%x:%x:%x",
13490 (*clientMacAddress)[0], (*clientMacAddress)[1], (*clientMacAddress)[2],
13491 (*clientMacAddress)[3], (*clientMacAddress)[4], (*clientMacAddress)[5]);
developer75bd10c2023-06-27 11:34:08 +080013492 if (os_snprintf_error(sizeof(mac_str), res)) {
13493 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13494 return RETURN_ERR;
13495 }
13496
13497 res = snprintf(cmd, sizeof(cmd), "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
13498 if (os_snprintf_error(sizeof(cmd), res)) {
13499 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13500 return RETURN_ERR;
13501 }
13502
developera3511852023-06-14 14:12:59 +080013503 if((f = popen(cmd, "r")) == NULL) {
13504 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
13505 return RETURN_ERR;
13506 }
developer72fb0bb2023-01-11 09:46:29 +080013507
developera3511852023-06-14 14:12:59 +080013508 while ((getline(&line, &len, f)) != -1) {
13509 key = strtok(line,":");
13510 val = strtok(NULL,":");
developer72fb0bb2023-01-11 09:46:29 +080013511
13512 if(!strncmp(key,"rx bytes",8))
developera3511852023-06-14 14:12:59 +080013513 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
developer72fb0bb2023-01-11 09:46:29 +080013514 if(!strncmp(key,"tx bytes",8))
developera3511852023-06-14 14:12:59 +080013515 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
developer72fb0bb2023-01-11 09:46:29 +080013516 if(!strncmp(key,"rx packets",10))
developera3511852023-06-14 14:12:59 +080013517 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
developer72fb0bb2023-01-11 09:46:29 +080013518 if(!strncmp(key,"tx packets",10))
developera3511852023-06-14 14:12:59 +080013519 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
13520 if(!strncmp(key,"tx retries",10))
13521 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
13522 if(!strncmp(key,"tx failed",9))
13523 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
13524 if(!strncmp(key,"rx drop misc",13))
13525 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
13526 if(!strncmp(key,"rx bitrate",10)) {
13527 val = strtok(val, " ");
13528 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
13529 }
13530 if(!strncmp(key,"tx bitrate",10)) {
13531 val = strtok(val, " ");
13532 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
13533 }
13534 }
13535 free(line);
13536 pclose(f);
13537 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013538}
13539
13540INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
13541{
developera3511852023-06-14 14:12:59 +080013542 char interface_name[IF_NAME_SIZE] = {0};
13543 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
developere40952c2023-06-15 18:46:43 +080013544 int res;
developer72fb0bb2023-01-11 09:46:29 +080013545
developera3511852023-06-14 14:12:59 +080013546 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080013547
developera3511852023-06-14 14:12:59 +080013548 if (NULL == output_string)
13549 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013550
developera3511852023-06-14 14:12:59 +080013551 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13552 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080013553
developere40952c2023-06-15 18:46:43 +080013554 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
13555 if (os_snprintf_error(sizeof(cmd), res)) {
13556 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13557 return RETURN_ERR;
13558 }
developera3511852023-06-14 14:12:59 +080013559 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080013560
developera3511852023-06-14 14:12:59 +080013561 //size of SSID name restricted to value less than 32 bytes
developere40952c2023-06-15 18:46:43 +080013562 res = snprintf(output_string, 32, "%s", buf);
13563 if (os_snprintf_error(32, res)) {
13564 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13565 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013566 }
developera3511852023-06-14 14:12:59 +080013567 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013568
developera3511852023-06-14 14:12:59 +080013569 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013570}
13571
13572INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
13573{
developer2edaf012023-05-24 14:24:53 +080013574 char *mac_arry_buf = NULL;
13575 INT policy = -1;
13576 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080013577
developer2edaf012023-05-24 14:24:53 +080013578 mac_arry_buf = malloc(buf_size);
13579 if (!mac_arry_buf) {
13580 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080013581 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080013582 }
13583 memset(mac_arry_buf, 0, buf_size);
13584 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
13585 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
13586 goto err;
13587 }
13588 /*
13589 mtk format to get policy:
13590 "policy=1
13591 00:11:22:33:44:55
13592 00:11:22:33:44:66
13593 "
13594 */
13595 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
13596 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
13597 goto err;
13598 }
13599 if (!(policy >=0 && policy <= 2)){
13600 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
13601 goto err;
13602 }
13603 *output_filterMode = policy;
13604 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
13605 free(mac_arry_buf);
13606 mac_arry_buf = NULL;
13607 return RETURN_OK;
13608err:
13609 free(mac_arry_buf);
13610 mac_arry_buf = NULL;
13611 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
13612 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013613}
13614
developer2edaf012023-05-24 14:24:53 +080013615
developer72fb0bb2023-01-11 09:46:29 +080013616INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
13617{
developera3511852023-06-14 14:12:59 +080013618 FILE *fp = NULL;
13619 char str[MAX_BUF_SIZE] = {0};
13620 int wificlientindex = 0 ;
13621 int count = 0;
13622 int signalstrength = 0;
13623 int arr[MACADDRESS_SIZE] = {0};
13624 unsigned char mac[MACADDRESS_SIZE] = {0};
13625 UINT wifi_count = 0;
13626 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080013627 int res;
developer72fb0bb2023-01-11 09:46:29 +080013628
developera3511852023-06-14 14:12:59 +080013629 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13630 *output_array_size = 0;
13631 *associated_dev_array = NULL;
13632 char interface_name[50] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013633
developera3511852023-06-14 14:12:59 +080013634 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
13635 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
13636 return RETURN_ERR;
13637 }
developer72fb0bb2023-01-11 09:46:29 +080013638
developer75bd10c2023-06-27 11:34:08 +080013639 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
13640 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13641 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13642 return RETURN_ERR;
13643 }
developera3511852023-06-14 14:12:59 +080013644 fp = popen(pipeCmd, "r");
13645 if (fp == NULL)
13646 {
13647 printf("Failed to run command inside function %s\n",__FUNCTION__ );
13648 return RETURN_ERR;
13649 }
developer72fb0bb2023-01-11 09:46:29 +080013650
developera3511852023-06-14 14:12:59 +080013651 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080013652 if (fgets(str, sizeof(str)-1, fp) == NULL) {
13653 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13654 pclose(fp);
13655 return RETURN_ERR;
13656 }
developera3511852023-06-14 14:12:59 +080013657 wifi_count = (unsigned int) atoi ( str );
13658 *output_array_size = wifi_count;
13659 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
13660 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080013661
developera3511852023-06-14 14:12:59 +080013662 if(wifi_count == 0)
13663 {
13664 return RETURN_OK;
13665 }
13666 else
13667 {
13668 wifi_associated_dev2_t* temp = NULL;
13669 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
13670 *associated_dev_array = temp;
13671 if(temp == NULL)
13672 {
13673 printf("Error Statement. Insufficient memory \n");
13674 return RETURN_ERR;
13675 }
developer72fb0bb2023-01-11 09:46:29 +080013676
developere40952c2023-06-15 18:46:43 +080013677 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
13678 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13679 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13680 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013681 }
developere40952c2023-06-15 18:46:43 +080013682
developera3511852023-06-14 14:12:59 +080013683 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080013684
developera3511852023-06-14 14:12:59 +080013685 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
13686 if(fp == NULL)
13687 {
13688 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
13689 return RETURN_ERR;
13690 }
13691 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080013692
developer86035662023-06-28 19:21:12 +080013693 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
13694 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13695 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13696 return RETURN_ERR;
13697 }
developera3511852023-06-14 14:12:59 +080013698 fp = popen(pipeCmd, "r");
13699 if(fp)
13700 {
13701 for(count =0 ; count < wifi_count; count++)
13702 {
developer86035662023-06-28 19:21:12 +080013703 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13704 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13705 pclose(fp);
13706 return RETURN_ERR;
13707 }
developera3511852023-06-14 14:12:59 +080013708 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
13709 {
13710 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
13711 {
13712 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080013713
developera3511852023-06-14 14:12:59 +080013714 }
13715 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
13716 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]);
13717 }
13718 temp[count].cli_AuthenticationState = 1; //TODO
13719 temp[count].cli_Active = 1; //TODO
13720 }
13721 pclose(fp);
13722 }
developer72fb0bb2023-01-11 09:46:29 +080013723
developera3511852023-06-14 14:12:59 +080013724 //Updating RSSI per client
developer86035662023-06-28 19:21:12 +080013725 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
13726 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13727 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13728 return RETURN_ERR;
13729 }
13730
developera3511852023-06-14 14:12:59 +080013731 fp = popen(pipeCmd, "r");
13732 if(fp)
13733 {
13734 pclose(fp);
13735 }
13736 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
13737 if(fp)
13738 {
13739 for(count =0 ; count < wifi_count ;count++)
13740 {
developer86035662023-06-28 19:21:12 +080013741 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13742 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13743 pclose(fp);
13744 return RETURN_ERR;
13745 }
developera3511852023-06-14 14:12:59 +080013746 signalstrength = atoi(str);
13747 temp[count].cli_RSSI = signalstrength;
13748 }
13749 pclose(fp);
13750 }
developer72fb0bb2023-01-11 09:46:29 +080013751
13752
developera3511852023-06-14 14:12:59 +080013753 //LastDataDownlinkRate
developer86035662023-06-28 19:21:12 +080013754 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
13755 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13756 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13757 return RETURN_ERR;
13758 }
developera3511852023-06-14 14:12:59 +080013759 fp = popen(pipeCmd, "r");
13760 if (fp)
13761 {
13762 pclose(fp);
13763 }
13764 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
13765 if (fp)
13766 {
13767 for (count = 0; count < wifi_count; count++)
13768 {
developer86035662023-06-28 19:21:12 +080013769 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13770 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13771 pclose(fp);
13772 return RETURN_ERR;
13773 }
developera3511852023-06-14 14:12:59 +080013774 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
13775 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
13776 }
13777 pclose(fp);
13778 }
developer72fb0bb2023-01-11 09:46:29 +080013779
developera3511852023-06-14 14:12:59 +080013780 //LastDataUplinkRate
developer86035662023-06-28 19:21:12 +080013781 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
13782 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13783 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13784 return RETURN_ERR;
13785 }
developera3511852023-06-14 14:12:59 +080013786 fp = popen(pipeCmd, "r");
13787 if (fp)
13788 {
13789 pclose(fp);
13790 }
13791 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
13792 if (fp)
13793 {
13794 for (count = 0; count < wifi_count; count++)
13795 {
developer86035662023-06-28 19:21:12 +080013796 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
13797 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13798 pclose(fp);
13799 return RETURN_ERR;
13800 }
developera3511852023-06-14 14:12:59 +080013801 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
13802 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
13803 }
13804 pclose(fp);
13805 }
13806 }
13807 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13808 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013809
13810}
13811
13812INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
13813{
developera3511852023-06-14 14:12:59 +080013814 FILE *fp = NULL;
13815 char interface_name[50] = {0};
13816 char pipeCmd[128] = {0};
13817 char str[256] = {0};
13818 wifi_ssidTrafficStats2_t *out = output_struct;
developer75bd10c2023-06-27 11:34:08 +080013819 int res;
developer72fb0bb2023-01-11 09:46:29 +080013820
developera3511852023-06-14 14:12:59 +080013821 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
13822 if (!output_struct)
13823 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013824
developera3511852023-06-14 14:12:59 +080013825 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
13826 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
13827 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080013828 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /proc/net/dev | grep %s", interface_name);
13829 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13830 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13831 return RETURN_ERR;
13832 }
developer72fb0bb2023-01-11 09:46:29 +080013833
developera3511852023-06-14 14:12:59 +080013834 fp = popen(pipeCmd, "r");
13835 if (fp == NULL) {
developer86035662023-06-28 19:21:12 +080013836 wifi_debug(DEBUG_ERROR, "%s: popen failed\n", __func__);
13837 return RETURN_ERR;
13838 }
13839 if (fgets(str, sizeof(str), fp) == NULL) {
13840 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13841 pclose(fp);
developera3511852023-06-14 14:12:59 +080013842 return RETURN_ERR;
13843 }
developer86035662023-06-28 19:21:12 +080013844
developera3511852023-06-14 14:12:59 +080013845 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080013846
developera3511852023-06-14 14:12:59 +080013847 if (strlen(str) == 0) // interface not exist
13848 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013849
developer6e578302023-06-21 10:11:16 +080013850 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 +080013851 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
developer72fb0bb2023-01-11 09:46:29 +080013852
developera3511852023-06-14 14:12:59 +080013853 memset(str, 0, sizeof(str));
developer75bd10c2023-06-27 11:34:08 +080013854
13855 res = snprintf(pipeCmd, sizeof(pipeCmd), "tail -n1 /proc/net/netstat");
13856 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13857 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13858 return RETURN_ERR;
13859 }
developera3511852023-06-14 14:12:59 +080013860 fp = popen(pipeCmd, "r");
13861 if (fp == NULL) {
developer75bd10c2023-06-27 11:34:08 +080013862 wifi_debug(DEBUG_ERROR, "popen failed\n");
developera3511852023-06-14 14:12:59 +080013863 return RETURN_ERR;
13864 }
developer86035662023-06-28 19:21:12 +080013865
13866 if (fgets(str, sizeof(str), fp) == NULL) {
13867 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13868 pclose(fp);
13869 return RETURN_ERR;
13870 }
developer72fb0bb2023-01-11 09:46:29 +080013871
developer6e578302023-06-21 10:11:16 +080013872 sscanf(str, "%*[^:]: %*d %*d %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
developera3511852023-06-14 14:12:59 +080013873 &out->ssid_BroadcastPacketsSent);
13874 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080013875
developera3511852023-06-14 14:12:59 +080013876 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
13877 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +080013878
developera3511852023-06-14 14:12:59 +080013879 // Not supported
13880 output_struct->ssid_RetransCount = 0;
13881 output_struct->ssid_FailedRetransCount = 0;
13882 output_struct->ssid_RetryCount = 0;
13883 output_struct->ssid_MultipleRetryCount = 0;
13884 output_struct->ssid_ACKFailureCount = 0;
13885 output_struct->ssid_AggregatedPacketCount = 0;
developer72fb0bb2023-01-11 09:46:29 +080013886
developera3511852023-06-14 14:12:59 +080013887 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013888}
13889
13890//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).
13891INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
13892{
developera3511852023-06-14 14:12:59 +080013893 char output_val[16]={'\0'};
13894 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080013895 int res;
developer72fb0bb2023-01-11 09:46:29 +080013896
developera3511852023-06-14 14:12:59 +080013897 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13898 if (!output)
13899 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080013900
13901 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
13902 if (os_snprintf_error(sizeof(config_file), res)) {
13903 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13904 return RETURN_ERR;
13905 }
developera3511852023-06-14 14:12:59 +080013906 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
developer72fb0bb2023-01-11 09:46:29 +080013907
developera3511852023-06-14 14:12:59 +080013908 if( strcmp(output_val,"1") == 0 )
13909 *output = TRUE;
13910 else
13911 *output = FALSE;
13912 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013913
developera3511852023-06-14 14:12:59 +080013914 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013915}
13916
13917INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
13918{
developera3511852023-06-14 14:12:59 +080013919 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13920 char string[MAX_BUF_SIZE]={'\0'};
13921 char config_file[MAX_BUF_SIZE] = {0};
13922 struct params params;
developer75bd10c2023-06-27 11:34:08 +080013923 int res;
developer72fb0bb2023-01-11 09:46:29 +080013924
developer32f2a182023-06-27 19:50:41 +080013925 string[0] = enable == TRUE ? '1' : '0';
developer72fb0bb2023-01-11 09:46:29 +080013926
developera3511852023-06-14 14:12:59 +080013927 params.name = "ap_isolate";
13928 params.value = string;
developer72fb0bb2023-01-11 09:46:29 +080013929
developer75bd10c2023-06-27 11:34:08 +080013930 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
13931 if (os_snprintf_error(sizeof(config_file), res)) {
13932 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13933 return RETURN_ERR;
13934 }
13935
developera3511852023-06-14 14:12:59 +080013936 wifi_hostapdWrite(config_file,&params,1);
13937 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013938
developera3511852023-06-14 14:12:59 +080013939 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013940}
13941
13942INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
13943{
developera3511852023-06-14 14:12:59 +080013944 char mgmtpwr_file[32] = {0};
13945 char cmd[64] = {0};
13946 char buf[32]={0};
developere40952c2023-06-15 18:46:43 +080013947 int res;
developera1255e42023-05-13 17:45:02 +080013948
developera3511852023-06-14 14:12:59 +080013949 if (NULL == output_dBm)
13950 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080013951 res = snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
13952 if (os_snprintf_error(sizeof(mgmtpwr_file), res)) {
13953 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13954 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013955 }
developere40952c2023-06-15 18:46:43 +080013956
13957 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
13958 if (os_snprintf_error(sizeof(cmd), res)) {
13959 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13960 return RETURN_ERR;
13961 }
developera3511852023-06-14 14:12:59 +080013962 _syscmd(cmd, buf, sizeof(buf));
13963 if (strlen(buf) > 0)
13964 *output_dBm = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +080013965 else
13966 *output_dBm = 23;
developera3511852023-06-14 14:12:59 +080013967 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013968}
13969
13970INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
13971{
developera1255e42023-05-13 17:45:02 +080013972 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080013973 char mgmt_pwr_file[128]={0};
13974 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080013975 int if_idx, ret = 0;
13976 struct nl_msg *msg = NULL;
13977 struct nlattr * msg_data = NULL;
13978 struct mtk_nl80211_param param;
13979 struct unl unl_ins;
13980 char power[16] = {0};
developere40952c2023-06-15 18:46:43 +080013981 int res;
developera1255e42023-05-13 17:45:02 +080013982
13983 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13984
13985 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
13986 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080013987
13988 if_idx = if_nametoindex(interface_name);
13989 /*init mtk nl80211 vendor cmd*/
13990 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
13991 param.if_type = NL80211_ATTR_IFINDEX;
13992 param.if_idx = if_idx;
13993
13994 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
13995 if (ret) {
13996 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
13997 return RETURN_ERR;
13998 }
13999
14000 /*add mtk vendor cmd data*/
developere40952c2023-06-15 18:46:43 +080014001 res = snprintf(power, sizeof(power), "%d", dBm);
14002 if (os_snprintf_error(sizeof(power), res)) {
14003 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14004 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014005 }
developere40952c2023-06-15 18:46:43 +080014006
developerfead3972023-05-25 20:15:02 +080014007 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
14008 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
14009 nlmsg_free(msg);
14010 goto err;
14011 }
14012
14013 /*send mtk nl80211 vendor msg*/
14014 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
14015 if (ret) {
14016 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
14017 goto err;
14018 }
14019
14020 /*deinit mtk nl80211 vendor msg*/
14021 mtk_nl80211_deint(&unl_ins);
14022 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
14023
developere40952c2023-06-15 18:46:43 +080014024 res = snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
14025 if (os_snprintf_error(sizeof(mgmt_pwr_file), res)) {
14026 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14027 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014028 }
developere40952c2023-06-15 18:46:43 +080014029
developera1255e42023-05-13 17:45:02 +080014030 f = fopen(mgmt_pwr_file, "w");
14031 if (f == NULL) {
14032 fprintf(stderr, "%s: fopen failed\n", __func__);
14033 return RETURN_ERR;
14034 }
14035 fprintf(f, "%d", dBm);
14036 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080014037 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080014038err:
14039 mtk_nl80211_deint(&unl_ins);
14040 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
14041 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014042}
14043INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
14044{
developera3511852023-06-14 14:12:59 +080014045 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014046}
14047INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
14048{
developera3511852023-06-14 14:12:59 +080014049 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014050}
14051INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
14052{
developera3511852023-06-14 14:12:59 +080014053 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014054}
14055INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
14056{
developera3511852023-06-14 14:12:59 +080014057 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014058}
14059INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
14060{
developera3511852023-06-14 14:12:59 +080014061 char config_file[MAX_BUF_SIZE] = {0};
14062 struct params list;
developere40952c2023-06-15 18:46:43 +080014063 int res;
developer72fb0bb2023-01-11 09:46:29 +080014064
developera3511852023-06-14 14:12:59 +080014065 list.name = "bss_transition";
14066 list.value = activate?"1":"0";
developere40952c2023-06-15 18:46:43 +080014067 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
14068 if (os_snprintf_error(sizeof(config_file), res)) {
14069 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14070 return RETURN_ERR;
14071 }
developera3511852023-06-14 14:12:59 +080014072 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080014073
developera3511852023-06-14 14:12:59 +080014074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014075}
14076wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
14077
14078void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
14079{
developera3511852023-06-14 14:12:59 +080014080 return;
developer72fb0bb2023-01-11 09:46:29 +080014081}
14082
14083INT wifi_setApCsaDeauth(INT apIndex, INT mode)
14084{
developera3511852023-06-14 14:12:59 +080014085 // TODO Implement me!
14086 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014087}
14088
14089INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
14090{
developera3511852023-06-14 14:12:59 +080014091 char file_name[128] = {0};
14092 FILE *f = NULL;
14093 int max_num_radios = 0;
developer75bd10c2023-06-27 11:34:08 +080014094 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080014095
developera3511852023-06-14 14:12:59 +080014096 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014097
developera3511852023-06-14 14:12:59 +080014098 wifi_getMaxRadioNumber(&max_num_radios);
14099 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
14100 for (int index = 0; index < max_num_radios; index++) {
developere40952c2023-06-15 18:46:43 +080014101 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
14102 if (os_snprintf_error(sizeof(file_name), res)) {
14103 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14104 return RETURN_ERR;
14105 }
14106
developera3511852023-06-14 14:12:59 +080014107 f = fopen(file_name, "w");
14108 if (f == NULL)
14109 return RETURN_ERR;
14110 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080014111 if (mode) {
14112 ret = fprintf(f, "%s", essid);
14113 if (ret < 0)
14114 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
14115 }
developer72fb0bb2023-01-11 09:46:29 +080014116
developera3511852023-06-14 14:12:59 +080014117 fclose(f);
14118 }
14119 } else { // special case, need to set AP's SSID as filter for each radio.
developere40952c2023-06-15 18:46:43 +080014120 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
14121 if (os_snprintf_error(sizeof(file_name), res)) {
14122 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14123 return RETURN_ERR;
14124 }
14125
developera3511852023-06-14 14:12:59 +080014126 f = fopen(file_name, "w");
14127 if (f == NULL)
14128 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014129
developera3511852023-06-14 14:12:59 +080014130 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080014131 if (mode) {
14132 ret = fprintf(f, "%s", essid);
14133 if (ret < 0)
14134 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
14135 }
developer72fb0bb2023-01-11 09:46:29 +080014136
developera3511852023-06-14 14:12:59 +080014137 fclose(f);
14138 }
developer72fb0bb2023-01-11 09:46:29 +080014139
developera3511852023-06-14 14:12:59 +080014140 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14141 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014142}
14143
14144INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
14145{
developera3511852023-06-14 14:12:59 +080014146 // TODO Implement me!
14147 //Apply wifi_pushRadioChannel() instantly
14148 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014149}
14150
14151INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
14152{
developera3511852023-06-14 14:12:59 +080014153 // TODO Implement me!
14154 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014155}
14156
developer72fb0bb2023-01-11 09:46:29 +080014157
developera3511852023-06-14 14:12:59 +080014158static int tidStats_callback(struct nl_msg *msg, void *arg) {
14159 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14160 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14161 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14162 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
14163 int rem , tid_index = 0;
developer72fb0bb2023-01-11 09:46:29 +080014164
developera3511852023-06-14 14:12:59 +080014165 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
14166 wifi_associated_dev_tid_entry_t *stats_entry;
developer72fb0bb2023-01-11 09:46:29 +080014167
developera3511852023-06-14 14:12:59 +080014168 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
14169 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
14170 };
14171 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
14172 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
14173 };
developer72fb0bb2023-01-11 09:46:29 +080014174
developera3511852023-06-14 14:12:59 +080014175 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
14176 genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080014177
developer72fb0bb2023-01-11 09:46:29 +080014178
developera3511852023-06-14 14:12:59 +080014179 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014180 wifi_debug(DEBUG_ERROR, "station stats missing!\n");
developera3511852023-06-14 14:12:59 +080014181 return NL_SKIP;
14182 }
developer72fb0bb2023-01-11 09:46:29 +080014183
developera3511852023-06-14 14:12:59 +080014184 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
14185 tb[NL80211_ATTR_STA_INFO],
14186 stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014187 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014188 return NL_SKIP;
14189 }
developer72fb0bb2023-01-11 09:46:29 +080014190
developera3511852023-06-14 14:12:59 +080014191 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14192 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
14193 {
14194 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080014195
developera3511852023-06-14 14:12:59 +080014196 stats_entry->tid = tid_index;
14197 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080014198
developera3511852023-06-14 14:12:59 +080014199 if(sinfo[NL80211_STA_INFO_TID_STATS])
14200 {
14201 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
14202 printf("failed to parse nested stats attributes!");
14203 return NL_SKIP;
14204 }
14205 }
14206 if(stats_info[NL80211_TID_STATS_TX_MSDU])
14207 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080014208
developera3511852023-06-14 14:12:59 +080014209 if(tid_index < (PS_MAX_TID - 1))
14210 tid_index++;
14211 }
14212 }
14213 //ToDo: sum_time_ms, ewma_time_ms
14214 return NL_SKIP;
14215}
developer72fb0bb2023-01-11 09:46:29 +080014216
developera3511852023-06-14 14:12:59 +080014217INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
14218{
14219 Netlink nl;
14220 char if_name[IF_NAME_SIZE];
14221 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014222 int res;
developer72fb0bb2023-01-11 09:46:29 +080014223
developera3511852023-06-14 14:12:59 +080014224 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
14225 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014226
developere40952c2023-06-15 18:46:43 +080014227 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
14228 if (os_snprintf_error(sizeof(if_name), res)) {
14229 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14230 return RETURN_ERR;
14231 }
developer72fb0bb2023-01-11 09:46:29 +080014232
developera3511852023-06-14 14:12:59 +080014233 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014234
developera3511852023-06-14 14:12:59 +080014235 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080014236 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080014237 return -1;
14238 }
developer72fb0bb2023-01-11 09:46:29 +080014239
developera3511852023-06-14 14:12:59 +080014240 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014241
developera3511852023-06-14 14:12:59 +080014242 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080014243 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080014244 nlfree(&nl);
14245 return -2;
14246 }
developer72fb0bb2023-01-11 09:46:29 +080014247
developera3511852023-06-14 14:12:59 +080014248 genlmsg_put(msg,
14249 NL_AUTO_PID,
14250 NL_AUTO_SEQ,
14251 nl.id,
14252 0,
14253 0,
14254 NL80211_CMD_GET_STATION,
14255 0);
developer72fb0bb2023-01-11 09:46:29 +080014256
developera3511852023-06-14 14:12:59 +080014257 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
14258 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14259 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
14260 nl_send_auto_complete(nl.socket, msg);
14261 nl_recvmsgs(nl.socket, nl.cb);
14262 nlmsg_free(msg);
14263 nlfree(&nl);
14264 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014265}
14266
14267
14268INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
14269{
developera3511852023-06-14 14:12:59 +080014270 char interface_name[16] = {0};
14271 char cmd[128]={0};
14272 char buf[128]={0};
14273 int freq = 0;
developere40952c2023-06-15 18:46:43 +080014274 int res;
developer72fb0bb2023-01-11 09:46:29 +080014275
developera3511852023-06-14 14:12:59 +080014276 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014277
developera3511852023-06-14 14:12:59 +080014278 // full mode is used to scan all channels.
14279 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
14280 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
14281 ieee80211_channel_to_frequency(chan_list[0], &freq);
developer72fb0bb2023-01-11 09:46:29 +080014282
developera3511852023-06-14 14:12:59 +080014283 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14284 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014285
developera3511852023-06-14 14:12:59 +080014286 if (freq)
developere40952c2023-06-15 18:46:43 +080014287 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
developera3511852023-06-14 14:12:59 +080014288 else
developere40952c2023-06-15 18:46:43 +080014289 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
14290 if (os_snprintf_error(sizeof(cmd), res)) {
14291 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14292 return RETURN_ERR;
14293 }
developer72fb0bb2023-01-11 09:46:29 +080014294
developera3511852023-06-14 14:12:59 +080014295 _syscmd(cmd, buf, sizeof(buf));
14296 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014297
developera3511852023-06-14 14:12:59 +080014298 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014299}
14300
14301
14302INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
14303{
developera3511852023-06-14 14:12:59 +080014304 // TODO Implement me!
14305 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014306}
14307
14308INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
14309{
developera3511852023-06-14 14:12:59 +080014310 // TODO Implement me!
14311 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014312}
14313
14314INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
14315{
developera3511852023-06-14 14:12:59 +080014316 // TODO Implement me!
14317 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014318}
14319
14320INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
14321{
developera3511852023-06-14 14:12:59 +080014322 // TODO Implement me!
14323 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014324}
14325
14326INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
14327{
developera3511852023-06-14 14:12:59 +080014328 // TODO Implement me!
14329 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014330}
14331
14332INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
14333{
developera3511852023-06-14 14:12:59 +080014334 // TODO Implement me!
14335 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014336}
14337
14338INT wifi_steering_eventUnregister(void)
14339{
developera3511852023-06-14 14:12:59 +080014340 // TODO Implement me!
14341 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014342}
14343
14344INT wifi_delApAclDevices(INT apIndex)
14345{
developer7e4a2a62023-04-06 19:56:03 +080014346 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080014347 struct unl unl_ins;
14348 int if_idx = 0, ret = 0;
14349 struct nl_msg *msg = NULL;
14350 struct nlattr * msg_data = NULL;
14351 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080014352
developer7e4a2a62023-04-06 19:56:03 +080014353 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
14354 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080014355 if_idx = if_nametoindex(inf_name);
14356 if (!if_idx) {
14357 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
14358 return RETURN_ERR;
14359 }
14360 /*init mtk nl80211 vendor cmd*/
14361 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
14362 param.if_type = NL80211_ATTR_IFINDEX;
14363 param.if_idx = if_idx;
14364 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
14365 if (ret) {
14366 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
14367 return RETURN_ERR;
14368 }
14369 /*add mtk vendor cmd data*/
14370 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
14371 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
14372 nlmsg_free(msg);
14373 goto err;
14374 }
14375 /*send mtk nl80211 vendor msg*/
14376 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
14377 if (ret) {
14378 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
14379 goto err;
14380 }
14381 /*deinit mtk nl80211 vendor msg*/
14382 mtk_nl80211_deint(&unl_ins);
14383 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
14384 return RETURN_OK;
14385err:
14386 mtk_nl80211_deint(&unl_ins);
14387 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
14388 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014389
developera3511852023-06-14 14:12:59 +080014390 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014391}
14392
developer72fb0bb2023-01-11 09:46:29 +080014393static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080014394 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14395 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14396 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14397 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
14398 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
14399 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080014400
developera3511852023-06-14 14:12:59 +080014401 nla_parse(tb,
14402 NL80211_ATTR_MAX,
14403 genlmsg_attrdata(gnlh, 0),
14404 genlmsg_attrlen(gnlh, 0),
14405 NULL);
developer72fb0bb2023-01-11 09:46:29 +080014406
developera3511852023-06-14 14:12:59 +080014407 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014408 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080014409 return NL_SKIP;
14410 }
developer72fb0bb2023-01-11 09:46:29 +080014411
developera3511852023-06-14 14:12:59 +080014412 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014413 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014414 return NL_SKIP;
14415 }
14416 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080014417
developera3511852023-06-14 14:12:59 +080014418 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080014419
developera3511852023-06-14 14:12:59 +080014420 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
14421 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
developer75bd10c2023-06-27 11:34:08 +080014422 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080014423 return NL_SKIP;
14424 }
14425 }
developer72fb0bb2023-01-11 09:46:29 +080014426
developera3511852023-06-14 14:12:59 +080014427 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14428 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
14429 printf("failed to parse nested stats attributes!");
14430 return NL_SKIP;
14431 }
14432 }
14433 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080014434
developera3511852023-06-14 14:12:59 +080014435 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
14436 {
14437 printf("Type is VHT\n");
14438 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
14439 ((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 +080014440
developera3511852023-06-14 14:12:59 +080014441 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
14442 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
14443 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
14444 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14445 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
14446 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14447 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
14448 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14449 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
14450 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
14451 } else {
14452 printf(" OFDM or CCK \n");
14453 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
14454 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
14455 }
14456 }
developer72fb0bb2023-01-11 09:46:29 +080014457
developera3511852023-06-14 14:12:59 +080014458 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
developereff896f2023-05-29 14:52:55 +080014459 if(rinfo[NL80211_RATE_INFO_MCS])
14460 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
14461 }
developera3511852023-06-14 14:12:59 +080014462 if (sinfo[NL80211_STA_INFO_RX_BYTES64])
developereff896f2023-05-29 14:52:55 +080014463 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
14464 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
14465 ((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 +080014466
developera3511852023-06-14 14:12:59 +080014467 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14468 if (stats_info[NL80211_TID_STATS_RX_MSDU])
developereff896f2023-05-29 14:52:55 +080014469 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
14470 }
developer72fb0bb2023-01-11 09:46:29 +080014471
developereff896f2023-05-29 14:52:55 +080014472 if (sinfo[NL80211_STA_INFO_SIGNAL])
14473 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
14474 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
14475 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
14476 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
14477 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
14478 //rssi_array need to be filled
14479 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080014480}
developer72fb0bb2023-01-11 09:46:29 +080014481
14482INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
14483{
developera3511852023-06-14 14:12:59 +080014484 Netlink nl;
14485 char if_name[32];
14486 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
14487 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014488
developera3511852023-06-14 14:12:59 +080014489 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080014490
developera3511852023-06-14 14:12:59 +080014491 if (*output_array_size <= 0)
14492 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014493
developera3511852023-06-14 14:12:59 +080014494 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014495
developera3511852023-06-14 14:12:59 +080014496 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080014497 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080014498 return 0;
14499 }
developer72fb0bb2023-01-11 09:46:29 +080014500
developera3511852023-06-14 14:12:59 +080014501 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014502
developera3511852023-06-14 14:12:59 +080014503 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080014504 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080014505 nlfree(&nl);
14506 return 0;
14507 }
developer72fb0bb2023-01-11 09:46:29 +080014508
developera3511852023-06-14 14:12:59 +080014509 genlmsg_put(msg,
14510 NL_AUTO_PID,
14511 NL_AUTO_SEQ,
14512 nl.id,
14513 0,
14514 0,
14515 NL80211_CMD_GET_STATION,
14516 0);
developer72fb0bb2023-01-11 09:46:29 +080014517
developera3511852023-06-14 14:12:59 +080014518 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
14519 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14520 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
14521 nl_send_auto_complete(nl.socket, msg);
14522 nl_recvmsgs(nl.socket, nl.cb);
14523 nlmsg_free(msg);
14524 nlfree(&nl);
14525 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014526}
14527
developer72fb0bb2023-01-11 09:46:29 +080014528static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080014529 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14530 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14531 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14532 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
14533 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
14534 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080014535
developera3511852023-06-14 14:12:59 +080014536 nla_parse(tb,
14537 NL80211_ATTR_MAX,
14538 genlmsg_attrdata(gnlh, 0),
14539 genlmsg_attrlen(gnlh, 0),
14540 NULL);
developer72fb0bb2023-01-11 09:46:29 +080014541
developera3511852023-06-14 14:12:59 +080014542 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014543 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080014544 return NL_SKIP;
14545 }
developer72fb0bb2023-01-11 09:46:29 +080014546
developera3511852023-06-14 14:12:59 +080014547 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014548 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014549 return NL_SKIP;
14550 }
developer72fb0bb2023-01-11 09:46:29 +080014551
developera3511852023-06-14 14:12:59 +080014552 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080014553
developera3511852023-06-14 14:12:59 +080014554 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080014555
developera3511852023-06-14 14:12:59 +080014556 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
14557 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014558 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080014559 return NL_SKIP;
14560 }
14561 }
developer72fb0bb2023-01-11 09:46:29 +080014562
developera3511852023-06-14 14:12:59 +080014563 if(sinfo[NL80211_STA_INFO_TID_STATS])
14564 {
14565 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
14566 printf("failed to parse nested stats attributes!");
14567 return NL_SKIP;
14568 }
14569 }
14570 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
14571 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
14572 {
14573 printf("Type is VHT\n");
14574 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
14575 ((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 +080014576
developera3511852023-06-14 14:12:59 +080014577 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
14578 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
14579 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
14580 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
14581 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
14582 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
14583 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
14584 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
14585 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
14586 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
14587 }
14588 else
14589 {
14590 printf(" OFDM or CCK \n");
14591 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
14592 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
14593 }
14594 }
developer72fb0bb2023-01-11 09:46:29 +080014595
developera3511852023-06-14 14:12:59 +080014596 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
14597 if(rinfo[NL80211_RATE_INFO_MCS])
14598 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
14599 }
developer72fb0bb2023-01-11 09:46:29 +080014600
developera3511852023-06-14 14:12:59 +080014601 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
14602 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
14603 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
14604 ((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 +080014605
developera3511852023-06-14 14:12:59 +080014606 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
14607 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
14608 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080014609
developera3511852023-06-14 14:12:59 +080014610 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
14611 if(stats_info[NL80211_TID_STATS_TX_MSDU])
14612 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
14613 }
developer72fb0bb2023-01-11 09:46:29 +080014614
developera3511852023-06-14 14:12:59 +080014615 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
14616 ((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 +080014617
developera3511852023-06-14 14:12:59 +080014618 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
14619 ((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 +080014620
developera3511852023-06-14 14:12:59 +080014621 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080014622}
developer72fb0bb2023-01-11 09:46:29 +080014623
14624INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
14625{
developera3511852023-06-14 14:12:59 +080014626 Netlink nl;
14627 char if_name[IF_NAME_SIZE];
14628 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014629 int res;
14630
developera3511852023-06-14 14:12:59 +080014631 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
14632 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014633
developera3511852023-06-14 14:12:59 +080014634 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080014635
developera3511852023-06-14 14:12:59 +080014636 if (*output_array_size <= 0)
14637 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014638
developere40952c2023-06-15 18:46:43 +080014639 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
14640 if (os_snprintf_error(sizeof(if_name), res)) {
14641 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14642 return RETURN_ERR;
14643 }
developer72fb0bb2023-01-11 09:46:29 +080014644
developera3511852023-06-14 14:12:59 +080014645 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014646
developera3511852023-06-14 14:12:59 +080014647 if(nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080014648 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080014649 return 0;
14650 }
developer72fb0bb2023-01-11 09:46:29 +080014651
developera3511852023-06-14 14:12:59 +080014652 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014653
developera3511852023-06-14 14:12:59 +080014654 if(!msg) {
developer75bd10c2023-06-27 11:34:08 +080014655 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080014656 nlfree(&nl);
14657 return 0;
14658 }
developer72fb0bb2023-01-11 09:46:29 +080014659
developera3511852023-06-14 14:12:59 +080014660 genlmsg_put(msg,
14661 NL_AUTO_PID,
14662 NL_AUTO_SEQ,
14663 nl.id,
14664 0,
14665 0,
14666 NL80211_CMD_GET_STATION,
14667 0);
developer72fb0bb2023-01-11 09:46:29 +080014668
developera3511852023-06-14 14:12:59 +080014669 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
14670 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14671 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
14672 nl_send_auto_complete(nl.socket, msg);
14673 nl_recvmsgs(nl.socket, nl.cb);
14674 nlmsg_free(msg);
14675 nlfree(&nl);
14676 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014677}
14678
14679INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
14680{
developera3511852023-06-14 14:12:59 +080014681 // TODO Implement me!
14682 char buf[MAX_BUF_SIZE] = {0};
14683 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014684 int res;
developer72fb0bb2023-01-11 09:46:29 +080014685
developere40952c2023-06-15 18:46:43 +080014686 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14687 if (os_snprintf_error(sizeof(config_file), res)) {
14688 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14689 return RETURN_ERR;
14690 }
developera3511852023-06-14 14:12:59 +080014691 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
14692 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080014693
developera3511852023-06-14 14:12:59 +080014694 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014695}
14696
14697INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
14698{
developera3511852023-06-14 14:12:59 +080014699 char config_file[MAX_BUF_SIZE] = {0};
14700 struct params list;
developer75bd10c2023-06-27 11:34:08 +080014701 int res;
developer72fb0bb2023-01-11 09:46:29 +080014702
developera3511852023-06-14 14:12:59 +080014703 list.name = "rrm_neighbor_report";
14704 list.value = activate?"1":"0";
developer75bd10c2023-06-27 11:34:08 +080014705 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14706 if (os_snprintf_error(sizeof(config_file), res)) {
14707 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14708 return RETURN_ERR;
14709 }
developera3511852023-06-14 14:12:59 +080014710 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080014711
developera3511852023-06-14 14:12:59 +080014712 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014713}
14714
14715INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
14716{
developera3511852023-06-14 14:12:59 +080014717 char buf[32] = {0};
14718 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080014719 int res;
developer72fb0bb2023-01-11 09:46:29 +080014720
developer75bd10c2023-06-27 11:34:08 +080014721 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14722 if (os_snprintf_error(sizeof(config_file), res)) {
14723 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14724 return RETURN_ERR;
14725 }
developera3511852023-06-14 14:12:59 +080014726 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
14727 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080014728
developera3511852023-06-14 14:12:59 +080014729 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014730}
14731#undef HAL_NETLINK_IMPL
14732#ifdef HAL_NETLINK_IMPL
14733static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080014734 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14735 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14736 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
14737 char dev[20];
14738 int freq =0 ;
14739 static int i=0;
developer72fb0bb2023-01-11 09:46:29 +080014740
developera3511852023-06-14 14:12:59 +080014741 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
developer72fb0bb2023-01-11 09:46:29 +080014742
developera3511852023-06-14 14:12:59 +080014743 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
14744 };
developer72fb0bb2023-01-11 09:46:29 +080014745
developera3511852023-06-14 14:12:59 +080014746 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080014747
developera3511852023-06-14 14:12:59 +080014748 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080014749
developera3511852023-06-14 14:12:59 +080014750 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
14751 fprintf(stderr, "survey data missing!\n");
14752 return NL_SKIP;
14753 }
developer72fb0bb2023-01-11 09:46:29 +080014754
developera3511852023-06-14 14:12:59 +080014755 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
14756 {
14757 fprintf(stderr, "failed to parse nested attributes!\n");
14758 return NL_SKIP;
14759 }
developer72fb0bb2023-01-11 09:46:29 +080014760
14761
developera3511852023-06-14 14:12:59 +080014762 if(out[0].array_size == 1 )
14763 {
14764 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
14765 {
14766 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
14767 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
14768 out[0].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080014769
developera3511852023-06-14 14:12:59 +080014770 if (sinfo[NL80211_SURVEY_INFO_NOISE])
14771 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
14772 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
14773 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
14774 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
14775 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
14776 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
14777 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
14778 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
14779 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
14780 if (sinfo[NL80211_SURVEY_INFO_TIME])
14781 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
14782 return NL_STOP;
14783 }
14784 } else {
14785 if ( i <= out[0].array_size ) {
14786 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
14787 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
14788 out[i].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080014789
developera3511852023-06-14 14:12:59 +080014790 if (sinfo[NL80211_SURVEY_INFO_NOISE])
14791 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
14792 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
14793 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
14794 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
14795 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
14796 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
14797 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
14798 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
14799 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
14800 if (sinfo[NL80211_SURVEY_INFO_TIME])
14801 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
14802 }
14803 }
developer72fb0bb2023-01-11 09:46:29 +080014804
developera3511852023-06-14 14:12:59 +080014805 i++;
14806 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080014807}
14808#endif
14809
14810static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
14811{
developera3511852023-06-14 14:12:59 +080014812 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
14813 FILE *fp;
developere40952c2023-06-15 18:46:43 +080014814 int res;
developer72fb0bb2023-01-11 09:46:29 +080014815
developera3511852023-06-14 14:12:59 +080014816 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
14817 {
14818 printf("Creating Frequency-Channel Map\n");
14819 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
14820 }
developere40952c2023-06-15 18:46:43 +080014821 res = snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
14822 if (os_snprintf_error(sizeof(command), res)) {
14823 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14824 return RETURN_ERR;
14825 }
14826
developera3511852023-06-14 14:12:59 +080014827 if((fp = popen(command, "r")))
14828 {
14829 fgets(output, sizeof(output), fp);
14830 *freqMHz = atoi(output);
14831 pclose(fp);
14832 }
developer72fb0bb2023-01-11 09:46:29 +080014833
developera3511852023-06-14 14:12:59 +080014834 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014835}
14836
developer2f79c922023-06-02 17:33:42 +080014837static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
developer72fb0bb2023-01-11 09:46:29 +080014838{
developera3511852023-06-14 14:12:59 +080014839 int freqMHz = -1;
14840 char cmd[MAX_CMD_SIZE] = {'\0'};
14841 char interface_name[16] = {0};
developer32f2a182023-06-27 19:50:41 +080014842 int res;
developer72fb0bb2023-01-11 09:46:29 +080014843
developera3511852023-06-14 14:12:59 +080014844 ieee80211_channel_to_frequency(channel, &freqMHz);
14845 if (freqMHz == -1) {
14846 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
14847 return -1;
14848 }
developer72fb0bb2023-01-11 09:46:29 +080014849
developer86035662023-06-28 19:21:12 +080014850 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
14851 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
14852 }
developer32f2a182023-06-27 19:50:41 +080014853 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz);
14854 if (os_snprintf_error(sizeof(cmd), res)) {
14855 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14856 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080014857 }
developer72fb0bb2023-01-11 09:46:29 +080014858
developera3511852023-06-14 14:12:59 +080014859 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
14860 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
14861 return -1;
14862 }
developer72fb0bb2023-01-11 09:46:29 +080014863
developera3511852023-06-14 14:12:59 +080014864 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014865}
14866
14867static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
14868{
developera3511852023-06-14 14:12:59 +080014869 const char *ptr = buf;
14870 char *key = NULL;
14871 char *val = NULL;
14872 char line[256] = { '\0' };
developer72fb0bb2023-01-11 09:46:29 +080014873
developera3511852023-06-14 14:12:59 +080014874 while ((ptr = get_line_from_str_buf(ptr, line))) {
14875 if (strstr(line, "Frequency")) continue;
developer72fb0bb2023-01-11 09:46:29 +080014876
developera3511852023-06-14 14:12:59 +080014877 key = strtok(line, ":");
14878 val = strtok(NULL, " ");
14879 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
developer72fb0bb2023-01-11 09:46:29 +080014880
developera3511852023-06-14 14:12:59 +080014881 if (!strcmp(key, "noise")) {
14882 sscanf(val, "%d", &stats->ch_noise);
14883 if (stats->ch_noise == 0) {
14884 // Workaround for missing noise information.
14885 // Assume -95 for 2.4G and -103 for 5G
14886 if (radioIndex == 0) stats->ch_noise = -95;
14887 if (radioIndex == 1) stats->ch_noise = -103;
14888 }
14889 }
14890 else if (!strcmp(key, "channel active time")) {
14891 sscanf(val, "%llu", &stats->ch_utilization_total);
14892 }
14893 else if (!strcmp(key, "channel busy time")) {
14894 sscanf(val, "%llu", &stats->ch_utilization_busy);
14895 }
14896 else if (!strcmp(key, "channel receive time")) {
14897 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
14898 }
14899 else if (!strcmp(key, "channel transmit time")) {
14900 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
14901 }
14902 };
developer72fb0bb2023-01-11 09:46:29 +080014903
developera3511852023-06-14 14:12:59 +080014904 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014905}
14906
14907INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
14908{
developera3511852023-06-14 14:12:59 +080014909 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014910#ifdef HAL_NETLINK_IMPL
developera3511852023-06-14 14:12:59 +080014911 Netlink nl;
14912 wifi_channelStats_t_loc local[array_size];
14913 char if_name[32];
developer72fb0bb2023-01-11 09:46:29 +080014914
developera3511852023-06-14 14:12:59 +080014915 local[0].array_size = array_size;
developer72fb0bb2023-01-11 09:46:29 +080014916
developera3511852023-06-14 14:12:59 +080014917 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
14918 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014919
developera3511852023-06-14 14:12:59 +080014920 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014921
developera3511852023-06-14 14:12:59 +080014922 if (nl.id < 0) {
14923 fprintf(stderr, "Error initializing netlink \n");
14924 return -1;
14925 }
developer72fb0bb2023-01-11 09:46:29 +080014926
developera3511852023-06-14 14:12:59 +080014927 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014928
developera3511852023-06-14 14:12:59 +080014929 if (!msg) {
14930 fprintf(stderr, "Failed to allocate netlink message.\n");
14931 nlfree(&nl);
14932 return -2;
14933 }
developer72fb0bb2023-01-11 09:46:29 +080014934
developera3511852023-06-14 14:12:59 +080014935 genlmsg_put(msg,
14936 NL_AUTO_PID,
14937 NL_AUTO_SEQ,
14938 nl.id,
14939 0,
14940 NLM_F_DUMP,
14941 NL80211_CMD_GET_SURVEY,
14942 0);
developer72fb0bb2023-01-11 09:46:29 +080014943
developera3511852023-06-14 14:12:59 +080014944 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14945 nl_send_auto_complete(nl.socket, msg);
14946 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
14947 nl_recvmsgs(nl.socket, nl.cb);
14948 nlmsg_free(msg);
14949 nlfree(&nl);
14950 //Copying the Values
14951 for(int i=0;i<array_size;i++)
14952 {
14953 input_output_channelStats_array[i].ch_number = local[i].ch_number;
14954 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
14955 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
14956 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
14957 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
14958 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
14959 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
14960 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
14961 }
developer72fb0bb2023-01-11 09:46:29 +080014962#else
developera3511852023-06-14 14:12:59 +080014963 ULONG channel = 0;
14964 int i;
14965 int number_of_channels = array_size;
14966 char buf[512];
developer72fb0bb2023-01-11 09:46:29 +080014967
developera3511852023-06-14 14:12:59 +080014968 if (number_of_channels == 0) {
14969 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
14970 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
14971 return RETURN_ERR;
14972 }
14973 number_of_channels = 1;
14974 input_output_channelStats_array[0].ch_number = channel;
14975 }
developer72fb0bb2023-01-11 09:46:29 +080014976
developera3511852023-06-14 14:12:59 +080014977 for (i = 0; i < number_of_channels; i++) {
developer72fb0bb2023-01-11 09:46:29 +080014978
developera3511852023-06-14 14:12:59 +080014979 input_output_channelStats_array[i].ch_noise = 0;
14980 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
14981 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
14982 input_output_channelStats_array[i].ch_utilization_busy = 0;
14983 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
14984 input_output_channelStats_array[i].ch_utilization_total = 0;
developer72fb0bb2023-01-11 09:46:29 +080014985
developera3511852023-06-14 14:12:59 +080014986 memset(buf, 0, sizeof(buf));
14987 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
14988 return RETURN_ERR;
14989 }
14990 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
14991 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
14992 return RETURN_ERR;
14993 }
developer72fb0bb2023-01-11 09:46:29 +080014994
developera3511852023-06-14 14:12:59 +080014995 // XXX: fake missing 'self' counter which is not available in iw survey output
14996 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
14997 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 +080014998
developera3511852023-06-14 14:12:59 +080014999 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
15000 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
15001 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
15002 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
15003 input_output_channelStats_array[i].ch_utilization_total *= 1000;
developer72fb0bb2023-01-11 09:46:29 +080015004
developera3511852023-06-14 14:12:59 +080015005 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",
15006 __func__,
15007 input_output_channelStats_array[i].ch_number,
15008 input_output_channelStats_array[i].ch_noise,
15009 input_output_channelStats_array[i].ch_utilization_total,
15010 input_output_channelStats_array[i].ch_utilization_busy,
15011 input_output_channelStats_array[i].ch_utilization_busy_rx,
15012 input_output_channelStats_array[i].ch_utilization_busy_tx,
15013 input_output_channelStats_array[i].ch_utilization_busy_self,
15014 input_output_channelStats_array[i].ch_utilization_busy_ext);
15015 }
developer72fb0bb2023-01-11 09:46:29 +080015016#endif
developera3511852023-06-14 14:12:59 +080015017 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15018 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015019}
15020#define HAL_NETLINK_IMPL
15021
15022/* Hostapd events */
15023
15024#ifndef container_of
15025#define offset_of(st, m) ((size_t)&(((st *)0)->m))
15026#define container_of(ptr, type, member) \
developera3511852023-06-14 14:12:59 +080015027 ((type *)((char *)ptr - offset_of(type, member)))
developer72fb0bb2023-01-11 09:46:29 +080015028#endif /* container_of */
15029
15030struct ctrl {
developera3511852023-06-14 14:12:59 +080015031 char sockpath[128];
15032 char sockdir[128];
15033 char bss[IFNAMSIZ];
15034 char reply[4096];
15035 int ssid_index;
15036 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
15037 void (*overrun)(struct ctrl *ctrl);
15038 struct wpa_ctrl *wpa;
15039 unsigned int ovfl;
15040 size_t reply_len;
15041 int initialized;
15042 ev_timer retry;
15043 ev_timer watchdog;
15044 ev_stat stat;
15045 ev_io io;
developer72fb0bb2023-01-11 09:46:29 +080015046};
15047static wifi_newApAssociatedDevice_callback clients_connect_cb;
15048static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
15049static struct ctrl wpa_ctrl[MAX_APS];
15050static int initialized;
15051
15052static unsigned int ctrl_get_drops(struct ctrl *ctrl)
15053{
developera3511852023-06-14 14:12:59 +080015054 char cbuf[256] = {};
15055 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
15056 struct cmsghdr *cmsg;
15057 unsigned int ovfl = ctrl->ovfl;
developer86035662023-06-28 19:21:12 +080015058 unsigned int drop = 0;
developer72fb0bb2023-01-11 09:46:29 +080015059
developer86035662023-06-28 19:21:12 +080015060 if (recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT) < 0)
15061 return drop;
developera3511852023-06-14 14:12:59 +080015062 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
15063 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
15064 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
developer72fb0bb2023-01-11 09:46:29 +080015065
developera3511852023-06-14 14:12:59 +080015066 drop = ovfl - ctrl->ovfl;
15067 ctrl->ovfl = ovfl;
developer72fb0bb2023-01-11 09:46:29 +080015068
developera3511852023-06-14 14:12:59 +080015069 return drop;
developer72fb0bb2023-01-11 09:46:29 +080015070}
15071
15072static void ctrl_close(struct ctrl *ctrl)
15073{
developera3511852023-06-14 14:12:59 +080015074 if (ctrl->io.cb)
15075 ev_io_stop(EV_DEFAULT_ &ctrl->io);
15076 if (ctrl->retry.cb)
15077 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
15078 if (!ctrl->wpa)
15079 return;
developer72fb0bb2023-01-11 09:46:29 +080015080
developera3511852023-06-14 14:12:59 +080015081 wpa_ctrl_detach(ctrl->wpa);
15082 wpa_ctrl_close(ctrl->wpa);
15083 ctrl->wpa = NULL;
15084 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
developer72fb0bb2023-01-11 09:46:29 +080015085}
15086
15087static void ctrl_process(struct ctrl *ctrl)
15088{
developera3511852023-06-14 14:12:59 +080015089 const char *str;
15090 int drops;
15091 int level;
developer72fb0bb2023-01-11 09:46:29 +080015092
developera3511852023-06-14 14:12:59 +080015093 /* Example events:
15094 *
15095 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
15096 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
15097 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
15098 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
15099 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
15100 */
15101 if (!(str = index(ctrl->reply, '>')))
15102 return;
15103 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
15104 return;
developer72fb0bb2023-01-11 09:46:29 +080015105
developera3511852023-06-14 14:12:59 +080015106 str++;
developer72fb0bb2023-01-11 09:46:29 +080015107
developera3511852023-06-14 14:12:59 +080015108 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
15109 if (!(str = index(ctrl->reply, ' ')))
15110 return;
15111 wifi_associated_dev_t sta;
15112 memset(&sta, 0, sizeof(sta));
developer72fb0bb2023-01-11 09:46:29 +080015113
developera3511852023-06-14 14:12:59 +080015114 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
15115 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
15116 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
developer72fb0bb2023-01-11 09:46:29 +080015117
developera3511852023-06-14 14:12:59 +080015118 sta.cli_Active=true;
developer72fb0bb2023-01-11 09:46:29 +080015119
developera3511852023-06-14 14:12:59 +080015120 (clients_connect_cb)(ctrl->ssid_index, &sta);
15121 goto handled;
15122 }
developer72fb0bb2023-01-11 09:46:29 +080015123
developera3511852023-06-14 14:12:59 +080015124 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
15125 if (!(str = index(ctrl->reply, ' ')))
15126 return;
developer72fb0bb2023-01-11 09:46:29 +080015127
developera3511852023-06-14 14:12:59 +080015128 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
15129 goto handled;
15130 }
developer72fb0bb2023-01-11 09:46:29 +080015131
developera3511852023-06-14 14:12:59 +080015132 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
15133 printf("CTRL_WPA: handle TERMINATING event\n");
15134 goto retry;
15135 }
developer72fb0bb2023-01-11 09:46:29 +080015136
developera3511852023-06-14 14:12:59 +080015137 if (strncmp("AP-DISABLED", str, 11) == 0) {
15138 printf("CTRL_WPA: handle AP-DISABLED\n");
15139 goto retry;
15140 }
developer72fb0bb2023-01-11 09:46:29 +080015141
developera3511852023-06-14 14:12:59 +080015142 printf("Event not supported!!\n");
developer72fb0bb2023-01-11 09:46:29 +080015143
15144handled:
15145
developera3511852023-06-14 14:12:59 +080015146 if ((drops = ctrl_get_drops(ctrl))) {
15147 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
15148 if (ctrl->overrun)
15149 ctrl->overrun(ctrl);
15150 }
developer72fb0bb2023-01-11 09:46:29 +080015151
developera3511852023-06-14 14:12:59 +080015152 return;
developer72fb0bb2023-01-11 09:46:29 +080015153
15154retry:
developera3511852023-06-14 14:12:59 +080015155 printf("WPA_CTRL: closing\n");
15156 ctrl_close(ctrl);
15157 printf("WPA_CTRL: retrying from ctrl prcoess\n");
15158 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
developer72fb0bb2023-01-11 09:46:29 +080015159}
15160
15161static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
15162{
developera3511852023-06-14 14:12:59 +080015163 struct ctrl *ctrl = container_of(io, struct ctrl, io);
15164 int err;
developer72fb0bb2023-01-11 09:46:29 +080015165
developera3511852023-06-14 14:12:59 +080015166 memset(ctrl->reply, 0, sizeof(ctrl->reply));
15167 ctrl->reply_len = sizeof(ctrl->reply) - 1;
15168 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
15169 ctrl->reply[ctrl->reply_len] = 0;
15170 if (err < 0) {
15171 if (errno == EAGAIN || errno == EWOULDBLOCK)
15172 return;
15173 ctrl_close(ctrl);
15174 ev_timer_again(EV_A_ &ctrl->retry);
15175 return;
15176 }
developer72fb0bb2023-01-11 09:46:29 +080015177
developera3511852023-06-14 14:12:59 +080015178 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015179}
15180
15181static int ctrl_open(struct ctrl *ctrl)
15182{
developera3511852023-06-14 14:12:59 +080015183 int fd;
developer72fb0bb2023-01-11 09:46:29 +080015184
developera3511852023-06-14 14:12:59 +080015185 if (ctrl->wpa)
15186 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015187
developera3511852023-06-14 14:12:59 +080015188 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
15189 if (!ctrl->wpa)
15190 goto err;
developer72fb0bb2023-01-11 09:46:29 +080015191
developera3511852023-06-14 14:12:59 +080015192 if (wpa_ctrl_attach(ctrl->wpa) < 0)
15193 goto err_close;
developer72fb0bb2023-01-11 09:46:29 +080015194
developera3511852023-06-14 14:12:59 +080015195 fd = wpa_ctrl_get_fd(ctrl->wpa);
15196 if (fd < 0)
15197 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080015198
developera3511852023-06-14 14:12:59 +080015199 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
15200 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080015201
developera3511852023-06-14 14:12:59 +080015202 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
15203 ev_io_start(EV_DEFAULT_ &ctrl->io);
developer72fb0bb2023-01-11 09:46:29 +080015204
developera3511852023-06-14 14:12:59 +080015205 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015206
15207err_detach:
developera3511852023-06-14 14:12:59 +080015208 wpa_ctrl_detach(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080015209err_close:
developera3511852023-06-14 14:12:59 +080015210 wpa_ctrl_close(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080015211err:
developera3511852023-06-14 14:12:59 +080015212 ctrl->wpa = NULL;
15213 return -1;
developer72fb0bb2023-01-11 09:46:29 +080015214}
15215
15216static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
15217{
developera3511852023-06-14 14:12:59 +080015218 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
developer72fb0bb2023-01-11 09:46:29 +080015219
developera3511852023-06-14 14:12:59 +080015220 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
15221 ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015222}
15223
15224static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
15225{
developera3511852023-06-14 14:12:59 +080015226 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
developer72fb0bb2023-01-11 09:46:29 +080015227
developera3511852023-06-14 14:12:59 +080015228 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
15229 if (ctrl_open(ctrl) == 0) {
15230 printf("WPA_CTRL: retry successful\n");
15231 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
15232 }
developer72fb0bb2023-01-11 09:46:29 +080015233}
15234
15235int ctrl_enable(struct ctrl *ctrl)
15236{
developera3511852023-06-14 14:12:59 +080015237 if (ctrl->wpa)
15238 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015239
developera3511852023-06-14 14:12:59 +080015240 if (!ctrl->stat.cb) {
15241 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
15242 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
15243 }
developer72fb0bb2023-01-11 09:46:29 +080015244
developera3511852023-06-14 14:12:59 +080015245 if (!ctrl->retry.cb) {
15246 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
15247 }
developer72fb0bb2023-01-11 09:46:29 +080015248
developera3511852023-06-14 14:12:59 +080015249 return ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015250}
15251
15252static void
15253ctrl_msg_cb(char *buf, size_t len)
15254{
developera3511852023-06-14 14:12:59 +080015255 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
developer72fb0bb2023-01-11 09:46:29 +080015256
developera3511852023-06-14 14:12:59 +080015257 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
15258 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015259}
15260
15261static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
15262{
developera3511852023-06-14 14:12:59 +080015263 int err;
developer72fb0bb2023-01-11 09:46:29 +080015264
developera3511852023-06-14 14:12:59 +080015265 if (!ctrl->wpa)
15266 return -1;
15267 if (*reply_len < 2)
15268 return -1;
developer72fb0bb2023-01-11 09:46:29 +080015269
developera3511852023-06-14 14:12:59 +080015270 (*reply_len)--;
15271 ctrl->reply_len = sizeof(ctrl->reply);
15272 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
15273 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
15274 if (err < 0)
15275 return err;
developer72fb0bb2023-01-11 09:46:29 +080015276
developera3511852023-06-14 14:12:59 +080015277 if (ctrl->reply_len > *reply_len)
15278 ctrl->reply_len = *reply_len;
developer72fb0bb2023-01-11 09:46:29 +080015279
developera3511852023-06-14 14:12:59 +080015280 *reply_len = ctrl->reply_len;
15281 memcpy(reply, ctrl->reply, *reply_len);
15282 reply[*reply_len - 1] = 0;
15283 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
15284 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015285}
15286
15287static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
15288{
developera3511852023-06-14 14:12:59 +080015289 const char *pong = "PONG";
15290 const char *ping = "PING";
15291 char reply[1024];
15292 size_t len = sizeof(reply);
15293 int err;
15294 ULONG s, snum;
15295 INT ret;
15296 BOOL status;
developer72fb0bb2023-01-11 09:46:29 +080015297
developera3511852023-06-14 14:12:59 +080015298 printf("WPA_CTRL: watchdog cb\n");
developer72fb0bb2023-01-11 09:46:29 +080015299
developera3511852023-06-14 14:12:59 +080015300 ret = wifi_getSSIDNumberOfEntries(&snum);
15301 if (ret != RETURN_OK) {
15302 printf("%s: failed to get SSID count", __func__);
15303 return;
15304 }
developer72fb0bb2023-01-11 09:46:29 +080015305
developera3511852023-06-14 14:12:59 +080015306 if (snum > MAX_APS) {
15307 printf("more ssid than supported! %lu\n", snum);
15308 return;
15309 }
developer72fb0bb2023-01-11 09:46:29 +080015310
developera3511852023-06-14 14:12:59 +080015311 for (s = 0; s < snum; s++) {
15312 if (wifi_getApEnable(s, &status) != RETURN_OK) {
15313 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
15314 continue;
15315 }
15316 if (status == false) continue;
developer72fb0bb2023-01-11 09:46:29 +080015317
developera3511852023-06-14 14:12:59 +080015318 memset(reply, 0, sizeof(reply));
15319 len = sizeof(reply);
15320 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
15321 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
15322 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
15323 continue;
developer72fb0bb2023-01-11 09:46:29 +080015324
developera3511852023-06-14 14:12:59 +080015325 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
15326 ctrl_close(&wpa_ctrl[s]);
15327 printf("WPA_CTRL: ev_timer_again %lu\n", s);
15328 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
15329 }
developer72fb0bb2023-01-11 09:46:29 +080015330}
15331
15332static int init_wpa()
15333{
developer9ce44382023-06-28 11:09:37 +080015334 int ret = 0;
developera3511852023-06-14 14:12:59 +080015335 ULONG s, snum;
developer72fb0bb2023-01-11 09:46:29 +080015336
developera3511852023-06-14 14:12:59 +080015337 ret = wifi_getSSIDNumberOfEntries(&snum);
15338 if (ret != RETURN_OK) {
15339 printf("%s: failed to get SSID count", __func__);
15340 return RETURN_ERR;
15341 }
developer72fb0bb2023-01-11 09:46:29 +080015342
developera3511852023-06-14 14:12:59 +080015343 if (snum > MAX_APS) {
15344 printf("more ssid than supported! %lu\n", snum);
15345 return RETURN_ERR;
15346 }
developer72fb0bb2023-01-11 09:46:29 +080015347
developera3511852023-06-14 14:12:59 +080015348 for (s = 0; s < snum; s++) {
15349 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
developer32f2a182023-06-27 19:50:41 +080015350 ret = snprintf(wpa_ctrl[s].sockpath, sizeof(wpa_ctrl[s].sockpath), "%s%lu", SOCK_PREFIX, s);
15351 if (os_snprintf_error(sizeof(wpa_ctrl[s].sockpath), ret)) {
15352 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15353 return RETURN_ERR;
15354 }
developera3511852023-06-14 14:12:59 +080015355 wpa_ctrl[s].ssid_index = s;
15356 ctrl_enable(&wpa_ctrl[s]);
15357 }
developer72fb0bb2023-01-11 09:46:29 +080015358
developera3511852023-06-14 14:12:59 +080015359 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
15360 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
developer72fb0bb2023-01-11 09:46:29 +080015361
developera3511852023-06-14 14:12:59 +080015362 initialized = 1;
15363 printf("WPA_CTRL: initialized\n");
developer72fb0bb2023-01-11 09:46:29 +080015364
developera3511852023-06-14 14:12:59 +080015365 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015366}
15367
15368void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
15369{
developera3511852023-06-14 14:12:59 +080015370 clients_connect_cb = callback_proc;
15371 if (!initialized)
15372 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080015373}
15374
15375void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
15376{
developera3511852023-06-14 14:12:59 +080015377 clients_disconnect_cb = callback_proc;
15378 if (!initialized)
15379 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080015380}
15381
15382INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
15383{
developera3511852023-06-14 14:12:59 +080015384 // TODO Implement me!
15385 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015386}
15387
15388INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
15389{
developera3511852023-06-14 14:12:59 +080015390 // TODO Implement me!
15391 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015392}
15393
15394INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
15395{
developera3511852023-06-14 14:12:59 +080015396 int i;
15397 int phyId = -1;
15398 char cmd[256] = {0};
15399 char channel_numbers_buf[256] = {0};
15400 char dfs_state_buf[256] = {0};
15401 char line[256] = {0};
15402 const char *ptr;
15403 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +080015404 int res;
developer72fb0bb2023-01-11 09:46:29 +080015405
developera3511852023-06-14 14:12:59 +080015406 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080015407
developera3511852023-06-14 14:12:59 +080015408 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
15409 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080015410
developere40952c2023-06-15 18:46:43 +080015411 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\\|");
15412 if (os_snprintf_error(sizeof(cmd), res)) {
15413 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15414 return RETURN_ERR;
15415 }
developer72fb0bb2023-01-11 09:46:29 +080015416
developera3511852023-06-14 14:12:59 +080015417 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
15418 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
15419 return RETURN_ERR;
15420 }
developer72fb0bb2023-01-11 09:46:29 +080015421
developera3511852023-06-14 14:12:59 +080015422 ptr = channel_numbers_buf;
15423 i = 0;
15424 while ((ptr = get_line_from_str_buf(ptr, line))) {
15425 if (i >= outputMapSize) {
15426 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
15427 return RETURN_ERR;
15428 }
15429 sscanf(line, "%d", &outputMap[i].ch_number);
developerd1824452023-05-18 12:30:04 +080015430
developera3511852023-06-14 14:12:59 +080015431 memset(cmd, 0, sizeof(cmd));
15432 // Below command should fetch string for DFS state (usable, available or unavailable)
15433 // Example line: "DFS state: usable (for 78930 sec)"
15434 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) {
15435 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
15436 return RETURN_ERR;
15437 }
developer72fb0bb2023-01-11 09:46:29 +080015438
developera3511852023-06-14 14:12:59 +080015439 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
15440 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
15441 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
15442 return RETURN_ERR;
15443 }
developer72fb0bb2023-01-11 09:46:29 +080015444
developera3511852023-06-14 14:12:59 +080015445 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080015446
developera3511852023-06-14 14:12:59 +080015447 if (!strcmp(dfs_state_buf, "usable")) {
15448 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
15449 } else if (!strcmp(dfs_state_buf, "available")) {
15450 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
15451 } else if (!strcmp(dfs_state_buf, "unavailable")) {
15452 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
15453 } else {
15454 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
15455 }
15456 i++;
15457 }
developer40ba1762023-05-13 11:03:49 +080015458
developera3511852023-06-14 14:12:59 +080015459 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +080015460
developera3511852023-06-14 14:12:59 +080015461 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
15462 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015463}
15464
15465INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
15466{
developera3511852023-06-14 14:12:59 +080015467 // TODO Implement me!
15468 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015469}
15470
15471INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
15472{
developer0155a502023-06-19 20:33:57 +080015473 int ret = -1;
15474 char inf_name[IF_NAME_SIZE] = {0};
15475 int if_idx = 0;
15476 struct unl unl_ins;
15477 struct nl_msg *msg = NULL;
15478 struct nlattr * msg_data = NULL;
15479 struct mtk_nl80211_param param;
15480 struct mtk_nl80211_cb_data cb_data;
15481 wdev_ap_metric ap_metric;
15482
15483 /*init mtk nl80211 vendor cmd*/
15484
15485 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
15486 return RETURN_ERR;
15487 if_idx = if_nametoindex(inf_name);
15488 if (!if_idx) {
15489 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
15490 return RETURN_ERR;
15491 }
15492
15493 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STATISTIC;
15494 param.if_type = NL80211_ATTR_IFINDEX;
15495 param.if_idx = if_idx;
15496
15497 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
15498 if (ret) {
15499 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
15500 return RETURN_ERR;
15501 }
15502
15503 /*add mtk vendor cmd data*/
15504
15505 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS, sizeof(wdev_ap_metric), (char *)&ap_metric)) {
15506 wifi_debug(DEBUG_ERROR, "Nla put GET_AP_METRICS attribute error\n");
15507 nlmsg_free(msg);
15508 goto err;
15509 }
15510
15511 /*send mtk nl80211 vendor msg*/
15512 cb_data.out_buf = (char *)output_percentage;
15513 cb_data.out_len = sizeof(wdev_ap_metric);
15514 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_metrics, &cb_data);
15515 if (ret) {
15516 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
15517 goto err;
15518 }
15519
15520 /*deinit mtk nl80211 vendor msg*/
15521 mtk_nl80211_deint(&unl_ins);
15522 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
15523 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15524
developera3511852023-06-14 14:12:59 +080015525 return RETURN_OK;
developer0155a502023-06-19 20:33:57 +080015526err:
15527 mtk_nl80211_deint(&unl_ins);
15528 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
15529 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015530}
15531
developer0155a502023-06-19 20:33:57 +080015532
developer72fb0bb2023-01-11 09:46:29 +080015533INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
15534{
developera3511852023-06-14 14:12:59 +080015535 // TODO Implement me!
15536 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015537}
15538
15539INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
15540{
developera3511852023-06-14 14:12:59 +080015541 // TODO API refrence Implementaion is present on RPI hal
15542 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015543}
15544
15545INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
15546{
developera3511852023-06-14 14:12:59 +080015547 ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080015548
developera3511852023-06-14 14:12:59 +080015549 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15550 if(txpwr_pcntg == NULL)
developerdaf24792023-06-06 11:40:04 +080015551 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015552
developera1255e42023-05-13 17:45:02 +080015553 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
15554 *txpwr_pcntg = pwr_percentage;
developera3511852023-06-14 14:12:59 +080015555 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15556 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015557}
15558
15559INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
15560{
developera3511852023-06-14 14:12:59 +080015561 // TODO precac feature.
15562 struct params params[2] = {0};
15563 char config_file[128] = {0};
15564 BOOL dfs_enable = false;
15565 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080015566 int res;
developer72fb0bb2023-01-11 09:46:29 +080015567
developera3511852023-06-14 14:12:59 +080015568 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15569 band = wifi_index_to_band(radioIndex);
15570 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080015571
developera3511852023-06-14 14:12:59 +080015572 if (dfs_enable == false) {
15573 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
15574 return RETURN_ERR;
15575 }
15576 params[0].name = "DfsZeroWaitDefault";
15577 params[0].value = enable?"1":"0";
15578 params[1].name = "DfsDedicatedZeroWait";
15579 params[1].value = enable?"1":"0";
developere40952c2023-06-15 18:46:43 +080015580 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15581 if (os_snprintf_error(sizeof(config_file), res)) {
15582 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15583 return RETURN_ERR;
15584 }
developera3511852023-06-14 14:12:59 +080015585 wifi_datfileWrite(config_file, params, 2);
15586 wifi_reloadAp(radioIndex);
15587 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080015588
developera3511852023-06-14 14:12:59 +080015589 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15590 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015591}
15592
15593INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
15594{
developera3511852023-06-14 14:12:59 +080015595 char config_file[128] = {0};
15596 char buf1[32] = {0};
15597 char buf2[32] = {0};
15598 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080015599 int res;
developer72fb0bb2023-01-11 09:46:29 +080015600
developera3511852023-06-14 14:12:59 +080015601 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15602 if (NULL == enable || NULL == precac)
15603 return RETURN_ERR;
15604 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080015605 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15606 if (os_snprintf_error(sizeof(config_file), res)) {
15607 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15608 return RETURN_ERR;
15609 }
developera3511852023-06-14 14:12:59 +080015610 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
15611 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
15612 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
15613 *enable = true;
15614 else
15615 *enable = false;
developer72fb0bb2023-01-11 09:46:29 +080015616
developera3511852023-06-14 14:12:59 +080015617 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080015618
developera3511852023-06-14 14:12:59 +080015619 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15620 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015621}
15622
15623INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
15624{
developera3511852023-06-14 14:12:59 +080015625 *supported = TRUE;
15626 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015627}
15628
15629INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
15630{
developer863a4a62023-06-06 16:55:59 +080015631 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080015632 wifi_band band = band_invalid;
15633 char ofdmabuf[32] = {'\0'};
15634 char mimobuf[32] = {'\0'};
15635 char new_ofdmabuf[32] = {'\0'};
15636 char new_mimobuf[32] = {'\0'};
15637 struct params params[2];
developera1255e42023-05-13 17:45:02 +080015638 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
15639 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
15640 UCHAR bss_cnt = 0;
15641 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080015642 int res;
developer72fb0bb2023-01-11 09:46:29 +080015643
developera3511852023-06-14 14:12:59 +080015644 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +080015645 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
15646 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
15647 printf("%s:mu_type input Error", __func__);
15648 return RETURN_ERR;
15649 }
developera3511852023-06-14 14:12:59 +080015650 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080015651 if (band == band_invalid) {
15652 printf("%s:Band Error\n", __func__);
15653 return RETURN_ERR;
15654 }
developere40952c2023-06-15 18:46:43 +080015655 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15656 if (os_snprintf_error(sizeof(dat_file), res)) {
15657 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15658 return RETURN_ERR;
15659 }
15660
developera1255e42023-05-13 17:45:02 +080015661 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080015662 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
15663 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080015664 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
15665 get_bssnum_byindex(radio_index, &bss_cnt);
15666 val_cnt = 2*bss_cnt - 1;
15667 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
15668 if ((val_cnt >= sizeof(new_ofdmabuf))
15669 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080015670 printf("%s:bss cnt Error", __func__);
developera1255e42023-05-13 17:45:02 +080015671 return RETURN_ERR;
15672 }
15673 /*translate set value*/
15674 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
15675 strncpy(new_ofdmabuf, str_zero, val_cnt);
15676 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080015677 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080015678 strncpy(new_ofdmabuf, str_one, val_cnt);
15679 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080015680 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080015681 strncpy(new_ofdmabuf, str_zero, val_cnt);
15682 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080015683 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
developera1255e42023-05-13 17:45:02 +080015684 strncpy(new_ofdmabuf, str_one, val_cnt);
15685 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080015686 }
developera1255e42023-05-13 17:45:02 +080015687 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
15688 /*same value, not operation*/
15689 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
15690 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
15691 printf("%s:Reduntant value\n", __func__);
15692 return RETURN_OK;
15693 }
15694 /*modify dat file to new file*/
15695 params[0].name="MuOfdmaDlEnable";
15696 params[0].value=new_ofdmabuf;
15697 params[1].name="MuMimoDlEnable";
15698 params[1].value=new_mimobuf;
15699 wifi_datfileWrite(dat_file, params, 2);
15700 /*hostapd control restarp ap to take effect on these new value*/
15701 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080015702 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15703 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015704}
15705
15706INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
15707{
developer5a333cf2023-06-06 18:18:50 +080015708 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080015709 wifi_band band = band_invalid;
15710 char ofdmabuf[32] = {'\0'};
15711 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080015712 char *token = NULL;
15713 UCHAR ofdma = 0;
15714 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080015715 int res;
developer72fb0bb2023-01-11 09:46:29 +080015716
developera3511852023-06-14 14:12:59 +080015717 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015718
developera3511852023-06-14 14:12:59 +080015719 if (mu_type == NULL)
15720 return RETURN_ERR;
15721 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080015722 if (band == band_invalid) {
15723 printf("%s:Band Error\n", __func__);
15724 return RETURN_ERR;
15725 }
developere40952c2023-06-15 18:46:43 +080015726 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15727 if (os_snprintf_error(sizeof(dat_file), res)) {
15728 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15729 return RETURN_ERR;
15730 }
developera1255e42023-05-13 17:45:02 +080015731 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080015732 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
15733 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080015734
developera1255e42023-05-13 17:45:02 +080015735 token = strtok(ofdmabuf, ";");
15736 ofdma = strtol(token, NULL, 10);
15737 token = strtok(mimobuf, ";");
15738 mimo = strtol(token, NULL, 10);
15739 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
15740 if ((ofdma == 1) && (mimo == 1))
15741 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
15742 else if ((ofdma == 0) && (mimo == 1))
15743 *mu_type = WIFI_DL_MU_TYPE_MIMO;
15744 else if ((ofdma == 1) && (mimo == 0))
15745 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
15746 else
15747 *mu_type = WIFI_DL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080015748 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15749 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015750}
15751
15752INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
15753{
developera3511852023-06-14 14:12:59 +080015754 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developer863a4a62023-06-06 16:55:59 +080015755 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080015756 wifi_band band = band_invalid;
15757 char ofdmabuf[32] = {'\0'};
15758 char mimobuf[32] = {'\0'};
15759 char new_ofdmabuf[32] = {'\0'};
15760 char new_mimobuf[32] = {'\0'};
15761 struct params params[2];
developera1255e42023-05-13 17:45:02 +080015762 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
15763 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
15764 UCHAR bss_cnt = 0;
15765 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080015766 int res;
developer72fb0bb2023-01-11 09:46:29 +080015767
developera3511852023-06-14 14:12:59 +080015768 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15769 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080015770 if (band == band_invalid) {
15771 printf("%s:Band Error\n", __func__);
15772 return RETURN_ERR;
15773 }
15774 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
15775 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
15776 printf("%s:mu_type input Error\n", __func__);
15777 return RETURN_ERR;
15778 }
developere40952c2023-06-15 18:46:43 +080015779 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15780 if (os_snprintf_error(sizeof(dat_file), res)) {
15781 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15782 return RETURN_ERR;
15783 }
developera1255e42023-05-13 17:45:02 +080015784 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080015785 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
15786 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080015787 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
15788 get_bssnum_byindex(radio_index, &bss_cnt);
15789 val_cnt = 2*bss_cnt - 1;
15790 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
15791 if ((val_cnt >= sizeof(new_ofdmabuf))
15792 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080015793 printf("%s:bss cnt Error\n", __func__);
developera1255e42023-05-13 17:45:02 +080015794 return RETURN_ERR;
15795 }
15796 /*translate set value*/
15797 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
15798 strncpy(new_ofdmabuf, str_zero, val_cnt);
15799 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080015800 }
developera1255e42023-05-13 17:45:02 +080015801 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
15802 strncpy(new_ofdmabuf, str_one, val_cnt);
15803 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080015804 }
developera1255e42023-05-13 17:45:02 +080015805 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
15806 /*same value, not operation*/
15807 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
15808 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
15809 printf("%s:Reduntant value\n", __func__);
15810 return RETURN_OK;
15811 }
15812 /*modify dat file to new file*/
15813 params[0].name="MuOfdmaUlEnable";
15814 params[0].value=new_ofdmabuf;
15815 params[1].name="MuMimoUlEnable";
15816 params[1].value=new_mimobuf;
15817 wifi_datfileWrite(dat_file, params, 2);
15818 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080015819 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15820 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015821}
15822
15823INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
15824{
developer863a4a62023-06-06 16:55:59 +080015825 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080015826 wifi_band band = band_invalid;
15827 char ofdmabuf[32] = {'\0'};
15828 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080015829 char *token = NULL;
15830 UCHAR ofdma = 0;
15831 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080015832 int res;
developer72fb0bb2023-01-11 09:46:29 +080015833
developera3511852023-06-14 14:12:59 +080015834 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015835
developera3511852023-06-14 14:12:59 +080015836 if (mu_type == NULL)
15837 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080015838 band = wifi_index_to_band(radio_index);
15839 if (band == band_invalid) {
15840 printf("%s:Band Error", __func__);
15841 return RETURN_ERR;
15842 }
developere40952c2023-06-15 18:46:43 +080015843 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15844 if (os_snprintf_error(sizeof(dat_file), res)) {
15845 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15846 return RETURN_ERR;
15847 }
developera1255e42023-05-13 17:45:02 +080015848 /*get current value in dat file*/
15849 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
15850 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080015851
developera1255e42023-05-13 17:45:02 +080015852 token = strtok(ofdmabuf, ";");
15853 ofdma = strtol(token, NULL, 10);
15854 token = strtok(mimobuf, ";");
15855 mimo = strtol(token, NULL, 10);
15856 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
15857 if ((ofdma == 1) && (mimo == 0))
15858 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
15859 else
15860 *mu_type = WIFI_UL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080015861 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15862 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015863}
15864
15865
15866INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
15867{
developera3511852023-06-14 14:12:59 +080015868 char cmd[128] = {0};
15869 char buf[256] = {0};
15870 char config_file[64] = {0};
15871 char GI[8] = {0};
15872 UINT mode_map = 0;
15873 FILE *f = NULL;
15874 wifi_band band = band_invalid;
15875 char dat_file[64] = {'\0'};
15876 struct params params[3];
developere40952c2023-06-15 18:46:43 +080015877 int res;
developer72fb0bb2023-01-11 09:46:29 +080015878
developera3511852023-06-14 14:12:59 +080015879 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015880
developera3511852023-06-14 14:12:59 +080015881 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
15882 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
15883 return RETURN_ERR;
15884 }
developera1255e42023-05-13 17:45:02 +080015885 /*sanity check*/
15886 if (((guard_interval == wifi_guard_interval_1600)
15887 || (guard_interval == wifi_guard_interval_3200))
developerdaf24792023-06-06 11:40:04 +080015888 && ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
developera3511852023-06-14 14:12:59 +080015889 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
15890 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080015891 }
developere40952c2023-06-15 18:46:43 +080015892 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
15893 if (os_snprintf_error(sizeof(config_file), res)) {
15894 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15895 return RETURN_ERR;
15896 }
developera3511852023-06-14 14:12:59 +080015897 band = wifi_index_to_band(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080015898
developera3511852023-06-14 14:12:59 +080015899 // Hostapd are not supported HE mode GI 1600, 3200 ns.
15900 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
developere40952c2023-06-15 18:46:43 +080015901 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
15902 if (os_snprintf_error(sizeof(cmd), res)) {
15903 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15904 return RETURN_ERR;
15905 }
developera3511852023-06-14 14:12:59 +080015906 _syscmd(cmd, buf, sizeof(buf));
15907 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
15908 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
15909 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080015910 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
15911 if (os_snprintf_error(sizeof(cmd), res)) {
15912 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15913 return RETURN_ERR;
15914 }
developera3511852023-06-14 14:12:59 +080015915 _syscmd(cmd, buf, sizeof(buf));
15916 }
15917 if (band == band_5) {
15918 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
15919 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080015920 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
15921 if (os_snprintf_error(sizeof(cmd), res)) {
15922 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15923 return RETURN_ERR;
15924 }
developera3511852023-06-14 14:12:59 +080015925 _syscmd(cmd, buf, sizeof(buf));
15926 }
15927 }
15928 }
15929 /*wifi_reloadAp(radio_index);
developera1255e42023-05-13 17:45:02 +080015930 caller "wifi_setRadioOperatingParameters" have done this step.
15931 */
developere40952c2023-06-15 18:46:43 +080015932 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15933 if (os_snprintf_error(sizeof(dat_file), res)) {
15934 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15935 return RETURN_ERR;
15936 }
developera3511852023-06-14 14:12:59 +080015937 if (guard_interval == wifi_guard_interval_400) {
developera1255e42023-05-13 17:45:02 +080015938 params[0].name = "HT_GI";
15939 params[0].value = "1";
15940 params[1].name = "VHT_SGI";
15941 params[1].value = "1";
15942 wifi_datfileWrite(dat_file, params, 2);
developer32f2a182023-06-27 19:50:41 +080015943 memcpy(GI, "0.4", 3);
developera1255e42023-05-13 17:45:02 +080015944 } else {
15945 params[0].name = "HT_GI";
15946 params[0].value = "0";
15947 params[1].name = "VHT_SGI";
15948 params[1].value = "0";
15949 /*should enable FIXED_HE_GI_SUPPORT in driver*/
15950 params[2].name = "FgiFltf";
15951 if (guard_interval == wifi_guard_interval_800) {
15952 params[2].value = "800";
developer32f2a182023-06-27 19:50:41 +080015953 memcpy(GI, "0.8", 3);
developera1255e42023-05-13 17:45:02 +080015954 } else if (guard_interval == wifi_guard_interval_1600) {
15955 params[2].value = "1600";
developer32f2a182023-06-27 19:50:41 +080015956 memcpy(GI, "1.6", 3);
developera1255e42023-05-13 17:45:02 +080015957 } else if (guard_interval == wifi_guard_interval_3200) {
15958 params[2].value = "3200";
developer32f2a182023-06-27 19:50:41 +080015959 memcpy(GI, "3.2", 3);
developera1255e42023-05-13 17:45:02 +080015960 } else if (guard_interval == wifi_guard_interval_auto) {
15961 params[2].value = "0";
developer32f2a182023-06-27 19:50:41 +080015962 memcpy(GI, "auto", 4);
developera1255e42023-05-13 17:45:02 +080015963 }
15964 wifi_datfileWrite(dat_file, params, 3);
15965 }
developera3511852023-06-14 14:12:59 +080015966 // Record GI for get GI function
developere40952c2023-06-15 18:46:43 +080015967 res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
15968 if (os_snprintf_error(sizeof(buf), res)) {
15969 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15970 return RETURN_ERR;
15971 }
developera3511852023-06-14 14:12:59 +080015972 f = fopen(buf, "w");
15973 if (f == NULL)
15974 return RETURN_ERR;
15975 fprintf(f, "%s", GI);
15976 fclose(f);
15977 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15978 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015979}
15980
15981INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
15982{
developera3511852023-06-14 14:12:59 +080015983 char buf[32] = {0};
15984 char cmd[64] = {0};
developere40952c2023-06-15 18:46:43 +080015985 int res;
developer72fb0bb2023-01-11 09:46:29 +080015986
developera3511852023-06-14 14:12:59 +080015987 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015988
developera3511852023-06-14 14:12:59 +080015989 if (guard_interval == NULL)
15990 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015991
developere40952c2023-06-15 18:46:43 +080015992 res = snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
15993 if (os_snprintf_error(sizeof(cmd), res)) {
15994 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15995 return RETURN_ERR;
15996 }
developera3511852023-06-14 14:12:59 +080015997 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015998
developera3511852023-06-14 14:12:59 +080015999 if (strncmp(buf, "0.4", 3) == 0)
16000 *guard_interval = wifi_guard_interval_400;
16001 else if (strncmp(buf, "0.8", 3) == 0)
16002 *guard_interval = wifi_guard_interval_800;
16003 else if (strncmp(buf, "1.6", 3) == 0)
16004 *guard_interval = wifi_guard_interval_1600;
16005 else if (strncmp(buf, "3.2", 3) == 0)
16006 *guard_interval = wifi_guard_interval_3200;
16007 else
16008 *guard_interval = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +080016009
developera3511852023-06-14 14:12:59 +080016010 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16011 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016012}
16013
16014INT wifi_setBSSColor(INT radio_index, UCHAR color)
16015{
developera3511852023-06-14 14:12:59 +080016016 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16017 struct params params = {0};
16018 char config_file[128] = {0};
16019 char bss_color[4] ={0};
developere40952c2023-06-15 18:46:43 +080016020 int res;
developer72fb0bb2023-01-11 09:46:29 +080016021
developera1255e42023-05-13 17:45:02 +080016022 if (color < 1 || color > 63) {
16023 wifi_dbg_printf("color value is err:%d.\n", color);
16024 return RETURN_ERR;
16025 }
developera3511852023-06-14 14:12:59 +080016026 params.name = "he_bss_color";
developere40952c2023-06-15 18:46:43 +080016027 res = snprintf(bss_color, sizeof(bss_color), "%hhu", color);
16028 if (os_snprintf_error(sizeof(bss_color), res)) {
16029 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16030 return RETURN_ERR;
16031 }
developera3511852023-06-14 14:12:59 +080016032 params.value = bss_color;
developer75bd10c2023-06-27 11:34:08 +080016033
16034 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16035 if (os_snprintf_error(sizeof(config_file), res)) {
16036 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16037 return RETURN_ERR;
16038 }
developera3511852023-06-14 14:12:59 +080016039 wifi_hostapdWrite(config_file, &params, 1);
16040 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
developera1255e42023-05-13 17:45:02 +080016041 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080016042
developera3511852023-06-14 14:12:59 +080016043 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16044 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016045}
16046
16047INT wifi_getBSSColor(INT radio_index, UCHAR *color)
16048{
developera3511852023-06-14 14:12:59 +080016049 char config_file[128] = {0};
16050 char buf[64] = {0};
16051 char temp_output[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +080016052 int res;
developer72fb0bb2023-01-11 09:46:29 +080016053
developera3511852023-06-14 14:12:59 +080016054 wifi_dbg_printf("\nFunc=%s\n", __func__);
16055 if (NULL == color)
16056 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016057
developer75bd10c2023-06-27 11:34:08 +080016058 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16059 if (os_snprintf_error(sizeof(config_file), res)) {
16060 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16061 return RETURN_ERR;
16062 }
developera3511852023-06-14 14:12:59 +080016063 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080016064
developera3511852023-06-14 14:12:59 +080016065 if(strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +080016066 res = snprintf(temp_output, sizeof(temp_output), "%s", buf);
developera3511852023-06-14 14:12:59 +080016067 } else {
developere40952c2023-06-15 18:46:43 +080016068 res = snprintf(temp_output, sizeof(temp_output), "1"); // default value
16069 }
16070 if (os_snprintf_error(sizeof(temp_output), res)) {
16071 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16072 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080016073 }
developer72fb0bb2023-01-11 09:46:29 +080016074
developera3511852023-06-14 14:12:59 +080016075 *color = (UCHAR)strtoul(temp_output, NULL, 10);
16076 wifi_dbg_printf("\noutput_string=%s\n", color);
developer72fb0bb2023-01-11 09:46:29 +080016077
developera3511852023-06-14 14:12:59 +080016078 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016079}
16080
16081/* multi-psk support */
16082INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
16083{
developera3511852023-06-14 14:12:59 +080016084 char cmd[256];
16085 char interface_name[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080016086 int res;
developer72fb0bb2023-01-11 09:46:29 +080016087
developera3511852023-06-14 14:12:59 +080016088 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16089 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016090
developer75bd10c2023-06-27 11:34:08 +080016091 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 +080016092 interface_name,
16093 mac[0],
16094 mac[1],
16095 mac[2],
16096 mac[3],
16097 mac[4],
16098 mac[5]
16099 );
developer75bd10c2023-06-27 11:34:08 +080016100 if (os_snprintf_error(sizeof(cmd), res)) {
16101 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16102 return RETURN_ERR;
16103 }
developera3511852023-06-14 14:12:59 +080016104 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
16105 _syscmd(cmd, key->wifi_keyId, 64);
developer72fb0bb2023-01-11 09:46:29 +080016106
16107
developera3511852023-06-14 14:12:59 +080016108 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016109}
16110
16111INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
16112{
developera3511852023-06-14 14:12:59 +080016113 char interface_name[16] = {0};
16114 FILE *fd = NULL;
16115 char fname[100];
16116 char cmd[128] = {0};
16117 char out[64] = {0};
16118 wifi_key_multi_psk_t * key = NULL;
developer75bd10c2023-06-27 11:34:08 +080016119 int res, ret;
developere40952c2023-06-15 18:46:43 +080016120
developera3511852023-06-14 14:12:59 +080016121 if(keysNumber < 0)
16122 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016123
developere40952c2023-06-15 18:46:43 +080016124 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
16125 if (os_snprintf_error(sizeof(fname), res)) {
16126 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16127 return RETURN_ERR;
16128 }
developera3511852023-06-14 14:12:59 +080016129 fd = fopen(fname, "w");
16130 if (!fd) {
16131 return RETURN_ERR;
16132 }
16133 key= (wifi_key_multi_psk_t *) keys;
16134 for(int i=0; i<keysNumber; ++i, key++) {
developer75bd10c2023-06-27 11:34:08 +080016135 ret = fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
16136 if (ret < 0)
16137 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developera3511852023-06-14 14:12:59 +080016138 }
16139 fclose(fd);
developer72fb0bb2023-01-11 09:46:29 +080016140
developera3511852023-06-14 14:12:59 +080016141 //reload file
16142 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16143 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080016144 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
16145
16146 if (os_snprintf_error(sizeof(cmd), res)) {
16147 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16148 return RETURN_ERR;
16149 }
developera3511852023-06-14 14:12:59 +080016150 _syscmd(cmd, out, 64);
16151 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016152}
16153
16154INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
16155{
developera3511852023-06-14 14:12:59 +080016156 FILE *fd = NULL;
16157 char fname[100];
16158 char * line = NULL;
16159 char * pos = NULL;
16160 size_t len = 0;
16161 ssize_t read = 0;
16162 INT ret = RETURN_OK;
16163 wifi_key_multi_psk_t *keys_it = NULL;
developere40952c2023-06-15 18:46:43 +080016164 int res;
developer72fb0bb2023-01-11 09:46:29 +080016165
developera3511852023-06-14 14:12:59 +080016166 if (keysNumber < 1) {
16167 return RETURN_ERR;
16168 }
developer72fb0bb2023-01-11 09:46:29 +080016169
developere40952c2023-06-15 18:46:43 +080016170 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
16171 if (os_snprintf_error(sizeof(fname), res)) {
16172 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16173 return RETURN_ERR;
16174 }
developera3511852023-06-14 14:12:59 +080016175 fd = fopen(fname, "r");
16176 if (!fd) {
16177 return RETURN_ERR;
16178 }
developer72fb0bb2023-01-11 09:46:29 +080016179
developera3511852023-06-14 14:12:59 +080016180 if (keys == NULL) {
16181 ret = RETURN_ERR;
16182 goto close;
16183 }
developer72fb0bb2023-01-11 09:46:29 +080016184
developera3511852023-06-14 14:12:59 +080016185 keys_it = keys;
16186 while ((read = getline(&line, &len, fd)) != -1) {
16187 //Strip trailing new line if present
16188 if (read > 0 && line[read-1] == '\n') {
16189 line[read-1] = '\0';
16190 }
developer72fb0bb2023-01-11 09:46:29 +080016191
developera3511852023-06-14 14:12:59 +080016192 if(strcmp(line,"keyid=")) {
developer32f2a182023-06-27 19:50:41 +080016193 sscanf(line, "keyid=%63s", keys_it->wifi_keyId);
developera3511852023-06-14 14:12:59 +080016194 if (!(pos = index(line, ' '))) {
16195 ret = RETURN_ERR;
16196 goto close;
16197 }
16198 pos++;
16199 //Here should be 00:00:00:00:00:00
16200 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
16201 printf("Not supported MAC: %s\n", pos);
16202 }
16203 if (!(pos = index(pos, ' '))) {
16204 ret = RETURN_ERR;
16205 goto close;
16206 }
16207 pos++;
developer72fb0bb2023-01-11 09:46:29 +080016208
developera3511852023-06-14 14:12:59 +080016209 //The rest is PSK
developere40952c2023-06-15 18:46:43 +080016210 res = snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
16211 if (os_snprintf_error(sizeof(keys_it->wifi_psk), res)) {
16212 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080016213 fclose(fd);
developere40952c2023-06-15 18:46:43 +080016214 return RETURN_ERR;
16215 }
16216
developera3511852023-06-14 14:12:59 +080016217 keys_it++;
developer72fb0bb2023-01-11 09:46:29 +080016218
developera3511852023-06-14 14:12:59 +080016219 if(--keysNumber <= 0)
developer72fb0bb2023-01-11 09:46:29 +080016220 break;
developera3511852023-06-14 14:12:59 +080016221 }
16222 }
developer72fb0bb2023-01-11 09:46:29 +080016223
16224close:
developera3511852023-06-14 14:12:59 +080016225 free(line);
16226 fclose(fd);
16227 return ret;
developer72fb0bb2023-01-11 09:46:29 +080016228}
16229/* end of multi-psk support */
16230
16231INT wifi_setNeighborReports(UINT apIndex,
developera3511852023-06-14 14:12:59 +080016232 UINT numNeighborReports,
16233 wifi_NeighborReport_t *neighborReports)
developer72fb0bb2023-01-11 09:46:29 +080016234{
developera3511852023-06-14 14:12:59 +080016235 char cmd[256] = { 0 };
16236 char hex_bssid[13] = { 0 };
16237 char bssid[18] = { 0 };
16238 char nr[100] = { 0 };
16239 char ssid[32];
16240 char hex_ssid[32];
16241 char interface_name[16] = {0};
16242 INT ret;
developere40952c2023-06-15 18:46:43 +080016243 int res;
developer72fb0bb2023-01-11 09:46:29 +080016244
developera3511852023-06-14 14:12:59 +080016245 /*rmeove all neighbors*/
16246 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
16247 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16248 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080016249 res = snprintf(cmd, sizeof(cmd),
16250 "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
16251 interface_name, interface_name);
16252
developer75bd10c2023-06-27 11:34:08 +080016253 if (os_snprintf_error(sizeof(cmd), res)) {
16254 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16255 return RETURN_ERR;
16256 }
developera3511852023-06-14 14:12:59 +080016257 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080016258
developera3511852023-06-14 14:12:59 +080016259 for(unsigned int i = 0; i < numNeighborReports; i++)
16260 {
16261 memset(ssid, 0, sizeof(ssid));
16262 ret = wifi_getSSIDName(apIndex, ssid);
16263 if (ret != RETURN_OK)
16264 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016265
developera3511852023-06-14 14:12:59 +080016266 memset(hex_ssid, 0, sizeof(hex_ssid));
16267 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
16268 sprintf(hex_ssid + k,"%02x", ssid[j]);
developer72fb0bb2023-01-11 09:46:29 +080016269
developere40952c2023-06-15 18:46:43 +080016270 res = snprintf(hex_bssid, sizeof(hex_bssid),
developera3511852023-06-14 14:12:59 +080016271 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
16272 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 +080016273 if (os_snprintf_error(sizeof(hex_bssid), res)) {
16274 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16275 return RETURN_ERR;
16276 }
16277 res = snprintf(bssid, sizeof(bssid),
developera3511852023-06-14 14:12:59 +080016278 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
16279 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 +080016280 if (os_snprintf_error(sizeof(bssid), res)) {
16281 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16282 return RETURN_ERR;
16283 }
developer72fb0bb2023-01-11 09:46:29 +080016284
developere40952c2023-06-15 18:46:43 +080016285 res = snprintf(nr, sizeof(nr),
developera3511852023-06-14 14:12:59 +080016286 "%s" // bssid
16287 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
16288 "%02hhx" // operclass
16289 "%02hhx" // channel
16290 "%02hhx", // phy_mode
16291 hex_bssid,
16292 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
16293 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
16294 neighborReports[i].opClass,
16295 neighborReports[i].channel,
16296 neighborReports[i].phyTable);
developere40952c2023-06-15 18:46:43 +080016297 if (os_snprintf_error(sizeof(nr), res)) {
16298 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16299 return RETURN_ERR;
16300 }
developer72fb0bb2023-01-11 09:46:29 +080016301
developere40952c2023-06-15 18:46:43 +080016302 res = snprintf(cmd, sizeof(cmd),
developera3511852023-06-14 14:12:59 +080016303 "hostapd_cli set_neighbor "
16304 "%s " // bssid
16305 "ssid=%s " // ssid
16306 "nr=%s " // nr
16307 "-i %s",
16308 bssid,hex_ssid,nr, interface_name);
developere40952c2023-06-15 18:46:43 +080016309 if (os_snprintf_error(sizeof(cmd), res)) {
16310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16311 return RETURN_ERR;
16312 }
developer72fb0bb2023-01-11 09:46:29 +080016313
developera3511852023-06-14 14:12:59 +080016314 if (WEXITSTATUS(system(cmd)) != 0)
16315 {
16316 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
16317 }
16318 }
developer72fb0bb2023-01-11 09:46:29 +080016319
developera3511852023-06-14 14:12:59 +080016320 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016321}
16322
16323INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
16324{
developera3511852023-06-14 14:12:59 +080016325 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016326}
16327
16328#ifdef _WIFI_HAL_TEST_
16329int main(int argc,char **argv)
16330{
developera3511852023-06-14 14:12:59 +080016331 int index;
16332 INT ret=0;
16333 char buf[1024]="";
developer72fb0bb2023-01-11 09:46:29 +080016334
developera3511852023-06-14 14:12:59 +080016335 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16336 if(argc<3)
16337 {
16338 if(argc==2)
16339 {
16340 if(!strcmp(argv[1], "init"))
16341 return wifi_init();
16342 if(!strcmp(argv[1], "reset"))
16343 return wifi_reset();
16344 if(!strcmp(argv[1], "wifi_getHalVersion"))
16345 {
16346 char buffer[64];
16347 if(wifi_getHalVersion(buffer)==RETURN_OK)
16348 printf("Version: %s\n", buffer);
16349 else
16350 printf("Error in wifi_getHalVersion\n");
16351 return RETURN_OK;
16352 }
16353 }
16354 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
16355 exit(-1);
16356 }
developer72fb0bb2023-01-11 09:46:29 +080016357
developera3511852023-06-14 14:12:59 +080016358 index = atoi(argv[2]);
16359 if(strstr(argv[1], "wifi_getApName")!=NULL)
16360 {
16361 wifi_getApName(index,buf);
16362 printf("Ap name is %s \n",buf);
16363 return 0;
16364 }
developerfead3972023-05-25 20:15:02 +080016365 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080016366 {
developerfead3972023-05-25 20:15:02 +080016367 UINT pureMode = atoi(argv[3]);
16368
developera3511852023-06-14 14:12:59 +080016369 wifi_setRadioMode(index, NULL, pureMode);
16370 printf("Ap SET Radio mode 0x%x\n", pureMode);
16371 return 0;
16372 }
16373 if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
16374 unsigned char enable = atoi(argv[3]);
16375 if (enable)
16376 wifi_setRadioAutoBlockAckEnable(index, TRUE);
16377 else
16378 wifi_setRadioAutoBlockAckEnable(index, FALSE);
16379 printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
16380 }
developera39cfb22023-06-20 16:28:17 +080016381 if(strstr(argv[1], "wifi_setRadioTrafficStatsRadioStatisticsEnable")!=NULL)
16382 {
16383 wifi_setRadioTrafficStatsRadioStatisticsEnable(index, TRUE);
16384 printf("Ap SET wifi_setRadioTrafficStatsRadioStatisticsEnable\n");
16385 return 0;
16386 }
16387 if(strstr(argv[1], "wifi_setRadioTrafficStatsMeasure")!=NULL)
16388 {
16389 wifi_radioTrafficStatsMeasure_t input = {30, 200};
16390
16391 wifi_setRadioTrafficStatsMeasure(index, &input);
16392 printf("Ap SET wifi_setRadioTrafficStatsMeasure\n");
16393 return 0;
16394 }
developerfead3972023-05-25 20:15:02 +080016395 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
developera3511852023-06-14 14:12:59 +080016396 {
developerfead3972023-05-25 20:15:02 +080016397 ULONG TransmitPower = atoi(argv[3]);
16398
developera3511852023-06-14 14:12:59 +080016399 wifi_setRadioTransmitPower(index, TransmitPower);
16400 printf("Ap SET TransmitPower %lu\n", TransmitPower);
16401 return 0;
16402 }
developerfead3972023-05-25 20:15:02 +080016403 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
developera3511852023-06-14 14:12:59 +080016404 {
developerfead3972023-05-25 20:15:02 +080016405 INT TransmitPower = atoi(argv[3]);
16406
developera3511852023-06-14 14:12:59 +080016407 wifi_setApManagementFramePowerControl(index, TransmitPower);
16408 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
16409 return 0;
16410 }
developerfead3972023-05-25 20:15:02 +080016411 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
developera3511852023-06-14 14:12:59 +080016412 {
developerfead3972023-05-25 20:15:02 +080016413 CHAR *bandwith = argv[3];
16414
developera3511852023-06-14 14:12:59 +080016415 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
16416 printf("Ap SET bw %s\n", bandwith);
16417 return 0;
16418 }
developerfead3972023-05-25 20:15:02 +080016419 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
developera3511852023-06-14 14:12:59 +080016420 {
16421 wifi_factoryResetRadio(index);
16422 printf("wifi_factoryResetRadio ok!\n");
16423 return 0;
16424 }
developerfead3972023-05-25 20:15:02 +080016425 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
developera3511852023-06-14 14:12:59 +080016426 {
16427 ULONG rst_cnt;
16428 wifi_getRadioResetCount(index, &rst_cnt);
16429 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
16430 return 0;
16431 }
developer2edaf012023-05-24 14:24:53 +080016432 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080016433 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016434 {
16435 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16436 exit(-1);
16437 }
developer49b17232023-05-19 16:35:19 +080016438 wifi_addApAclDevice(index, argv[3]);
16439 return 0;
16440 }
developer2edaf012023-05-24 14:24:53 +080016441 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
16442 wifi_getApAclDevices(index, buf, 1024);
16443 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080016444 return 0;
16445 }
developer2edaf012023-05-24 14:24:53 +080016446 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
16447 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016448 {
16449 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16450 exit(-1);
16451 }
developer2edaf012023-05-24 14:24:53 +080016452 wifi_delApAclDevice(index, argv[3]);
16453 return 0;
16454 }
16455 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
16456 wifi_delApAclDevices(index);
16457 return 0;
16458 }
16459 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
developer863a4a62023-06-06 16:55:59 +080016460 UINT acl_num = 0;
developer2edaf012023-05-24 14:24:53 +080016461 wifi_getApAclDeviceNum(index, &acl_num);
16462 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
16463 return 0;
16464 }
16465 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
16466 wifi_getApDenyAclDevices(index, buf, 1024);
16467 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
16468 return 0;
16469 }
16470 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
16471 int filter_mode = 0;
16472 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016473 {
16474 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16475 exit(-1);
16476 }
developer2edaf012023-05-24 14:24:53 +080016477 filter_mode = atoi(argv[3]);
16478 wifi_setApMacAddressControlMode(index,filter_mode);
16479 return 0;
16480 }
developer5cd4c862023-05-26 09:34:42 +080016481 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
16482 BOOL output_bool = 0;
16483 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
16484 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
16485 return 0;
16486 }
16487 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
16488 BOOL output_bool = 0;
16489 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
16490 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
16491 return 0;
16492 }
16493
16494 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
16495 int filter_mode = 0;
16496 wifi_getApMacAddressControlMode(index, &filter_mode);
16497 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
16498 return 0;
16499 }
16500 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
16501 int enable = 0;
16502 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016503 {
16504 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16505 exit(-1);
16506 }
developer5cd4c862023-05-26 09:34:42 +080016507 enable = (BOOL)atoi(argv[3]);
16508 wifi_setRadioIGMPSnoopingEnable(index, enable);
16509 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
16510 return 0;
16511 }
developer326d4232023-06-15 16:45:30 +080016512 if (strncmp(argv[1], "wifi_setRadioDCSEnable(", strlen(argv[1])) == 0) {
16513 int enable = 0;
16514 if(argc <= 3 )
16515 {
16516 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16517 exit(-1);
16518 }
16519 enable = (BOOL)atoi(argv[3]);
16520 wifi_setRadioDCSEnable(index, enable);
16521 wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
16522 return 0;
16523 }
16524 if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod(", strlen(argv[1])) == 0) {
16525 ULONG period = 0;
developer5cd4c862023-05-26 09:34:42 +080016526
developer326d4232023-06-15 16:45:30 +080016527 wifi_getRadioAutoChannelRefreshPeriod(index, &period);
16528 wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
16529 return 0;
16530 }
16531 if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod(", strlen(argv[1])) == 0) {
16532 ULONG period = 0;
16533
16534 period = (ULONG)atoi(argv[3]);
16535 wifi_setRadioDfsRefreshPeriod(index, period);
16536 wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
16537 return 0;
16538 }
16539 if (strncmp(argv[1], "wifi_setRadioDCSChannelPool(", strlen(argv[1])) == 0) {
16540 char pool[256] = {'\0'};
16541
16542 strcpy(pool, argv[3]);
16543 wifi_setRadioDCSChannelPool(index, pool);
16544 wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
16545 return 0;
16546 }
16547 if (strncmp(argv[1], "wifi_getRadioDCSChannelPool(", strlen(argv[1])) == 0) {
16548 char pool[256] = {'\0'};
16549
16550 wifi_getRadioDCSChannelPool(index, pool);
16551 wifi_debug(DEBUG_NOTICE, "Get DCSChannelPool: %s\n", pool);
16552 return 0;
16553 }
developer5cd4c862023-05-26 09:34:42 +080016554 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
16555 BOOL out_status = 0;
16556 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
16557 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
16558 return 0;
16559 }
developer121a8e72023-05-22 09:19:39 +080016560
developer95c045d2023-05-24 19:26:28 +080016561 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
16562 int enable = 0;
16563 if(argc <= 3)
16564 {
16565 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16566 exit(-1);
16567 }
16568 enable = atoi(argv[3]);
16569 wifi_setApWmmEnable(index,enable);
16570 return 0;
16571 }
developerc1aa6532023-06-09 09:37:01 +080016572 if (strncmp(argv[1], "wifi_pushSsidAdvertisementEnable", strlen(argv[1])) == 0) {
16573 int enable = 0;
16574 if(argc <= 3)
16575 {
16576 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16577 exit(-1);
16578 }
16579 enable = atoi(argv[3]);
16580 wifi_pushSsidAdvertisementEnable(index,enable);
16581 return 0;
16582 }
developer56fbedb2023-05-30 16:47:05 +080016583 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
16584 wifi_down();
16585 return 0;
16586 }
developer95c045d2023-05-24 19:26:28 +080016587
developer56fbedb2023-05-30 16:47:05 +080016588 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
16589 BOOL enable = 0;
16590
16591 wifi_getRadioStatus(index, &enable);
16592 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
16593 return 0;
16594 }
developer333c1eb2023-05-31 14:59:39 +080016595
developer95c045d2023-05-24 19:26:28 +080016596 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
16597 BOOL enable = 0;
16598
16599 wifi_getApWMMCapability(index, &enable);
16600 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
16601 return 0;
16602 }
16603
16604 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
16605 BOOL enable = 0;
16606
16607 wifi_getApWmmEnable(index, &enable);
16608 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
16609 return 0;
16610 }
16611
developer2edaf012023-05-24 14:24:53 +080016612 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
16613 int filter_mode = 0;
16614 wifi_getApMacAddressControlMode(index, &filter_mode);
16615 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
16616 return 0;
16617 }
developer0f10c772023-05-16 21:43:39 +080016618 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080016619 {
developer863a4a62023-06-06 16:55:59 +080016620 UINT mode = 0;
developer0f10c772023-05-16 21:43:39 +080016621
developera3511852023-06-14 14:12:59 +080016622 wifi_getRadioMode(index, buf, &mode);
16623 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
16624 return 0;
16625 }
16626 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
16627 {
16628 BOOL b = FALSE;
16629 BOOL *output_bool = &b;
16630 wifi_getRadioAutoChannelEnable(index,output_bool);
16631 printf("Channel enabled = %d \n",b);
16632 return 0;
16633 }
16634 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
16635 {
16636 wifi_getApWpaEncryptionMode(index,buf);
16637 printf("encryption enabled = %s\n",buf);
16638 return 0;
16639 }
16640 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
16641 {
16642 BOOL b = FALSE;
16643 BOOL *output_bool = &b;
16644 wifi_getApSsidAdvertisementEnable(index,output_bool);
16645 printf("advertisment enabled = %d\n",b);
16646 return 0;
16647 }
16648 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
16649 {
16650 if(argc <= 3 )
16651 {
16652 printf("Insufficient arguments \n");
16653 exit(-1);
16654 }
developer72fb0bb2023-01-11 09:46:29 +080016655
developera3511852023-06-14 14:12:59 +080016656 char sta[20] = {'\0'};
16657 ULLONG handle= 0;
16658 strcpy(sta,argv[3]);
16659 mac_address_t st;
developer72fb0bb2023-01-11 09:46:29 +080016660 mac_addr_aton(st,sta);
16661
developera3511852023-06-14 14:12:59 +080016662 wifi_associated_dev_tid_stats_t tid_stats;
16663 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
16664 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
16665 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);
16666 }
developer72fb0bb2023-01-11 09:46:29 +080016667
developera3511852023-06-14 14:12:59 +080016668 if(strstr(argv[1], "getApEnable")!=NULL) {
16669 BOOL enable;
16670 ret=wifi_getApEnable(index, &enable);
16671 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
16672 }
16673 else if(strstr(argv[1], "setApEnable")!=NULL) {
16674 BOOL enable = atoi(argv[3]);
16675 ret=wifi_setApEnable(index, enable);
16676 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
16677 }
16678 else if(strstr(argv[1], "getApStatus")!=NULL) {
16679 char status[64];
16680 ret=wifi_getApStatus(index, status);
16681 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
16682 }
16683 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
16684 {
16685 wifi_getSSIDNameStatus(index,buf);
16686 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
16687 return 0;
16688 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
16689 wifi_resetApVlanCfg(index);
16690 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
16691 return 0;
16692 }
16693 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
16694 wifi_ssidTrafficStats2_t stats={0};
16695 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
16696 printf("%s %d: returns %d\n", argv[1], index, ret);
16697 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
16698 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
16699 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
16700 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
16701 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
16702 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
16703 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
16704 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
16705 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
16706 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
16707 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
16708 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
16709 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
16710 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
16711 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
16712 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
16713 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
16714 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
16715 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
16716 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
16717 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
16718 }
16719 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
16720 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
16721 UINT array_size=0;
16722 UINT i=0;
16723 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
16724 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
16725 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
16726 printf(" neighbor %d:\n", i);
16727 printf(" ap_SSID =%s\n", pt->ap_SSID);
16728 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
16729 printf(" ap_Mode =%s\n", pt->ap_Mode);
16730 printf(" ap_Channel =%d\n", pt->ap_Channel);
16731 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
16732 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
16733 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
16734 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
16735 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
16736 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
16737 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
16738 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
16739 printf(" ap_Noise =%d\n", pt->ap_Noise);
16740 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
16741 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
16742 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
16743 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
16744 }
16745 if(neighbor_ap_array)
16746 free(neighbor_ap_array); //make sure to free the list
16747 }
16748 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
16749 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
16750 UINT array_size=0;
16751 UINT i=0;
16752 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
16753 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
16754 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
16755 printf(" associated_dev %d:\n", i);
16756 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
16757 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
16758 printf(" cli_SNR =%d\n", pt->cli_SNR);
16759 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
16760 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
16761 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
16762 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
16763 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
16764 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
16765 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
16766 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
16767 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
16768 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
16769 }
16770 if(associated_dev_array)
16771 free(associated_dev_array); //make sure to free the list
16772 }
developer72fb0bb2023-01-11 09:46:29 +080016773
developera3511852023-06-14 14:12:59 +080016774 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
16775 {
developer72fb0bb2023-01-11 09:46:29 +080016776#define MAX_ARRAY_SIZE 64
developera3511852023-06-14 14:12:59 +080016777 int i, array_size;
16778 char *p, *ch_str;
16779 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
developer72fb0bb2023-01-11 09:46:29 +080016780
developera3511852023-06-14 14:12:59 +080016781 if(argc != 5)
16782 {
16783 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
16784 exit(-1);
16785 }
16786 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
developer72fb0bb2023-01-11 09:46:29 +080016787
developera3511852023-06-14 14:12:59 +080016788 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
16789 {
16790 strtok_r(ch_str, ",", &p);
16791 input_output_channelStats_array[i].ch_number = atoi(ch_str);
16792 }
16793 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
16794 if(!array_size)
16795 array_size=1;//Need to print current channel statistics
16796 for(i=0; i<array_size; i++)
16797 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
16798 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
16799 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
16800 input_output_channelStats_array[i].ch_number,\
16801 input_output_channelStats_array[i].ch_noise,\
16802 input_output_channelStats_array[i].ch_utilization_busy_rx,\
16803 input_output_channelStats_array[i].ch_utilization_busy_tx,\
16804 input_output_channelStats_array[i].ch_utilization_busy,\
16805 input_output_channelStats_array[i].ch_utilization_busy_ext,\
16806 input_output_channelStats_array[i].ch_utilization_total);
16807 }
developer72fb0bb2023-01-11 09:46:29 +080016808
developera3511852023-06-14 14:12:59 +080016809 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
16810 {
16811 if(argc <= 3 )
16812 {
16813 printf("Insufficient arguments \n");
16814 exit(-1);
16815 }
16816 char mac_addr[20] = {'\0'};
16817 wifi_device_t output_struct;
16818 int dev_index = atoi(argv[3]);
developer72fb0bb2023-01-11 09:46:29 +080016819
developera3511852023-06-14 14:12:59 +080016820 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
16821 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
16822 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);
16823 }
developer72fb0bb2023-01-11 09:46:29 +080016824
developera3511852023-06-14 14:12:59 +080016825 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
16826 {
16827 if (argc <= 3)
16828 {
16829 printf("Insufficient arguments\n");
16830 exit(-1);
16831 }
16832 char args[256];
16833 wifi_NeighborReport_t *neighborReports;
developer72fb0bb2023-01-11 09:46:29 +080016834
developera3511852023-06-14 14:12:59 +080016835 neighborReports = calloc(argc - 2, sizeof(neighborReports));
16836 if (!neighborReports)
16837 {
16838 printf("Failed to allocate memory");
16839 exit(-1);
16840 }
developer72fb0bb2023-01-11 09:46:29 +080016841
developera3511852023-06-14 14:12:59 +080016842 for (int i = 3; i < argc; ++i)
16843 {
16844 char *val;
16845 int j = 0;
16846 memset(args, 0, sizeof(args));
16847 strncpy(args, argv[i], sizeof(args));
16848 val = strtok(args, ";");
16849 while (val != NULL)
16850 {
16851 if (j == 0)
16852 {
16853 mac_addr_aton(neighborReports[i - 3].bssid, val);
16854 } else if (j == 1)
16855 {
16856 neighborReports[i - 3].info = strtol(val, NULL, 16);
16857 } else if (j == 2)
16858 {
16859 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
16860 } else if (j == 3)
16861 {
16862 neighborReports[i - 3].channel = strtol(val, NULL, 16);
16863 } else if (j == 4)
16864 {
16865 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
16866 } else {
16867 printf("Insufficient arguments]n\n");
16868 exit(-1);
16869 }
16870 val = strtok(NULL, ";");
16871 j++;
16872 }
16873 }
developer72fb0bb2023-01-11 09:46:29 +080016874
developera3511852023-06-14 14:12:59 +080016875 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
16876 if (ret != RETURN_OK)
16877 {
16878 printf("wifi_setNeighborReports ret = %d", ret);
16879 exit(-1);
16880 }
16881 }
16882 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
16883 {
16884 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
16885 printf("%s.\n", buf);
16886 else
16887 printf("Error returned\n");
16888 }
16889 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
16890 {
16891 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
16892 printf("%s.\n", buf);
16893 else
16894 printf("Error returned\n");
16895 }
16896 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
16897 {
16898 if (argc <= 2)
16899 {
16900 printf("Insufficient arguments\n");
16901 exit(-1);
16902 }
16903 char buf[64]= {'\0'};
16904 wifi_getRadioOperatingChannelBandwidth(index,buf);
16905 printf("Current bandwidth is %s \n",buf);
16906 return 0;
16907 }
16908 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
16909 {
16910 if (argc <= 5)
16911 {
16912 printf("Insufficient arguments\n");
16913 exit(-1);
16914 }
16915 UINT channel = atoi(argv[3]);
16916 UINT width = atoi(argv[4]);
16917 UINT beacon = atoi(argv[5]);
16918 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
16919 printf("Result = %d", ret);
16920 }
developercc5cbfb2023-06-13 18:29:52 +080016921 if(strstr(argv[1],"wifi_getApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080016922 {
developercc5cbfb2023-06-13 18:29:52 +080016923 char br_name[64], ip[64], subset[64] = {0};
16924 wifi_getApBridgeInfo(0, br_name, ip, subset);
16925 printf("wifi_getApBridgeInfo br_name = %s, ip = %s, subset = %s\n", br_name, ip, subset);
developera3511852023-06-14 14:12:59 +080016926 }
developercc5cbfb2023-06-13 18:29:52 +080016927 if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
developera3511852023-06-14 14:12:59 +080016928 {
developercc5cbfb2023-06-13 18:29:52 +080016929 int enable = atoi(argv[3]);
16930 wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
16931 printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
developera3511852023-06-14 14:12:59 +080016932 }
developercc5cbfb2023-06-13 18:29:52 +080016933 if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080016934 {
developercc5cbfb2023-06-13 18:29:52 +080016935 wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
16936 printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
developera3511852023-06-14 14:12:59 +080016937 }
developer72fb0bb2023-01-11 09:46:29 +080016938
developer6e578302023-06-21 10:11:16 +080016939 if(strstr(argv[1], "wifi_getATMCapable")!=NULL)
16940 {
16941 BOOL b = FALSE;
16942 BOOL *output_bool = &b;
16943 wifi_getATMCapable(output_bool);
16944 printf("ATM capable = %d \n",b);
16945 return 0;
16946 }
16947 if (strncmp(argv[1], "wifi_setATMEnable", strlen(argv[1])) == 0) {
16948 int enable = 0;
16949 if(argc <= 3)
16950 {
16951 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16952 exit(-1);
16953 }
16954 enable = atoi(argv[3]);
16955 wifi_setATMEnable(enable);
16956 return 0;
16957 }
16958 if (strncmp(argv[1], "wifi_getATMEnable", strlen(argv[1])) == 0) {
16959 BOOL b = FALSE;
16960 BOOL *output_bool = &b;
16961 wifi_getATMEnable(output_bool);
16962 printf("ATM enable = %d \n", b);
16963 return 0;
16964 }
16965 if (strncmp(argv[1], "wifi_setApATMAirTimePercent", strlen(argv[1])) == 0) {
16966 unsigned int percent = 0;
16967 if(argc <= 3)
16968 {
16969 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16970 exit(-1);
16971 }
16972 percent = atoi(argv[3]);
16973 wifi_setApATMAirTimePercent(index, percent);
16974 return 0;
16975 }
16976 if (strncmp(argv[1], "wifi_getApATMAirTimePercent", strlen(argv[1])) == 0) {
16977 unsigned int percent = 0;
16978 unsigned int *output = &percent;
16979
16980 wifi_getApATMAirTimePercent(index, output);
16981 printf("ATM percent = %d \n", percent);
16982 return 0;
16983 }
developer82533be2023-06-28 17:21:01 +080016984 if (strstr(argv[1],"setGF")!=NULL)
16985 {
16986 BOOL enable = atoi(argv[3]);
16987 if((ret=wifi_setRadio11nGreenfieldEnable(index, enable))==RETURN_OK)
16988 printf("wifi_setRadio11nGreenfieldEnable success\n");
16989 else
16990 printf("wifi_setRadio11nGreenfieldEnable Error\n");
16991 }
16992 if (strstr(argv[1],"setVID")!=NULL)
16993 {
16994 INT vid = atoi(argv[3]);
16995 if((ret=wifi_setApVlanID(index, vid))==RETURN_OK)
16996 printf("wifi_setApVlanID success.\n");
16997 else
16998 printf("wifi_setApVlanID Error\n");
16999 }
developera3511852023-06-14 14:12:59 +080017000 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17001 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017002}
17003
17004#endif
17005
17006#ifdef WIFI_HAL_VERSION_3
17007
developer32f2a182023-06-27 19:50:41 +080017008INT BitMapToTransmitRates(UINT bitMap, char *BasicRate, unsigned long size)
developer72fb0bb2023-01-11 09:46:29 +080017009{
developera3511852023-06-14 14:12:59 +080017010 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer32f2a182023-06-27 19:50:41 +080017011 if (bitMap & WIFI_BITRATE_1MBPS) {
17012 if ((size - strlen(BasicRate)) <= 2)
17013 return RETURN_ERR;
17014 strncat(BasicRate, "1,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17015 }
17016 if (bitMap & WIFI_BITRATE_2MBPS) {
17017 if ((size - strlen(BasicRate)) <= 2)
17018 return RETURN_ERR;
17019 strncat(BasicRate, "2,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17020 }
17021 if (bitMap & WIFI_BITRATE_5_5MBPS) {
17022 if ((size - strlen(BasicRate)) <= 4)
17023 return RETURN_ERR;
17024 strncat(BasicRate, "5.5,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17025 }
17026 if (bitMap & WIFI_BITRATE_6MBPS) {
17027 if ((size - strlen(BasicRate)) <= 2)
17028 return RETURN_ERR;
17029 strncat(BasicRate, "6,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17030 }
17031 if (bitMap & WIFI_BITRATE_9MBPS) {
17032 if ((size - strlen(BasicRate)) <= 2)
17033 return RETURN_ERR;
17034 strncat(BasicRate, "9,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17035 }
17036 if (bitMap & WIFI_BITRATE_11MBPS) {
17037 if ((size - strlen(BasicRate)) <= 3)
17038 return RETURN_ERR;
17039 strncat(BasicRate, "11,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17040 }
17041 if (bitMap & WIFI_BITRATE_12MBPS) {
17042 if ((size - strlen(BasicRate)) <= 3)
17043 return RETURN_ERR;
17044 strncat(BasicRate, "12,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17045 }
17046 if (bitMap & WIFI_BITRATE_18MBPS) {
17047 if ((size - strlen(BasicRate)) <= 3)
17048 return RETURN_ERR;
17049 strncat(BasicRate, "18,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17050 }
17051 if (bitMap & WIFI_BITRATE_24MBPS) {
17052 if ((size - strlen(BasicRate)) <= 3)
17053 return RETURN_ERR;
17054 strncat(BasicRate, "24,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17055 }
17056 if (bitMap & WIFI_BITRATE_36MBPS) {
17057 if ((size - strlen(BasicRate)) <= 3)
17058 return RETURN_ERR;
17059 strncat(BasicRate, "36,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17060 }
17061 if (bitMap & WIFI_BITRATE_48MBPS) {
17062 if ((size - strlen(BasicRate)) <= 3)
17063 return RETURN_ERR;
17064 strncat(BasicRate, "48,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17065 }
17066 if (bitMap & WIFI_BITRATE_54MBPS) {
17067 if ((size - strlen(BasicRate)) <= 3)
17068 return RETURN_ERR;
17069 strncat(BasicRate, "54,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17070 }
developera3511852023-06-14 14:12:59 +080017071 if (strlen(BasicRate) != 0) // remove last comma
17072 BasicRate[strlen(BasicRate) - 1] = '\0';
17073 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017075}
17076
17077INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
17078{
developera3511852023-06-14 14:12:59 +080017079 UINT BitMap = 0;
17080 char *rate;
developer72fb0bb2023-01-11 09:46:29 +080017081
developera3511852023-06-14 14:12:59 +080017082 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17083 rate = strtok(BasicRatesList, ",");
17084 while(rate != NULL)
17085 {
17086 if (strcmp(rate, "1") == 0)
17087 BitMap |= WIFI_BITRATE_1MBPS;
17088 else if (strcmp(rate, "2") == 0)
17089 BitMap |= WIFI_BITRATE_2MBPS;
17090 else if (strcmp(rate, "5.5") == 0)
17091 BitMap |= WIFI_BITRATE_5_5MBPS;
17092 else if (strcmp(rate, "6") == 0)
17093 BitMap |= WIFI_BITRATE_6MBPS;
17094 else if (strcmp(rate, "9") == 0)
17095 BitMap |= WIFI_BITRATE_9MBPS;
17096 else if (strcmp(rate, "11") == 0)
17097 BitMap |= WIFI_BITRATE_11MBPS;
17098 else if (strcmp(rate, "12") == 0)
17099 BitMap |= WIFI_BITRATE_12MBPS;
17100 else if (strcmp(rate, "18") == 0)
17101 BitMap |= WIFI_BITRATE_18MBPS;
17102 else if (strcmp(rate, "24") == 0)
17103 BitMap |= WIFI_BITRATE_24MBPS;
17104 else if (strcmp(rate, "36") == 0)
17105 BitMap |= WIFI_BITRATE_36MBPS;
17106 else if (strcmp(rate, "48") == 0)
17107 BitMap |= WIFI_BITRATE_48MBPS;
17108 else if (strcmp(rate, "54") == 0)
17109 BitMap |= WIFI_BITRATE_54MBPS;
17110 rate = strtok(NULL, ",");
17111 }
17112 *basicRateBitMap = BitMap;
17113 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17114 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017115}
17116
17117// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
17118INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
17119{
developera3511852023-06-14 14:12:59 +080017120 char buf[128] = {0};
17121 int bandwidth = 20;
17122 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080017123 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developera3511852023-06-14 14:12:59 +080017124 wifi_radio_operationParam_t current_param;
developer72fb0bb2023-01-11 09:46:29 +080017125
developera3511852023-06-14 14:12:59 +080017126 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017127
developera3511852023-06-14 14:12:59 +080017128 multiple_set = TRUE;
17129 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017130 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingParameters return error.\n");
developera3511852023-06-14 14:12:59 +080017131 return RETURN_ERR;
17132 }
17133 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
17134 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017135 wifi_debug(DEBUG_ERROR, "wifi_setRadioAutoChannelEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017136 return RETURN_ERR;
17137 }
17138 drv_dat_change = TRUE;
17139 }
17140 if (current_param.channelWidth != operationParam->channelWidth ||
17141 current_param.channel != operationParam->channel ||
17142 current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
17143 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
17144 bandwidth = 20;
17145 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
17146 bandwidth = 40;
17147 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
17148 bandwidth = 80;
17149 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
17150 bandwidth = 160;
developer72fb0bb2023-01-11 09:46:29 +080017151
developera3511852023-06-14 14:12:59 +080017152 if (operationParam->autoChannelEnabled) {
17153 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017154 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developera3511852023-06-14 14:12:59 +080017155 return RETURN_ERR;
17156 }
17157 } else {
17158 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017159 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developera3511852023-06-14 14:12:59 +080017160 return RETURN_ERR;
17161 }
17162 }
developer56fbedb2023-05-30 16:47:05 +080017163 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017164 }
17165 if (current_param.variant != operationParam->variant) {
17166 // Two different definition bit map, so need to check every bit.
17167 if (operationParam->variant & WIFI_80211_VARIANT_A)
17168 set_mode |= WIFI_MODE_A;
17169 if (operationParam->variant & WIFI_80211_VARIANT_B)
17170 set_mode |= WIFI_MODE_B;
17171 if (operationParam->variant & WIFI_80211_VARIANT_G)
17172 set_mode |= WIFI_MODE_G;
17173 if (operationParam->variant & WIFI_80211_VARIANT_N)
17174 set_mode |= WIFI_MODE_N;
17175 if (operationParam->variant & WIFI_80211_VARIANT_AC)
17176 set_mode |= WIFI_MODE_AC;
17177 if (operationParam->variant & WIFI_80211_VARIANT_AX)
17178 set_mode |= WIFI_MODE_AX;
17179 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
17180 memset(buf, 0, sizeof(buf));
17181 drv_dat_change = TRUE;
17182 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017183 wifi_debug(DEBUG_ERROR, "wifi_setRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080017184 return RETURN_ERR;
17185 }
17186 }
17187 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer56fbedb2023-05-30 16:47:05 +080017188 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017189 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017190 wifi_debug(DEBUG_ERROR, "wifi_setApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017191 return RETURN_ERR;
17192 }
17193 }
17194 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer56fbedb2023-05-30 16:47:05 +080017195 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017196 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017197 wifi_debug(DEBUG_ERROR, "wifi_setRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080017198 return RETURN_ERR;
17199 }
17200 }
17201 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer56fbedb2023-05-30 16:47:05 +080017202 hapd_conf_change = TRUE;
developer32f2a182023-06-27 19:50:41 +080017203 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080017204 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017205 wifi_debug(DEBUG_ERROR, "wifi_setRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017206 return RETURN_ERR;
17207 }
17208 }
17209 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer56fbedb2023-05-30 16:47:05 +080017210 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017211 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017212 wifi_debug(DEBUG_ERROR, "wifi_setRadioFragmentationThreshold return error.\n");
developera3511852023-06-14 14:12:59 +080017213 return RETURN_ERR;
17214 }
17215 }
17216 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080017217 hapd_conf_change = TRUE;
17218 drv_dat_change = TRUE;
17219 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017220 wifi_debug(DEBUG_ERROR, "wifi_setGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017221 return RETURN_ERR;
17222 }
17223 }
17224 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080017225 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017226 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017227 wifi_debug(DEBUG_ERROR, "wifi_setRadioTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080017228 return RETURN_ERR;
17229 }
17230 }
17231 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
developer56fbedb2023-05-30 16:47:05 +080017232 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017233 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017234 wifi_debug(DEBUG_ERROR, "wifi_setApRtsThreshold return error.\n");
developera3511852023-06-14 14:12:59 +080017235 return RETURN_ERR;
17236 }
17237 }
17238 if (current_param.obssCoex != operationParam->obssCoex) {
developer56fbedb2023-05-30 16:47:05 +080017239 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017240 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017241 wifi_debug(DEBUG_ERROR, "wifi_setRadioObssCoexistenceEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017242 return RETURN_ERR;
17243 }
17244 }
17245 if (current_param.stbcEnable != operationParam->stbcEnable) {
developer56fbedb2023-05-30 16:47:05 +080017246 hapd_conf_change = TRUE;
17247 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017248 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017249 wifi_debug(DEBUG_ERROR, "wifi_setRadioSTBCEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017250 return RETURN_ERR;
17251 }
17252 }
17253 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
17254 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017255 wifi_debug(DEBUG_ERROR, "wifi_setRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017256 return RETURN_ERR;
17257 }
17258 }
developer72fb0bb2023-01-11 09:46:29 +080017259
developera3511852023-06-14 14:12:59 +080017260 /* only down/up interface when dat file has been changed,
17261 * if enable is true, then restart the radio.
17262 */
17263 if (drv_dat_change == TRUE) {
17264 wifi_setRadioEnable(index, FALSE);
developer56fbedb2023-05-30 16:47:05 +080017265 if (operationParam->enable == TRUE)
developera3511852023-06-14 14:12:59 +080017266 wifi_setRadioEnable(index, TRUE);
17267 } else if (hapd_conf_change == TRUE) {
17268 hostapd_raw_remove_bss(index);
17269 if (operationParam->enable == TRUE)
17270 hostapd_raw_add_bss(index);
17271 }
developer56fbedb2023-05-30 16:47:05 +080017272
developera3511852023-06-14 14:12:59 +080017273 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017274
developera3511852023-06-14 14:12:59 +080017275 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017276}
17277
17278INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
17279{
developera3511852023-06-14 14:12:59 +080017280 char band[64] = {0};
17281 char buf[256] = {0};
17282 char config_file[64] = {0};
17283 char cmd[128] = {0};
17284 UINT mode = 0;
17285 BOOL enabled = FALSE;
developer863a4a62023-06-06 16:55:59 +080017286 int dtimPeriod;
developer2f79c922023-06-02 17:33:42 +080017287 UINT beaconInterval;
17288 UINT basicDataTransmitRates;
17289 UINT operationalDataTransmitRates;
17290 wifi_guard_interval_t guardInterval;
17291 UINT transmitPower;
developere40952c2023-06-15 18:46:43 +080017292 int res;
developer72fb0bb2023-01-11 09:46:29 +080017293
developera3511852023-06-14 14:12:59 +080017294 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17295 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080017296
developera3511852023-06-14 14:12:59 +080017297 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
developere40952c2023-06-15 18:46:43 +080017298 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
17299 if (os_snprintf_error(sizeof(config_file), res)) {
17300 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17301 return RETURN_ERR;
17302 }
developera3511852023-06-14 14:12:59 +080017303 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
17304 {
developer75bd10c2023-06-27 11:34:08 +080017305 wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017306 return RETURN_ERR;
17307 }
17308 operationParam->enable = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017309
developera3511852023-06-14 14:12:59 +080017310 memset(band, 0, sizeof(band));
17311 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
17312 {
developer75bd10c2023-06-27 11:34:08 +080017313 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingFrequencyBand return error.\n");
developera3511852023-06-14 14:12:59 +080017314 return RETURN_ERR;
17315 }
developer72fb0bb2023-01-11 09:46:29 +080017316
developera3511852023-06-14 14:12:59 +080017317 if (!strcmp(band, "2.4GHz"))
17318 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
17319 else if (!strcmp(band, "5GHz"))
17320 operationParam->band = WIFI_FREQUENCY_5_BAND;
17321 else if (!strcmp(band, "6GHz"))
17322 operationParam->band = WIFI_FREQUENCY_6_BAND;
17323 else
17324 {
developer75bd10c2023-06-27 11:34:08 +080017325 wifi_debug(DEBUG_ERROR, "cannot decode band for radio index %d ('%s')\n", index, band);
developera3511852023-06-14 14:12:59 +080017326 }
developer72fb0bb2023-01-11 09:46:29 +080017327
developera3511852023-06-14 14:12:59 +080017328 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
17329 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
17330 operationParam->channel = 0;
17331 operationParam->autoChannelEnabled = TRUE;
17332 } else {
17333 operationParam->channel = strtol(buf, NULL, 10);
17334 operationParam->autoChannelEnabled = FALSE;
17335 }
developer72fb0bb2023-01-11 09:46:29 +080017336
developera3511852023-06-14 14:12:59 +080017337 memset(buf, 0, sizeof(buf));
17338 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017339 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
developera3511852023-06-14 14:12:59 +080017340 return RETURN_ERR;
17341 }
17342 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
17343 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
17344 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
17345 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
17346 else
17347 {
developer75bd10c2023-06-27 11:34:08 +080017348 wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", buf);
developera3511852023-06-14 14:12:59 +080017349 return false;
17350 }
developer72fb0bb2023-01-11 09:46:29 +080017351
developera3511852023-06-14 14:12:59 +080017352 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017353 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080017354 return RETURN_ERR;
17355 }
17356 // Two different definition bit map, so need to check every bit.
17357 if (mode & WIFI_MODE_A)
17358 operationParam->variant |= WIFI_80211_VARIANT_A;
17359 if (mode & WIFI_MODE_B)
17360 operationParam->variant |= WIFI_80211_VARIANT_B;
17361 if (mode & WIFI_MODE_G)
17362 operationParam->variant |= WIFI_80211_VARIANT_G;
17363 if (mode & WIFI_MODE_N)
17364 operationParam->variant |= WIFI_80211_VARIANT_N;
17365 if (mode & WIFI_MODE_AC)
17366 operationParam->variant |= WIFI_80211_VARIANT_AC;
17367 if (mode & WIFI_MODE_AX)
17368 operationParam->variant |= WIFI_80211_VARIANT_AX;
17369 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017370 wifi_debug(DEBUG_ERROR, "wifi_getRadioDCSEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017371 return RETURN_ERR;
17372 }
17373 if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017374 wifi_debug(DEBUG_ERROR, "wifi_getApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017375 return RETURN_ERR;
17376 }
developer2f79c922023-06-02 17:33:42 +080017377 operationParam->dtimPeriod = dtimPeriod;
developera3511852023-06-14 14:12:59 +080017378 if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017379 wifi_debug(DEBUG_ERROR, "wifi_getRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080017380 return RETURN_ERR;
17381 }
developer2f79c922023-06-02 17:33:42 +080017382 operationParam->beaconInterval = beaconInterval;
developer72fb0bb2023-01-11 09:46:29 +080017383
developera3511852023-06-14 14:12:59 +080017384 memset(buf, 0, sizeof(buf));
17385 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017386 wifi_debug(DEBUG_ERROR, "wifi_getRadioSupportedDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017387 return RETURN_ERR;
17388 }
17389 TransmitRatesToBitMap(buf, &basicDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080017390 operationParam->basicDataTransmitRates = basicDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080017391
developera3511852023-06-14 14:12:59 +080017392 memset(buf, 0, sizeof(buf));
17393 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017394 wifi_debug(DEBUG_ERROR, "wifi_getRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017395 return RETURN_ERR;
17396 }
17397 TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080017398 operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080017399
developera3511852023-06-14 14:12:59 +080017400 memset(buf, 0, sizeof(buf));
17401 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
17402 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080017403
developera3511852023-06-14 14:12:59 +080017404 if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017405 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017406 return RETURN_ERR;
17407 }
developer2f79c922023-06-02 17:33:42 +080017408 operationParam->guardInterval = guardInterval;
17409
developera3511852023-06-14 14:12:59 +080017410 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017411 wifi_debug(DEBUG_ERROR, "wifi_getRadioPercentageTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080017412 return RETURN_ERR;
17413 }
developer2f79c922023-06-02 17:33:42 +080017414 operationParam->transmitPower = transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080017415
developera3511852023-06-14 14:12:59 +080017416 memset(buf, 0, sizeof(buf));
17417 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
17418 if (strcmp(buf, "-1") == 0) {
17419 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
17420 operationParam->ctsProtection = FALSE;
17421 } else {
17422 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
17423 operationParam->ctsProtection = TRUE;
17424 }
developer72fb0bb2023-01-11 09:46:29 +080017425
developera3511852023-06-14 14:12:59 +080017426 memset(buf, 0, sizeof(buf));
17427 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
17428 if (strcmp(buf, "0") == 0)
17429 operationParam->obssCoex = FALSE;
17430 else
17431 operationParam->obssCoex = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080017432
developere40952c2023-06-15 18:46:43 +080017433 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
17434 if (os_snprintf_error(sizeof(cmd), res)) {
17435 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17436 return RETURN_ERR;
17437 }
developera3511852023-06-14 14:12:59 +080017438 _syscmd(cmd, buf, sizeof(buf));
17439 if (strlen(buf) != 0)
17440 operationParam->stbcEnable = TRUE;
17441 else
17442 operationParam->stbcEnable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080017443
developera3511852023-06-14 14:12:59 +080017444 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017445 wifi_debug(DEBUG_ERROR, "wifi_getRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017446 return RETURN_ERR;
17447 }
developer72fb0bb2023-01-11 09:46:29 +080017448
developera3511852023-06-14 14:12:59 +080017449 // Below value is hardcoded
developer72fb0bb2023-01-11 09:46:29 +080017450
developera3511852023-06-14 14:12:59 +080017451 operationParam->numSecondaryChannels = 0;
17452 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
17453 operationParam->channelSecondary[i] = 0;
17454 }
17455 operationParam->csa_beacon_count = 15;
17456 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
developer72fb0bb2023-01-11 09:46:29 +080017457
developera3511852023-06-14 14:12:59 +080017458 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17459 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017460}
17461
17462static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
17463{
developera3511852023-06-14 14:12:59 +080017464 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +080017465
developera3511852023-06-14 14:12:59 +080017466 wifi_getMaxRadioNumber(&max_radio_num);
17467 if (radioIndex >= max_radio_num) {
developer75bd10c2023-06-27 11:34:08 +080017468 wifi_debug(DEBUG_ERROR, "Wrong radio index (%d)\n", radioIndex);
developera3511852023-06-14 14:12:59 +080017469 return RETURN_ERR;
17470 }
developer72fb0bb2023-01-11 09:46:29 +080017471
developera3511852023-06-14 14:12:59 +080017472 return (arrayIndex * max_radio_num) + radioIndex;
developer72fb0bb2023-01-11 09:46:29 +080017473}
17474
developer96b38512023-02-22 11:17:45 +080017475static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
17476{
developera3511852023-06-14 14:12:59 +080017477 int max_radio_num = 0;
developer96b38512023-02-22 11:17:45 +080017478
developera3511852023-06-14 14:12:59 +080017479 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
developer96b38512023-02-22 11:17:45 +080017480 return -1;
17481
developera3511852023-06-14 14:12:59 +080017482 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080017483 if(max_radio_num == 0){
17484 return RETURN_ERR;
17485 }
developera3511852023-06-14 14:12:59 +080017486 (*radioIndex) = vapIndex % max_radio_num;
17487 (*arrayIndex) = vapIndex / max_radio_num;
developer96b38512023-02-22 11:17:45 +080017488
developera3511852023-06-14 14:12:59 +080017489 return 0;
developer96b38512023-02-22 11:17:45 +080017490}
17491
17492
developer72fb0bb2023-01-11 09:46:29 +080017493wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
developera3511852023-06-14 14:12:59 +080017494 if (strncmp(beaconRate, "1Mbps", 5) == 0)
17495 return WIFI_BITRATE_1MBPS;
17496 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
17497 return WIFI_BITRATE_2MBPS;
17498 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
17499 return WIFI_BITRATE_5_5MBPS;
17500 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
17501 return WIFI_BITRATE_6MBPS;
17502 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
17503 return WIFI_BITRATE_9MBPS;
17504 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
17505 return WIFI_BITRATE_11MBPS;
17506 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
17507 return WIFI_BITRATE_12MBPS;
17508 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
17509 return WIFI_BITRATE_18MBPS;
17510 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
17511 return WIFI_BITRATE_24MBPS;
17512 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
17513 return WIFI_BITRATE_36MBPS;
17514 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
17515 return WIFI_BITRATE_48MBPS;
17516 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
17517 return WIFI_BITRATE_54MBPS;
17518 return WIFI_BITRATE_DEFAULT;
developer72fb0bb2023-01-11 09:46:29 +080017519}
17520
developer32f2a182023-06-27 19:50:41 +080017521struct beacon_rate_2_string {
17522 wifi_bitrate_t beacon;
17523 char beacon_str[8];
17524};
17525
17526struct beacon_rate_2_string br2str[12] = {
17527 {WIFI_BITRATE_1MBPS, "1Mbps"},
17528 {WIFI_BITRATE_2MBPS, "2Mbps"},
17529 {WIFI_BITRATE_5_5MBPS, "5.5Mbps"},
17530 {WIFI_BITRATE_6MBPS, "6Mbps"},
17531 {WIFI_BITRATE_9MBPS, "9Mbps"},
17532 {WIFI_BITRATE_11MBPS, "11Mbps"},
17533 {WIFI_BITRATE_12MBPS, "12Mbps"},
17534 {WIFI_BITRATE_18MBPS, "18Mbps"},
17535 {WIFI_BITRATE_24MBPS, "24Mbps"},
17536 {WIFI_BITRATE_36MBPS, "36Mbps"},
17537 {WIFI_BITRATE_48MBPS, "48Mbps"},
17538 {WIFI_BITRATE_54MBPS, "54Mbps"}
17539};
17540
17541INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str, unsigned long str_size)
developer72fb0bb2023-01-11 09:46:29 +080017542{
developer32f2a182023-06-27 19:50:41 +080017543 int i;
17544 unsigned long len;
17545
17546 for (i = 0; i < (sizeof(br2str)/sizeof(br2str[0])); i++) {
17547 if (beacon == br2str[i].beacon) {
17548 len = strlen(br2str[i].beacon_str);
17549 if (len >= str_size)
17550 return RETURN_ERR;
17551 memcpy(beacon_str, br2str[i].beacon_str, len);
17552 beacon_str[len] = '\0';
17553 break;
17554 }
17555 }
developera3511852023-06-14 14:12:59 +080017556 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017557}
17558
17559INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
17560{
developera3511852023-06-14 14:12:59 +080017561 INT mode = 0;
17562 INT ret = -1;
17563 UINT output = 0;
17564 int i = 0;
17565 int vap_index = 0;
17566 BOOL enabled = FALSE;
17567 char buf[32] = {0};
17568 wifi_vap_security_t security = {0};
developere40952c2023-06-15 18:46:43 +080017569 int res;
developer72fb0bb2023-01-11 09:46:29 +080017570
developera3511852023-06-14 14:12:59 +080017571 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17572 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080017573
developera3511852023-06-14 14:12:59 +080017574 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
17575 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +080017576 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
developera3511852023-06-14 14:12:59 +080017577 return RETURN_ERR;
17578 }
developerfde01262023-05-22 15:15:24 +080017579
developera3511852023-06-14 14:12:59 +080017580 map->num_vaps = atoi(buf);
17581 if (map->num_vaps <= 0) {
developer75bd10c2023-06-27 11:34:08 +080017582 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
developera3511852023-06-14 14:12:59 +080017583 return RETURN_ERR;
17584 }
developerfde01262023-05-22 15:15:24 +080017585
developera3511852023-06-14 14:12:59 +080017586 for (i = 0; i < map->num_vaps; i++)
17587 {
17588 map->vap_array[i].radio_index = index;
developer72fb0bb2023-01-11 09:46:29 +080017589
developera3511852023-06-14 14:12:59 +080017590 vap_index = array_index_to_vap_index(index, i);
17591 if (vap_index < 0)
17592 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080017593
developer9ce44382023-06-28 11:09:37 +080017594 strncpy(map->vap_array[i].bridge_name, BRIDGE_NAME,sizeof(map->vap_array[i].bridge_name) - 1);
17595 map->vap_array[i].bridge_name[sizeof(map->vap_array[i].bridge_name) - 1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080017596
developera3511852023-06-14 14:12:59 +080017597 map->vap_array[i].vap_index = vap_index;
developer72fb0bb2023-01-11 09:46:29 +080017598
developera3511852023-06-14 14:12:59 +080017599 memset(buf, 0, sizeof(buf));
17600 ret = wifi_getApName(vap_index, buf);
17601 if (ret != RETURN_OK) {
17602 printf("%s: wifi_getApName return error\n", __func__);
17603 return RETURN_ERR;
17604 }
developere40952c2023-06-15 18:46:43 +080017605 res = snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
17606 if (os_snprintf_error(sizeof(map->vap_array[i].vap_name), res)) {
17607 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17608 return RETURN_ERR;
17609 }
developer72fb0bb2023-01-11 09:46:29 +080017610
developera3511852023-06-14 14:12:59 +080017611 memset(buf, 0, sizeof(buf));
17612 ret = wifi_getSSIDName(vap_index, buf);
17613 if (ret != RETURN_OK) {
17614 printf("%s: wifi_getSSIDName return error\n", __func__);
17615 return RETURN_ERR;
17616 }
developere40952c2023-06-15 18:46:43 +080017617 res = snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
17618 if (os_snprintf_error(sizeof(map->vap_array[i].u.bss_info.ssid), res)) {
17619 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17620 return RETURN_ERR;
17621 }
developer72fb0bb2023-01-11 09:46:29 +080017622
developera3511852023-06-14 14:12:59 +080017623 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080017624
developera3511852023-06-14 14:12:59 +080017625 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
17626 if (ret != RETURN_OK) {
17627 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
17628 return RETURN_ERR;
17629 }
17630 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080017631
developera3511852023-06-14 14:12:59 +080017632 ret = wifi_getApIsolationEnable(vap_index, &enabled);
17633 if (ret != RETURN_OK) {
17634 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
17635 return RETURN_ERR;
17636 }
17637 map->vap_array[i].u.bss_info.isolation = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017638
developera3511852023-06-14 14:12:59 +080017639 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
17640 if (ret != RETURN_OK) {
17641 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
17642 return RETURN_ERR;
17643 }
17644 map->vap_array[i].u.bss_info.bssMaxSta = output;
developer72fb0bb2023-01-11 09:46:29 +080017645
developera3511852023-06-14 14:12:59 +080017646 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
17647 if (ret != RETURN_OK) {
17648 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
17649 return RETURN_ERR;
17650 }
17651 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017652
developera3511852023-06-14 14:12:59 +080017653 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
17654 if (ret != RETURN_OK) {
17655 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
17656 return RETURN_ERR;
17657 }
17658 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017659
developera3511852023-06-14 14:12:59 +080017660 ret = wifi_getApSecurity(vap_index, &security);
17661 if (ret != RETURN_OK) {
17662 printf("%s: wifi_getApSecurity return error\n", __func__);
17663 return RETURN_ERR;
17664 }
17665 map->vap_array[i].u.bss_info.security = security;
developer72fb0bb2023-01-11 09:46:29 +080017666
developera3511852023-06-14 14:12:59 +080017667 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
17668 if (ret != RETURN_OK) {
17669 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
17670 return RETURN_ERR;
17671 }
17672 if (mode == 0)
17673 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
17674 else
17675 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
17676 if (mode == 1)
17677 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
17678 else if (mode == 2)
17679 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
developer72fb0bb2023-01-11 09:46:29 +080017680
developera3511852023-06-14 14:12:59 +080017681 ret = wifi_getApWmmEnable(vap_index, &enabled);
17682 if (ret != RETURN_OK) {
17683 printf("%s: wifi_getApWmmEnable return error\n", __func__);
17684 return RETURN_ERR;
17685 }
17686 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017687
developera3511852023-06-14 14:12:59 +080017688 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
17689 if (ret != RETURN_OK) {
17690 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
17691 return RETURN_ERR;
17692 }
17693 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017694
developera3511852023-06-14 14:12:59 +080017695 memset(buf, 0, sizeof(buf));
17696 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
17697 if (ret != RETURN_OK) {
17698 printf("%s: wifi_getApBeaconRate return error\n", __func__);
17699 return RETURN_ERR;
17700 }
17701 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
developer72fb0bb2023-01-11 09:46:29 +080017702
developera3511852023-06-14 14:12:59 +080017703 memset(buf, 0, sizeof(buf));
17704 ret = wifi_getBaseBSSID(vap_index, buf);
17705 if (ret != RETURN_OK) {
17706 printf("%s: wifi_getBaseBSSID return error\n", __func__);
17707 return RETURN_ERR;
17708 }
developer5b2f10c2023-05-25 17:02:21 +080017709 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
17710 printf("%s: hwaddr_aton2 fail\n", __func__);
developera3511852023-06-14 14:12:59 +080017711 return RETURN_ERR;
developer5b2f10c2023-05-25 17:02:21 +080017712 }
developer72fb0bb2023-01-11 09:46:29 +080017713
developera3511852023-06-14 14:12:59 +080017714 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
17715 if (ret != RETURN_OK) {
17716 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
17717 return RETURN_ERR;
17718 }
17719 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017720
developera3511852023-06-14 14:12:59 +080017721 // TODO: wps, noack
17722 }
17723 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17724 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017725}
17726
developer47cc27a2023-05-17 23:09:58 +080017727void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080017728{
developera3511852023-06-14 14:12:59 +080017729 char if_name[16] = {0};
17730 char cmd[128] = {0};
17731 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080017732 int res;
developer72fb0bb2023-01-11 09:46:29 +080017733
developera3511852023-06-14 14:12:59 +080017734 *enable = FALSE;
17735 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
17736 return;
developer72fb0bb2023-01-11 09:46:29 +080017737
developere40952c2023-06-15 18:46:43 +080017738 res = snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
17739 if (os_snprintf_error(sizeof(cmd), res)) {
17740 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17741 return;
17742 }
developera3511852023-06-14 14:12:59 +080017743 _syscmd(cmd, buf, sizeof(buf));
17744 if (strlen(buf) > 0)
17745 *enable = TRUE;
17746 return;
developer72fb0bb2023-01-11 09:46:29 +080017747}
17748
developer56fbedb2023-05-30 16:47:05 +080017749int hostapd_manage_bss(INT apIndex, BOOL enable)
17750{
17751 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080017752 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer56fbedb2023-05-30 16:47:05 +080017753 char cmd[MAX_CMD_SIZE] = {0};
17754 char buf[MAX_BUF_SIZE] = {0};
17755 BOOL status = FALSE;
17756 int max_radio_num = 0;
17757 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080017758 int res;
developer56fbedb2023-05-30 16:47:05 +080017759
17760 wifi_getApEnable(apIndex, &status);
17761
17762 wifi_getMaxRadioNumber(&max_radio_num);
17763 if (enable == status)
17764 return RETURN_OK;
17765
17766 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
17767 return RETURN_ERR;
17768
17769 if (enable == TRUE) {
17770 int radioIndex = apIndex % max_radio_num;
17771 phyId = radio_index_to_phy(radioIndex);
17772 fprintf(stderr, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080017773 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
17774 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
17775 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17776 return RETURN_ERR;
17777 }
17778 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
17779 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
17780 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17781 return RETURN_ERR;
17782 }
developer56fbedb2023-05-30 16:47:05 +080017783 _syscmd(cmd, buf, sizeof(buf));
17784 } else {
17785 fprintf(stderr, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080017786 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
17787 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
17788 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17789 return RETURN_ERR;
17790 }
developer56fbedb2023-05-30 16:47:05 +080017791 _syscmd(cmd, buf, sizeof(buf));
17792 }
developere40952c2023-06-15 18:46:43 +080017793 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer56fbedb2023-05-30 16:47:05 +080017794 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +080017795 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
17796 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17797 return RETURN_ERR;
17798 }
developer56fbedb2023-05-30 16:47:05 +080017799 _syscmd(cmd, buf, sizeof(buf));
17800 //Wait for wifi up/down to apply
17801 return RETURN_OK;
17802}
17803
17804int hostapd_raw_add_bss(int apIndex)
17805{
17806 return hostapd_manage_bss(apIndex, TRUE);
17807}
17808
17809int hostapd_raw_remove_bss(int apIndex)
17810{
17811 return hostapd_manage_bss(apIndex, FALSE);
17812}
17813
17814int hostapd_raw_restart_bss(int apIndex)
developer333c1eb2023-05-31 14:59:39 +080017815{
developerdaf24792023-06-06 11:40:04 +080017816 int ret = 0;
17817
17818 ret = hostapd_raw_remove_bss(apIndex);
17819 if(ret != RETURN_OK)
17820 return RETURN_ERR;
17821
17822 ret = hostapd_raw_add_bss(apIndex);
17823 if(ret != RETURN_OK)
17824 return RETURN_ERR;
17825
17826 return RETURN_OK;
developer56fbedb2023-05-30 16:47:05 +080017827}
17828
developer72fb0bb2023-01-11 09:46:29 +080017829INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
17830{
developera3511852023-06-14 14:12:59 +080017831 unsigned int i;
17832 wifi_vap_info_t *vap_info = NULL;
17833 int acl_mode;
17834 int ret = 0;
17835 char buf[256] = {0};
17836 char cmd[128] = {0};
17837 char config_file[64] = {0};
17838 char psk_file[64] = {0};
17839 BOOL enable = FALSE;
17840 int band_idx;
developere40952c2023-06-15 18:46:43 +080017841 int res;
developere740c2a2023-05-23 18:34:32 +080017842
developer72fb0bb2023-01-11 09:46:29 +080017843
developera3511852023-06-14 14:12:59 +080017844 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17845 printf("Entering %s index = %d\n", __func__, (int)index);
17846 for (i = 0; i < map->num_vaps; i++)
17847 {
17848 multiple_set = TRUE;
17849 vap_info = &map->vap_array[i];
developer72fb0bb2023-01-11 09:46:29 +080017850
developera3511852023-06-14 14:12:59 +080017851 // Check vap status file to enable multiple ap if the system boot.
17852 checkVapStatus(vap_info->vap_index, &enable);
17853 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
17854 continue;
developer72fb0bb2023-01-11 09:46:29 +080017855
developer75bd10c2023-06-27 11:34:08 +080017856 wifi_debug(DEBUG_ERROR, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
developer72fb0bb2023-01-11 09:46:29 +080017857
developera3511852023-06-14 14:12:59 +080017858 band_idx = radio_index_to_band(index);
developere40952c2023-06-15 18:46:43 +080017859 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
17860 if (os_snprintf_error(sizeof(config_file), res)) {
17861 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17862 return RETURN_ERR;
17863 }
developer9ce44382023-06-28 11:09:37 +080017864 if(band_idx >= 0 && band_idx < sizeof(wifi_band_str)/sizeof(wifi_band_str[0])){
17865 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
17866 } else{
17867 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17868 return RETURN_ERR;
17869 }
developere40952c2023-06-15 18:46:43 +080017870 if (os_snprintf_error(sizeof(cmd), res)) {
17871 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17872 return RETURN_ERR;
17873 }
developera3511852023-06-14 14:12:59 +080017874 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080017875
developera3511852023-06-14 14:12:59 +080017876 struct params params[3];
17877 params[0].name = "interface";
17878 params[0].value = vap_info->vap_name;
developere40952c2023-06-15 18:46:43 +080017879 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
17880 if (os_snprintf_error(sizeof(psk_file), res)) {
17881 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17882 return RETURN_ERR;
17883 }
developera3511852023-06-14 14:12:59 +080017884 params[1].name = "wpa_psk_file";
17885 params[1].value = psk_file;
17886 params[2].name = "ssid";
17887 params[2].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080017888
developer9ce44382023-06-28 11:09:37 +080017889 snprintf(config_file,sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
developera3511852023-06-14 14:12:59 +080017890 wifi_hostapdWrite(config_file, params, 3);
developer72fb0bb2023-01-11 09:46:29 +080017891
developere40952c2023-06-15 18:46:43 +080017892 res = snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
17893 if (os_snprintf_error(sizeof(cmd), res)) {
17894 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17895 return RETURN_ERR;
17896 }
developera3511852023-06-14 14:12:59 +080017897 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080017898
developera3511852023-06-14 14:12:59 +080017899 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
17900 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017901 wifi_debug(DEBUG_ERROR,"wifi_setSSIDName return error\n");
developera3511852023-06-14 14:12:59 +080017902 return RETURN_ERR;
17903 }
developer72fb0bb2023-01-11 09:46:29 +080017904
developera3511852023-06-14 14:12:59 +080017905 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
17906 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017907 wifi_debug(DEBUG_ERROR, "wifi_setApSsidAdvertisementEnable return error\n");
developera3511852023-06-14 14:12:59 +080017908 return RETURN_ERR;
17909 }
developer72fb0bb2023-01-11 09:46:29 +080017910
developera3511852023-06-14 14:12:59 +080017911 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
17912 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017913 wifi_debug(DEBUG_ERROR, "wifi_setApIsolationEnable return error\n");
developera3511852023-06-14 14:12:59 +080017914 return RETURN_ERR;
17915 }
developer72fb0bb2023-01-11 09:46:29 +080017916
developera3511852023-06-14 14:12:59 +080017917 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
17918 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017919 wifi_debug(DEBUG_ERROR, "wifi_setApMaxAssociatedDevices return error\n");
developera3511852023-06-14 14:12:59 +080017920 return RETURN_ERR;
17921 }
developer72fb0bb2023-01-11 09:46:29 +080017922
developera3511852023-06-14 14:12:59 +080017923 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
17924 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017925 wifi_debug(DEBUG_ERROR, "wifi_setBSSTransitionActivation return error\n");
developera3511852023-06-14 14:12:59 +080017926 return RETURN_ERR;
17927 }
developer72fb0bb2023-01-11 09:46:29 +080017928
developera3511852023-06-14 14:12:59 +080017929 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
17930 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017931 wifi_debug(DEBUG_ERROR, "wifi_setNeighborReportActivation return error\n");
developera3511852023-06-14 14:12:59 +080017932 return RETURN_ERR;
17933 }
developer72fb0bb2023-01-11 09:46:29 +080017934
developera3511852023-06-14 14:12:59 +080017935 if (vap_info->u.bss_info.mac_filter_enable == false){
17936 acl_mode = 0;
17937 }else {
17938 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
17939 acl_mode = 2;
developere40952c2023-06-15 18:46:43 +080017940 res = snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
17941 if (os_snprintf_error(sizeof(cmd), res)) {
17942 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17943 return RETURN_ERR;
17944 }
developera3511852023-06-14 14:12:59 +080017945 _syscmd(cmd, buf, sizeof(buf));
17946 }else{
17947 acl_mode = 1;
17948 }
17949 }
developer72fb0bb2023-01-11 09:46:29 +080017950
developera3511852023-06-14 14:12:59 +080017951 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
17952 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017953 wifi_debug(DEBUG_ERROR, "wifi_setApWmmEnable return error\n");
developera3511852023-06-14 14:12:59 +080017954 return RETURN_ERR;
17955 }
developer72fb0bb2023-01-11 09:46:29 +080017956
developera3511852023-06-14 14:12:59 +080017957 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
17958 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017959 wifi_debug(DEBUG_ERROR, "wifi_setApWmmUapsdEnable return error\n");
developera3511852023-06-14 14:12:59 +080017960 return RETURN_ERR;
17961 }
developer72fb0bb2023-01-11 09:46:29 +080017962
developera3511852023-06-14 14:12:59 +080017963 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080017964 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080017965 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
17966 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017967 wifi_debug(DEBUG_ERROR, "wifi_setApBeaconRate return error\n");
developera3511852023-06-14 14:12:59 +080017968 return RETURN_ERR;
17969 }
developer72fb0bb2023-01-11 09:46:29 +080017970
developera3511852023-06-14 14:12:59 +080017971 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
17972 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017973 wifi_debug(DEBUG_ERROR, "wifi_setRadioIGMPSnoopingEnable\n");
developera3511852023-06-14 14:12:59 +080017974 return RETURN_ERR;
17975 }
developer72fb0bb2023-01-11 09:46:29 +080017976
developera3511852023-06-14 14:12:59 +080017977 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
17978 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017979 wifi_debug(DEBUG_ERROR, "wifi_setApSecurity return error\n");
developera3511852023-06-14 14:12:59 +080017980 return RETURN_ERR;
17981 }
developer333c1eb2023-05-31 14:59:39 +080017982
developer56fbedb2023-05-30 16:47:05 +080017983 hostapd_raw_restart_bss(vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080017984
developera3511852023-06-14 14:12:59 +080017985 multiple_set = FALSE;
developer23e71282023-01-18 10:25:19 +080017986
developera3511852023-06-14 14:12:59 +080017987 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
17988 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
17989 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080017990 wifi_debug(DEBUG_ERROR, "wifi_setApMacAddressControlMode return error\n");
developera3511852023-06-14 14:12:59 +080017991 return RETURN_ERR;
17992 }
developer72fb0bb2023-01-11 09:46:29 +080017993
developera3511852023-06-14 14:12:59 +080017994 // TODO mgmtPowerControl, interworking, wps
17995 }
17996 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17997 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017998}
17999
18000int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
18001{
developera3511852023-06-14 14:12:59 +080018002 char *token, *next;
18003 const char s[2] = ",";
18004 int count =0;
developer72fb0bb2023-01-11 09:46:29 +080018005
developera3511852023-06-14 14:12:59 +080018006 /* get the first token */
18007 token = strtok_r(pchannels, s, &next);
developer72fb0bb2023-01-11 09:46:29 +080018008
developera3511852023-06-14 14:12:59 +080018009 /* walk through other tokens */
18010 while( token != NULL && count < MAX_CHANNELS) {
18011 chlistptr->channels_list[count++] = atoi(token);
18012 token = strtok_r(NULL, s, &next);
18013 }
developer72fb0bb2023-01-11 09:46:29 +080018014
developera3511852023-06-14 14:12:59 +080018015 return count;
developer72fb0bb2023-01-11 09:46:29 +080018016}
18017
18018static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
18019{
developera3511852023-06-14 14:12:59 +080018020 INT status;
18021 wifi_channels_list_t *chlistp;
18022 CHAR output_string[64];
18023 CHAR pchannels[128];
18024 CHAR interface_name[16] = {0};
18025 wifi_band band;
developere40952c2023-06-15 18:46:43 +080018026 int res;
developer72fb0bb2023-01-11 09:46:29 +080018027
developera3511852023-06-14 14:12:59 +080018028 if(rcap == NULL)
18029 {
18030 return RETURN_ERR;
18031 }
developer72fb0bb2023-01-11 09:46:29 +080018032
developera3511852023-06-14 14:12:59 +080018033 rcap->numSupportedFreqBand = 1;
18034 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080018035
developera3511852023-06-14 14:12:59 +080018036 if (band == band_2_4)
18037 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
18038 else if (band == band_5)
18039 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
18040 else if (band == band_6)
18041 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
developer72fb0bb2023-01-11 09:46:29 +080018042
developera3511852023-06-14 14:12:59 +080018043 chlistp = &(rcap->channel_list[0]);
18044 memset(pchannels, 0, sizeof(pchannels));
developer72fb0bb2023-01-11 09:46:29 +080018045
developera3511852023-06-14 14:12:59 +080018046 /* possible number of radio channels */
18047 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
18048 {
18049 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
18050 }
18051 /* Number of channels and list*/
18052 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
developer72fb0bb2023-01-11 09:46:29 +080018053
developera3511852023-06-14 14:12:59 +080018054 /* autoChannelSupported */
18055 /* always ON with wifi_getRadioAutoChannelSupported */
18056 rcap->autoChannelSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018057
developera3511852023-06-14 14:12:59 +080018058 /* DCSSupported */
18059 /* always ON with wifi_getRadioDCSSupported */
18060 rcap->DCSSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018061
developera3511852023-06-14 14:12:59 +080018062 /* zeroDFSSupported - TBD */
18063 rcap->zeroDFSSupported = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018064
developera3511852023-06-14 14:12:59 +080018065 /* Supported Country List*/
18066 memset(output_string, 0, sizeof(output_string));
18067 status = wifi_getRadioCountryCode(radioIndex, output_string);
18068 if( status != 0 ) {
18069 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
18070 return RETURN_ERR;
18071 } else {
18072 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
18073 }
18074 if(!strcmp(output_string,"US")){
18075 rcap->countrySupported[0] = wifi_countrycode_US;
18076 rcap->countrySupported[1] = wifi_countrycode_CA;
18077 } else if (!strcmp(output_string,"CA")) {
18078 rcap->countrySupported[0] = wifi_countrycode_CA;
18079 rcap->countrySupported[1] = wifi_countrycode_US;
18080 } else {
18081 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
18082 }
developer72fb0bb2023-01-11 09:46:29 +080018083
developera3511852023-06-14 14:12:59 +080018084 rcap->numcountrySupported = 2;
developer72fb0bb2023-01-11 09:46:29 +080018085
developera3511852023-06-14 14:12:59 +080018086 /* csi */
18087 rcap->csi.maxDevices = 8;
18088 rcap->csi.soudingFrameSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018089
developer86035662023-06-28 19:21:12 +080018090 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
18091 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
18092 }
developere40952c2023-06-15 18:46:43 +080018093 res = snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
18094 if (os_snprintf_error(sizeof(interface_name), res)) {
18095 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18096 return RETURN_ERR;
18097 }
developer72fb0bb2023-01-11 09:46:29 +080018098
developera3511852023-06-14 14:12:59 +080018099 /* channelWidth - all supported bandwidths */
18100 int i=0;
18101 rcap->channelWidth[i] = 0;
18102 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
18103 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
18104 WIFI_CHANNELBANDWIDTH_40MHZ);
developer72fb0bb2023-01-11 09:46:29 +080018105
developera3511852023-06-14 14:12:59 +080018106 }
18107 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
18108 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
18109 WIFI_CHANNELBANDWIDTH_40MHZ |
18110 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
18111 }
developer72fb0bb2023-01-11 09:46:29 +080018112
18113
developera3511852023-06-14 14:12:59 +080018114 /* mode - all supported variants */
18115 // rcap->mode[i] = WIFI_80211_VARIANT_H;
18116 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
18117 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
18118 }
18119 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
18120 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
18121 }
18122 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
18123 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
18124 }
18125 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
18126 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
developer72fb0bb2023-01-11 09:46:29 +080018127
developera3511852023-06-14 14:12:59 +080018128 /* supportedBitRate - all supported bitrates */
18129 rcap->supportedBitRate[i] = 0;
18130 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
18131 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
18132 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
18133 }
18134 else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
18135 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
18136 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
18137 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
18138 }
developer72fb0bb2023-01-11 09:46:29 +080018139
18140
developera3511852023-06-14 14:12:59 +080018141 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
18142 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
18143 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
18144 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
18145 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
18146 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
18147 rcap->cipherSupported = 0;
18148 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
18149 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
developer72fb0bb2023-01-11 09:46:29 +080018150
developera3511852023-06-14 14:12:59 +080018151 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018152}
18153
18154INT wifi_getHalCapability(wifi_hal_capability_t *cap)
18155{
developera3511852023-06-14 14:12:59 +080018156 INT status = 0, radioIndex = 0;
18157 char output[MAX_BUF_SIZE] = {0};
18158 int iter = 0;
18159 unsigned int j = 0;
developer9ce44382023-06-28 11:09:37 +080018160 int max_num_radios = 0;
developera3511852023-06-14 14:12:59 +080018161 wifi_interface_name_idex_map_t *iface_info = NULL;
developer72fb0bb2023-01-11 09:46:29 +080018162
developera3511852023-06-14 14:12:59 +080018163 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018164
developera3511852023-06-14 14:12:59 +080018165 memset(cap, 0, sizeof(wifi_hal_capability_t));
developer72fb0bb2023-01-11 09:46:29 +080018166
developera3511852023-06-14 14:12:59 +080018167 /* version */
18168 cap->version.major = WIFI_HAL_MAJOR_VERSION;
18169 cap->version.minor = WIFI_HAL_MINOR_VERSION;
developer72fb0bb2023-01-11 09:46:29 +080018170
developera3511852023-06-14 14:12:59 +080018171 /* number of radios platform property */
18172 wifi_getMaxRadioNumber(&max_num_radios);
18173 cap->wifi_prop.numRadios = max_num_radios;
developer72fb0bb2023-01-11 09:46:29 +080018174
developera3511852023-06-14 14:12:59 +080018175 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
18176 {
18177 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
18178 if (status != 0) {
18179 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
18180 return RETURN_ERR;
18181 }
developer72fb0bb2023-01-11 09:46:29 +080018182
developera3511852023-06-14 14:12:59 +080018183 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
18184 {
18185 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
18186 {
18187 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
18188 return RETURN_ERR;
18189 }
18190 iface_info = &cap->wifi_prop.interface_map[iter];
18191 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
18192 iface_info->rdk_radio_index = radioIndex;
18193 memset(output, 0, sizeof(output));
18194 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
18195 {
18196 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
18197 }
18198 // TODO: bridge name
18199 // TODO: vlan id
18200 // TODO: primary
18201 iface_info->index = array_index_to_vap_index(radioIndex, j);
18202 memset(output, 0, sizeof(output));
18203 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
18204 {
18205 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
18206 }
18207 iter++;
18208 }
18209 }
developer72fb0bb2023-01-11 09:46:29 +080018210
developera3511852023-06-14 14:12:59 +080018211 cap->BandSteeringSupported = FALSE;
18212 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18213 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018214}
18215
18216INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
18217{
developera3511852023-06-14 14:12:59 +080018218 struct params h_config={0};
18219 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018220 int res;
developer72fb0bb2023-01-11 09:46:29 +080018221
developera3511852023-06-14 14:12:59 +080018222 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018223
developera3511852023-06-14 14:12:59 +080018224 h_config.name = "okc";
18225 h_config.value = okc_enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018226
developere40952c2023-06-15 18:46:43 +080018227 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18228 if (os_snprintf_error(sizeof(config_file), res)) {
18229 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18230 return RETURN_ERR;
18231 }
developera3511852023-06-14 14:12:59 +080018232 wifi_hostapdWrite(config_file, &h_config, 1);
18233 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018234
developera3511852023-06-14 14:12:59 +080018235 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18236 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018237}
18238
18239INT wifi_setSAEMFP(int ap_index, BOOL enable)
18240{
developera3511852023-06-14 14:12:59 +080018241 struct params h_config={0};
18242 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018243 int res;
developer72fb0bb2023-01-11 09:46:29 +080018244
developera3511852023-06-14 14:12:59 +080018245 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018246
developera3511852023-06-14 14:12:59 +080018247 h_config.name = "sae_require_mfp";
18248 h_config.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018249
developere40952c2023-06-15 18:46:43 +080018250 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18251 if (os_snprintf_error(sizeof(config_file), res)) {
18252 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18253 return RETURN_ERR;
18254 }
developera3511852023-06-14 14:12:59 +080018255 wifi_hostapdWrite(config_file, &h_config, 1);
18256 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018257
developera3511852023-06-14 14:12:59 +080018258 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18259 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018260}
18261
18262INT wifi_setSAEpwe(int ap_index, int sae_pwe)
18263{
developera3511852023-06-14 14:12:59 +080018264 struct params h_config={0};
18265 char config_file[64] = {0};
18266 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080018267 int res;
developer72fb0bb2023-01-11 09:46:29 +080018268
developera3511852023-06-14 14:12:59 +080018269 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018270
developera3511852023-06-14 14:12:59 +080018271 h_config.name = "sae_pwe";
developere40952c2023-06-15 18:46:43 +080018272 res = snprintf(buf, sizeof(buf), "%d", sae_pwe);
18273 if (os_snprintf_error(sizeof(buf), res)) {
18274 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18275 return RETURN_ERR;
18276 }
18277
developera3511852023-06-14 14:12:59 +080018278 h_config.value = buf;
developer72fb0bb2023-01-11 09:46:29 +080018279
developere40952c2023-06-15 18:46:43 +080018280 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18281 if (os_snprintf_error(sizeof(config_file), res)) {
18282 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18283 return RETURN_ERR;
18284 }
developera3511852023-06-14 14:12:59 +080018285 wifi_hostapdWrite(config_file, &h_config, 1);
18286 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018287
developera3511852023-06-14 14:12:59 +080018288 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18289 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018290}
18291
18292INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
18293{
developera3511852023-06-14 14:12:59 +080018294 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
18295 struct params h_config={0};
18296 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018297 int res;
developer72fb0bb2023-01-11 09:46:29 +080018298
developera3511852023-06-14 14:12:59 +080018299 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018300
developera3511852023-06-14 14:12:59 +080018301 h_config.name = "wpa_disable_eapol_key_retries";
18302 h_config.value = disable_EAPOL_retries?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018303
developere40952c2023-06-15 18:46:43 +080018304 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18305 if (os_snprintf_error(sizeof(config_file), res)) {
18306 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18307 return RETURN_ERR;
18308 }
developera3511852023-06-14 14:12:59 +080018309 wifi_hostapdWrite(config_file, &h_config, 1);
18310 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018311
developera3511852023-06-14 14:12:59 +080018312 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18313 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018314}
18315
18316INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
18317{
developera3511852023-06-14 14:12:59 +080018318 char buf[128] = {0};
18319 char config_file[128] = {0};
18320 char cmd[MAX_CMD_SIZE] = {0};
18321 char password[65] = {0};
18322 char mfp[32] = {0};
18323 char wpa_mode[32] = {0};
18324 BOOL okc_enable = FALSE;
18325 BOOL sae_MFP = FALSE;
18326 BOOL disable_EAPOL_retries = TRUE;
18327 int sae_pwe = 0;
18328 struct params params = {0};
18329 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080018330 int res;
developer72fb0bb2023-01-11 09:46:29 +080018331
developera3511852023-06-14 14:12:59 +080018332 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018333
developera3511852023-06-14 14:12:59 +080018334 multiple_set = TRUE;
developer9ce44382023-06-28 11:09:37 +080018335 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
developera3511852023-06-14 14:12:59 +080018336 if (security->mode == wifi_security_mode_none) {
developer9ce44382023-06-28 11:09:37 +080018337 strncpy(wpa_mode, "None",sizeof(wpa_mode) - 1);
18338 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18339 } else if (security->mode == wifi_security_mode_wpa_personal) {
18340 strncpy(wpa_mode, "WPA-Personal",sizeof(wpa_mode) - 1);
18341 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18342 } else if (security->mode == wifi_security_mode_wpa2_personal){
18343 strncpy(wpa_mode, "WPA2-Personal",sizeof(wpa_mode) - 1);
18344 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18345 } else if (security->mode == wifi_security_mode_wpa_wpa2_personal){
18346 strncpy(wpa_mode, "WPA-WPA2-Personal",sizeof(wpa_mode) - 1);
18347 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18348 } else if (security->mode == wifi_security_mode_wpa_enterprise){
18349 strncpy(wpa_mode, "WPA-Enterprise",sizeof(wpa_mode) - 1);
18350 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18351 } else if (security->mode == wifi_security_mode_wpa2_enterprise){
18352 strncpy(wpa_mode, "WPA2-Enterprise",sizeof(wpa_mode) - 1);
18353 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18354 } else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise){
18355 strncpy(wpa_mode, "WPA-WAP2-Enterprise",sizeof(wpa_mode) - 1);
18356 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18357 } else if (security->mode == wifi_security_mode_wpa3_personal) {
18358 strncpy(wpa_mode, "WPA3-Personal",sizeof(wpa_mode) - 1);
18359 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018360 okc_enable = TRUE;
18361 sae_MFP = TRUE;
18362 sae_pwe = 2;
18363 disable_EAPOL_retries = FALSE;
18364 } else if (security->mode == wifi_security_mode_wpa3_transition) {
developer9ce44382023-06-28 11:09:37 +080018365 strncpy(wpa_mode, "WPA3-Personal-Transition",sizeof(wpa_mode) - 1);
18366 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018367 okc_enable = TRUE;
18368 sae_MFP = TRUE;
18369 sae_pwe = 2;
18370 disable_EAPOL_retries = FALSE;
18371 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
developer9ce44382023-06-28 11:09:37 +080018372 strncpy(wpa_mode, "WPA3-Enterprise",sizeof(wpa_mode) - 1);
18373 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018374 sae_MFP = TRUE;
18375 sae_pwe = 2;
18376 disable_EAPOL_retries = FALSE;
18377 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer9ce44382023-06-28 11:09:37 +080018378 strncpy(wpa_mode, "OWE",sizeof(wpa_mode) - 1);
18379 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018380 sae_MFP = TRUE;
18381 sae_pwe = 2;
18382 disable_EAPOL_retries = FALSE;
18383 }
developer72fb0bb2023-01-11 09:46:29 +080018384
developera3511852023-06-14 14:12:59 +080018385 band = wifi_index_to_band(ap_index);
18386 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
18387 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
18388 return RETURN_ERR;
18389 }
developer72fb0bb2023-01-11 09:46:29 +080018390
developera3511852023-06-14 14:12:59 +080018391 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
18392 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
18393 wifi_setSAEMFP(ap_index, sae_MFP);
18394 wifi_setSAEpwe(ap_index, sae_pwe);
18395 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
developer72fb0bb2023-01-11 09:46:29 +080018396
developera3511852023-06-14 14:12:59 +080018397 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
18398 if (security->u.key.type == wifi_security_key_type_psk || security->u.key.type == wifi_security_key_type_pass || security->u.key.type == wifi_security_key_type_psk_sae) {
18399 int key_len = strlen(security->u.key.key);
18400 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
18401 if (key_len == 64) { // set wpa_psk
18402 strncpy(password, security->u.key.key, 64); // 64 characters
18403 password[64] = '\0';
18404 wifi_setApSecurityPreSharedKey(ap_index, password);
developere40952c2023-06-15 18:46:43 +080018405 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
18406 if (os_snprintf_error(sizeof(cmd), res)) {
18407 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18408 return RETURN_ERR;
18409 }
developera3511852023-06-14 14:12:59 +080018410 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
18411 strncpy(password, security->u.key.key, 63);
18412 password[63] = '\0';
18413 wifi_setApSecurityKeyPassphrase(ap_index, password);
developere40952c2023-06-15 18:46:43 +080018414 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
developer9ce44382023-06-28 11:09:37 +080018415 if (os_snprintf_error(sizeof(cmd), res)) {
18416 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18417 return RETURN_ERR;
18418 }
developera3511852023-06-14 14:12:59 +080018419 } else
18420 return RETURN_ERR;
18421 _syscmd(cmd, buf, sizeof(buf));
18422 }
18423 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
18424 params.name = "sae_password";
18425 params.value = security->u.key.key;
18426 wifi_hostapdWrite(config_file, &params, 1);
18427 } else { // remove sae_password
developere40952c2023-06-15 18:46:43 +080018428 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
18429 if (os_snprintf_error(sizeof(cmd), res)) {
18430 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18431 return RETURN_ERR;
18432 }
developera3511852023-06-14 14:12:59 +080018433 _syscmd(cmd, buf, sizeof(buf));
18434 }
18435 }
developer72fb0bb2023-01-11 09:46:29 +080018436
developera3511852023-06-14 14:12:59 +080018437 if (security->mode != wifi_security_mode_none) {
18438 memset(&params, 0, sizeof(params));
18439 params.name = "wpa_pairwise";
18440 if (security->encr == wifi_encryption_tkip)
18441 params.value = "TKIP";
18442 else if (security->encr == wifi_encryption_aes)
18443 params.value = "CCMP";
18444 else if (security->encr == wifi_encryption_aes_tkip)
18445 params.value = "TKIP CCMP";
18446 wifi_hostapdWrite(config_file, &params, 1);
18447 }
developer72fb0bb2023-01-11 09:46:29 +080018448
developer9ce44382023-06-28 11:09:37 +080018449 if (security->mfp == wifi_mfp_cfg_disabled){
18450 strncpy(mfp,"Disabled",sizeof(mfp)-1);
18451 mfp[sizeof(mfp)-1] = '\0';
18452 } else if (security->mfp == wifi_mfp_cfg_optional){
18453 strncpy(mfp,"Optional",sizeof(mfp)-1);
18454 mfp[sizeof(mfp)-1] = '\0';
18455 } else if (security->mfp == wifi_mfp_cfg_required){
18456 strncpy(mfp,"Required",sizeof(mfp)-1);
18457 mfp[sizeof(mfp)-1] = '\0';
18458 }
developera3511852023-06-14 14:12:59 +080018459 wifi_setApSecurityMFPConfig(ap_index, mfp);
developer72fb0bb2023-01-11 09:46:29 +080018460
developera3511852023-06-14 14:12:59 +080018461 memset(&params, 0, sizeof(params));
18462 params.name = "transition_disable";
18463 if (security->wpa3_transition_disable == TRUE)
18464 params.value = "0x01";
18465 else
18466 params.value = "0x00";
18467 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018468
developera3511852023-06-14 14:12:59 +080018469 memset(&params, 0, sizeof(params));
18470 params.name = "wpa_group_rekey";
developere40952c2023-06-15 18:46:43 +080018471 res = snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
18472 if (os_snprintf_error(sizeof(buf), res)) {
18473 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18474 return RETURN_ERR;
18475 }
developera3511852023-06-14 14:12:59 +080018476 params.value = buf;
18477 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018478
developera3511852023-06-14 14:12:59 +080018479 memset(&params, 0, sizeof(params));
18480 params.name = "wpa_strict_rekey";
18481 params.value = security->strict_rekey?"1":"0";
18482 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018483
developera3511852023-06-14 14:12:59 +080018484 memset(&params, 0, sizeof(params));
18485 params.name = "wpa_pairwise_update_count";
18486 if (security->eapol_key_retries == 0)
18487 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developere40952c2023-06-15 18:46:43 +080018488 res = snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
18489 if (os_snprintf_error(sizeof(buf), res)) {
18490 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18491 return RETURN_ERR;
18492 }
developera3511852023-06-14 14:12:59 +080018493 params.value = buf;
18494 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018495
developera3511852023-06-14 14:12:59 +080018496 memset(&params, 0, sizeof(params));
18497 params.name = "disable_pmksa_caching";
18498 params.value = security->disable_pmksa_caching?"1":"0";
18499 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018500
developera3511852023-06-14 14:12:59 +080018501 if (multiple_set == FALSE) {
18502 wifi_setApEnable(ap_index, FALSE);
18503 wifi_setApEnable(ap_index, TRUE);
18504 }
developer72fb0bb2023-01-11 09:46:29 +080018505
developera3511852023-06-14 14:12:59 +080018506 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018507
developera3511852023-06-14 14:12:59 +080018508 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018509}
18510
18511INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
18512{
developera3511852023-06-14 14:12:59 +080018513 char buf[256] = {0};
18514 char config_file[128] = {0};
developer86035662023-06-28 19:21:12 +080018515 long int disable = 0;
18516 long int tmp;
developera3511852023-06-14 14:12:59 +080018517 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018518
developera3511852023-06-14 14:12:59 +080018519 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer9ce44382023-06-28 11:09:37 +080018520 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
developera3511852023-06-14 14:12:59 +080018521 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
18522 security->mode = wifi_security_mode_none;
18523 if (strlen(buf) != 0) {
18524 if (!strcmp(buf, "WPA-Personal"))
18525 security->mode = wifi_security_mode_wpa_personal;
18526 else if (!strcmp(buf, "WPA2-Personal"))
18527 security->mode = wifi_security_mode_wpa2_personal;
18528 else if (!strcmp(buf, "WPA-WPA2-Personal"))
18529 security->mode = wifi_security_mode_wpa_wpa2_personal;
18530 else if (!strcmp(buf, "WPA-Enterprise"))
18531 security->mode = wifi_security_mode_wpa_enterprise;
18532 else if (!strcmp(buf, "WPA2-Enterprise"))
18533 security->mode = wifi_security_mode_wpa2_enterprise;
18534 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
18535 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
18536 else if (!strcmp(buf, "WPA3-Personal"))
18537 security->mode = wifi_security_mode_wpa3_personal;
18538 else if (!strcmp(buf, "WPA3-Personal-Transition"))
18539 security->mode = wifi_security_mode_wpa3_transition;
18540 else if (!strcmp(buf, "WPA3-Enterprise"))
18541 security->mode = wifi_security_mode_wpa3_enterprise;
18542 else if (!strcmp(buf, "OWE"))
18543 security->mode = wifi_security_mode_enhanced_open;
18544 }
developer72fb0bb2023-01-11 09:46:29 +080018545
developera3511852023-06-14 14:12:59 +080018546 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
18547 if (security->mode == wifi_security_mode_none)
18548 security->encr = wifi_encryption_none;
18549 else {
18550 if (strcmp(buf, "TKIP") == 0)
18551 security->encr = wifi_encryption_tkip;
18552 else if (strcmp(buf, "CCMP") == 0)
18553 security->encr = wifi_encryption_aes;
18554 else
18555 security->encr = wifi_encryption_aes_tkip;
18556 }
developer72fb0bb2023-01-11 09:46:29 +080018557
developera3511852023-06-14 14:12:59 +080018558 if (security->mode != wifi_security_mode_none) {
18559 memset(buf, 0, sizeof(buf));
18560 // wpa3 can use one or both configs as password, so we check sae_password first.
18561 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
18562 if (strlen(buf) != 0) {
18563 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
18564 security->u.key.type = wifi_security_key_type_sae;
18565 set_sae = TRUE;
18566 strncpy(security->u.key.key, buf, sizeof(buf));
18567 }
18568 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
18569 if (strlen(buf) != 0){
18570 if (set_sae == TRUE)
18571 security->u.key.type = wifi_security_key_type_psk_sae;
18572 else if (strlen(buf) == 64)
18573 security->u.key.type = wifi_security_key_type_psk;
18574 else
18575 security->u.key.type = wifi_security_key_type_pass;
18576 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
18577 }
18578 security->u.key.key[255] = '\0';
18579 }
developer72fb0bb2023-01-11 09:46:29 +080018580
developera3511852023-06-14 14:12:59 +080018581 memset(buf, 0, sizeof(buf));
18582 wifi_getApSecurityMFPConfig(ap_index, buf);
18583 if (strcmp(buf, "Disabled") == 0)
18584 security->mfp = wifi_mfp_cfg_disabled;
18585 else if (strcmp(buf, "Optional") == 0)
18586 security->mfp = wifi_mfp_cfg_optional;
18587 else if (strcmp(buf, "Required") == 0)
18588 security->mfp = wifi_mfp_cfg_required;
developer72fb0bb2023-01-11 09:46:29 +080018589
developera3511852023-06-14 14:12:59 +080018590 memset(buf, 0, sizeof(buf));
18591 security->wpa3_transition_disable = FALSE;
18592 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
developer3de255a2023-06-29 10:35:45 +080018593 if (strlen(buf) == 0)
18594 disable = 0;
18595 else {
18596 if (hal_strtol(buf, 16, &disable) < 0) {
18597 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18598 return RETURN_ERR;
18599 }
developer86035662023-06-28 19:21:12 +080018600 }
developera3511852023-06-14 14:12:59 +080018601 if (disable != 0)
18602 security->wpa3_transition_disable = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018603
developera3511852023-06-14 14:12:59 +080018604 memset(buf, 0, sizeof(buf));
18605 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
18606 if (strlen(buf) == 0)
18607 security->rekey_interval = 86400;
developer86035662023-06-28 19:21:12 +080018608 else {
18609 if (hal_strtol(buf, 10, &tmp) < 0) {
18610 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18611 return RETURN_ERR;
18612 }
18613 security->rekey_interval = tmp;
18614 }
developer72fb0bb2023-01-11 09:46:29 +080018615
developera3511852023-06-14 14:12:59 +080018616 memset(buf, 0, sizeof(buf));
18617 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
18618 if (strlen(buf) == 0)
18619 security->strict_rekey = 1;
developer86035662023-06-28 19:21:12 +080018620 else {
18621 if (hal_strtol(buf, 10, &tmp) < 0) {
18622 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18623 return RETURN_ERR;
18624 }
18625 security->strict_rekey = tmp;
18626 }
developer72fb0bb2023-01-11 09:46:29 +080018627
developera3511852023-06-14 14:12:59 +080018628 memset(buf, 0, sizeof(buf));
18629 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
18630 if (strlen(buf) == 0)
18631 security->eapol_key_retries = 4;
developer86035662023-06-28 19:21:12 +080018632 else {
18633 if (hal_strtol(buf, 10, &tmp) < 0) {
18634 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18635 return RETURN_ERR;
18636 }
18637 security->eapol_key_retries = tmp;
18638 }
developer72fb0bb2023-01-11 09:46:29 +080018639
developera3511852023-06-14 14:12:59 +080018640 memset(buf, 0, sizeof(buf));
18641 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
18642 if (strlen(buf) == 0)
18643 security->disable_pmksa_caching = FALSE;
developer86035662023-06-28 19:21:12 +080018644 else {
18645 if (hal_strtol(buf, 10, &(tmp)) < 0) {
18646 wifi_debug(DEBUG_ERROR, "strtol fail\n");
18647 return RETURN_ERR;
18648 }
18649 security->disable_pmksa_caching = tmp ? TRUE : FALSE;
18650 }
developera3511852023-06-14 14:12:59 +080018651 /* TODO
18652 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
18653 */
18654 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
18655 security->eap_identity_req_timeout = 0;
18656 security->eap_identity_req_retries = 0;
18657 security->eap_req_timeout = 0;
18658 security->eap_req_retries = 0;
18659 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018661}
18662
18663#endif /* WIFI_HAL_VERSION_3 */
18664
18665#ifdef WIFI_HAL_VERSION_3_PHASE2
18666INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
18667{
developera3511852023-06-14 14:12:59 +080018668 char interface_name[16] = {0};
18669 char cmd[128] = {0};
18670 char buf[128] = {0};
18671 char *mac_addr = NULL;
18672 BOOL status = FALSE;
18673 size_t len = 0;
developer72fb0bb2023-01-11 09:46:29 +080018674
developera3511852023-06-14 14:12:59 +080018675 if(ap_index > MAX_APS)
18676 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018677
developera3511852023-06-14 14:12:59 +080018678 *output_numDevices = 0;
18679 wifi_getApEnable(ap_index, &status);
18680 if (status == FALSE)
18681 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018682
developera3511852023-06-14 14:12:59 +080018683 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
18684 return RETURN_ERR;
18685 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
18686 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080018687
developera3511852023-06-14 14:12:59 +080018688 mac_addr = strtok(buf, "\n");
18689 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
18690 *output_numDevices = i + 1;
18691 fprintf(stderr, "mac_addr: %s\n", mac_addr);
18692 addr_ptr = output_deviceMacAddressArray[i];
18693 mac_addr_aton(addr_ptr, mac_addr);
18694 mac_addr = strtok(NULL, "\n");
18695 }
developer72fb0bb2023-01-11 09:46:29 +080018696
developera3511852023-06-14 14:12:59 +080018697 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018698}
18699#else
18700INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
18701{
developera3511852023-06-14 14:12:59 +080018702 char interface_name[16] = {0};
18703 char cmd[128];
18704 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +080018705 int res;
developer72fb0bb2023-01-11 09:46:29 +080018706
developera3511852023-06-14 14:12:59 +080018707 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
18708 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018709
developera3511852023-06-14 14:12:59 +080018710 output_buf[0] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080018711
developera3511852023-06-14 14:12:59 +080018712 wifi_getApEnable(ap_index,&status);
18713 if (!status)
18714 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018715
developera3511852023-06-14 14:12:59 +080018716 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
18717 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080018718 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
18719 if (os_snprintf_error(sizeof(cmd), res)) {
18720 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18721 return RETURN_ERR;
18722 }
18723
developera3511852023-06-14 14:12:59 +080018724 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080018725
developera3511852023-06-14 14:12:59 +080018726 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018727}
18728#endif
18729
18730INT wifi_getProxyArp(INT apIndex, BOOL *enable)
18731{
developera3511852023-06-14 14:12:59 +080018732 char output[16]={'\0'};
18733 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080018734 int res;
developer72fb0bb2023-01-11 09:46:29 +080018735
developera3511852023-06-14 14:12:59 +080018736 if (!enable)
18737 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018738
developer75bd10c2023-06-27 11:34:08 +080018739 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
18740 if (os_snprintf_error(sizeof(config_file), res)) {
18741 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18742 return RETURN_ERR;
18743 }
developera3511852023-06-14 14:12:59 +080018744 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080018745
developera3511852023-06-14 14:12:59 +080018746 if (strlen(output) == 0)
18747 *enable = FALSE;
18748 else if (strncmp(output, "1", 1) == 0)
18749 *enable = TRUE;
18750 else
18751 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018752
developera3511852023-06-14 14:12:59 +080018753 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
18754 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018755}
18756
18757INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
18758{
developera3511852023-06-14 14:12:59 +080018759 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
18760 return RETURN_ERR;
18761 *output_enable=TRUE;
18762 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018763}
18764
18765INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
18766{
developera3511852023-06-14 14:12:59 +080018767 char cmd[128] = {0};
18768 char buf[128] = {0};
18769 char line[128] = {0};
18770 FILE *f = NULL;
18771 int index = 0;
18772 int exp = 0;
18773 int mantissa = 0;
18774 int duration = 0;
18775 int radio_index = 0;
18776 int max_radio_num = 0;
18777 uint twt_wake_interval = 0;
18778 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +080018779 int res;
18780
developera3511852023-06-14 14:12:59 +080018781 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018782
developera3511852023-06-14 14:12:59 +080018783 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080018784 if(max_radio_num == 0){
18785 return RETURN_ERR;
18786 }
developera3511852023-06-14 14:12:59 +080018787 radio_index = ap_index % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +080018788
developera3511852023-06-14 14:12:59 +080018789 phyId = radio_index_to_phy(radio_index);
developer75bd10c2023-06-27 11:34:08 +080018790
18791 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
18792 if (os_snprintf_error(sizeof(cmd), res)) {
18793 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18794 return RETURN_ERR;
18795 }
developera3511852023-06-14 14:12:59 +080018796 _syscmd(cmd, buf, sizeof(buf));
18797 *numSessionReturned = strtol(buf, NULL, 10) - 1;
18798 if (*numSessionReturned > maxNumberSessions)
18799 *numSessionReturned = maxNumberSessions;
18800 else if (*numSessionReturned < 1) {
18801 *numSessionReturned = 0;
18802 return RETURN_OK;
18803 }
developer72fb0bb2023-01-11 09:46:29 +080018804
developer75bd10c2023-06-27 11:34:08 +080018805 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
18806 if (os_snprintf_error(sizeof(cmd), res)) {
18807 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18808 return RETURN_ERR;
18809 }
developera3511852023-06-14 14:12:59 +080018810 if ((f = popen(cmd, "r")) == NULL) {
18811 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
18812 return RETURN_ERR;
18813 }
developer72fb0bb2023-01-11 09:46:29 +080018814
developera3511852023-06-14 14:12:59 +080018815 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
18816 while((fgets(line, sizeof(line), f)) != NULL) {
18817 char *tmp = NULL;
developer9ce44382023-06-28 11:09:37 +080018818 size_t len = strlen(line);
18819 strncpy(buf, line,len);
18820 buf[len] = '\0';
developera3511852023-06-14 14:12:59 +080018821 tmp = strtok(buf, " ");
18822 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
18823 tmp = strtok(NULL, " ");
18824 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
18825 tmp = strtok(NULL, " ");
18826 if (strstr(tmp, "t")) {
18827 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
18828 }
18829 if (strstr(tmp, "a")) {
18830 twtSessions[index].twtParameters.operation.announced = TRUE;
18831 }
18832 tmp = strtok(NULL, " ");
18833 exp = strtol(tmp, NULL, 10);
18834 tmp = strtok(NULL, " ");
18835 mantissa = strtol(tmp, NULL, 10);
18836 tmp = strtok(NULL, " ");
18837 duration = strtol(tmp, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080018838
developera3511852023-06-14 14:12:59 +080018839 // only implicit supported
18840 twtSessions[index].twtParameters.operation.implicit = TRUE;
18841 // only individual agreement supported
18842 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
developer72fb0bb2023-01-11 09:46:29 +080018843
developera3511852023-06-14 14:12:59 +080018844 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
18845 twt_wake_interval = mantissa * (1 << exp);
18846 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
18847 // Overflow handling
18848 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
18849 } else {
18850 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
18851 }
18852 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
18853 index++;
18854 }
developer72fb0bb2023-01-11 09:46:29 +080018855
developera3511852023-06-14 14:12:59 +080018856 pclose(f);
18857 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18858 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018859}
developercc5cbfb2023-06-13 18:29:52 +080018860
18861INT wifi_enableGreylistAccessControl(BOOL enable)
18862{
18863 char inf_name[IFNAMSIZ] = {0};
18864 int if_idx, ret = 0;
18865 struct nl_msg *msg = NULL;
18866 struct nlattr * msg_data = NULL;
18867 struct mtk_nl80211_param param;
18868 struct unl unl_ins;
18869 unsigned short apIndex = 0;
18870
18871 for (apIndex = 0; apIndex < MAX_APS; apIndex++) {
18872 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
18873 continue;
18874
18875 if_idx = if_nametoindex(inf_name);
18876 if (!if_idx) {
18877 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
18878 continue;
18879 }
18880
18881 /*init mtk nl80211 vendor cmd*/
18882 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
18883 param.if_type = NL80211_ATTR_IFINDEX;
18884 param.if_idx = if_idx;
18885 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
18886 if (ret) {
18887 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
18888 return RETURN_ERR;
18889 }
18890
18891 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, enable == FALSE ? 0 : 1)) {
18892 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
18893 nlmsg_free(msg);
18894 mtk_nl80211_deint(&unl_ins);
18895 continue;
18896 }
18897
18898 /*send mtk nl80211 vendor msg*/
18899 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
18900 if (ret) {
18901 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
18902 mtk_nl80211_deint(&unl_ins);
18903 continue;
18904 }
18905 /*deinit mtk nl80211 vendor msg*/
18906 mtk_nl80211_deint(&unl_ins);
18907 wifi_debug(DEBUG_NOTICE, " %s cmd success.\n", inf_name);
18908 }
18909
18910 return RETURN_OK;
18911}