blob: 95c3be0fb86a96e0708720db7d47092c58200bcc [file] [log] [blame]
developer72fb0bb2023-01-11 09:46:29 +08001/*
2 * If not stated otherwise in this file or this component's LICENSE file the
3 * following copyright and licenses apply:
4 *
5 * Copyright 2019 RDK Management
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18*/
19
20/*
21* Material from the TR181 data model is Copyright (c) 2010-2017, Broadband Forum
22* Licensed under the BSD-3 license
23*/
24
25/*
26* This file includes material that is Copyright (c) 2020, Plume Design Inc.
27* Licensed under the BSD-3 license
28*/
29
30/* Code in rxStatsInfo_callback and other callbacks is credited as follows:
developera3511852023-06-14 14:12:59 +080031Copyright (c) 2007, 2008 Johannes Berg
32Copyright (c) 2007 Andy Lutomirski
33Copyright (c) 2007 Mike Kershaw
34Copyright (c) 2008-2009 Luis R. Rodriguez
developer72fb0bb2023-01-11 09:46:29 +080035Licensed under the ISC license
36*/
37#define MTK_IMPL
38#define HAL_NETLINK_IMPL
39#define _GNU_SOURCE /* needed for strcasestr */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44#include <string.h>
45#include <fcntl.h>
46#include <stdbool.h>
47#include "wifi_hal.h"
48
49#ifdef HAL_NETLINK_IMPL
50#include <errno.h>
51#include <netlink/attr.h>
52#include <netlink/netlink.h>
53#include <netlink/genl/genl.h>
54#include <netlink/genl/family.h>
55#include <netlink/genl/ctrl.h>
56#include <linux/nl80211.h>
developer8dd72532023-05-17 19:58:35 +080057#include <net/if.h>
58#include <unl.h>
59#include "mtk_vendor_nl80211.h"
developer72fb0bb2023-01-11 09:46:29 +080060#endif
61
62#include <ev.h>
63#include <wpa_ctrl.h>
64#include <errno.h>
65#include <time.h>
developercc5cbfb2023-06-13 18:29:52 +080066
67#include <sys/socket.h>
68#include <sys/ioctl.h>
69#include <arpa/inet.h>
70#include <linux/if.h>
71#include <linux/if_bridge.h>
72#include <linux/sockios.h>
developer86035662023-06-28 19:21:12 +080073#include <errno.h>
74#include <limits.h>
developercc5cbfb2023-06-13 18:29:52 +080075
developer72fb0bb2023-01-11 09:46:29 +080076#define MAC_ALEN 6
77
78#define MAX_BUF_SIZE 256
79#define MAX_CMD_SIZE 256
developerb149d9d2023-06-06 16:14:22 +080080#define MAX_SUB_CMD_SIZE 200
81
developer72fb0bb2023-01-11 09:46:29 +080082#define IF_NAME_SIZE 16
83#define CONFIG_PREFIX "/nvram/hostapd"
84#define ACL_PREFIX "/nvram/hostapd-acl"
85#define DENY_PREFIX "/nvram/hostapd-deny"
86//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
87#define SOCK_PREFIX "/var/run/hostapd/wifi"
88#define VAP_STATUS_FILE "/nvram/vap-status"
89#define ESSID_FILE "/tmp/essid"
90#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
91#define CHANNEL_STATS_FILE "/tmp/channel_stats"
92#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
93#define VLAN_FILE "/nvram/hostapd.vlan"
94#define PSK_FILE "/nvram/hostapd"
95#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080096#define POWER_PERCENTAGE "/tmp/POWER"
97#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
98/*LOGAN_DAT_FILE: may be different on customer's platform.*/
99#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +0800100#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +0800101
developer72fb0bb2023-01-11 09:46:29 +0800102#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +0800103#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +0800104
developer72fb0bb2023-01-11 09:46:29 +0800105#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +0800106#define BASE_PHY_INDEX 1
107#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +0800108
109/*
110 MAX_APS - Number of all AP available in system
111 2x Home AP
112 2x Backhaul AP
113 2x Guest AP
114 2x Secure Onboard AP
115 2x Service AP
116
117*/
118
119
120#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800121
122#define PREFIX_WIFI2G "ra"
123#define PREFIX_WIFI5G "rai"
124#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800125
developer47cc27a2023-05-17 23:09:58 +0800126#define PREFIX_SSID_2G "RDKB_2G"
127#define PREFIX_SSID_5G "RDKB_5G"
128#define PREFIX_SSID_6G "RDKB_6G"
129
developer72fb0bb2023-01-11 09:46:29 +0800130#ifndef RADIO_PREFIX
131#define RADIO_PREFIX "wlan"
132#endif
133
134#define MAX_ASSOCIATED_STA_NUM 2007
135
136//Uncomment to enable debug logs
137//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800138enum {
139 DEBUG_OFF = 0,
140 DEBUG_ERROR = 1,
141 DEBUG_WARN = 2,
142 DEBUG_NOTICE = 3,
143 DEBUG_INFO = 4
144};
145int wifi_debug_level = DEBUG_NOTICE;
146#define wifi_debug(level, fmt, args...) \
147{ \
148 if (level <= wifi_debug_level) \
149 { \
developer2edaf012023-05-24 14:24:53 +0800150 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800151 } \
152}
developer72fb0bb2023-01-11 09:46:29 +0800153
154#ifdef WIFI_DEBUG
155#define wifi_dbg_printf printf
156#define WIFI_ENTRY_EXIT_DEBUG printf
157#else
developer2f79c922023-06-02 17:33:42 +0800158#define wifi_dbg_printf(format, args...)
159#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
developer72fb0bb2023-01-11 09:46:29 +0800160#endif
161
162#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
163#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
164#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
165#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
166#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
167#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
168#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
169#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
170#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
171#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
172
173#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
174
175#define BW_FNAME "/nvram/bw_file.txt"
176
177#define PS_MAX_TID 16
178
developer96b38512023-02-22 11:17:45 +0800179#define MAX_CARD_INDEX 3
180
developer72fb0bb2023-01-11 09:46:29 +0800181static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
developera3511852023-06-14 14:12:59 +0800182 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
183 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
184 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
185 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
186 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
187 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
188 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
189 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
190 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
191 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
192 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
193 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
194 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
195 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
196 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
197 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
developer72fb0bb2023-01-11 09:46:29 +0800198};
199
200typedef unsigned long long u64;
201
202/* Enum to define WiFi Bands */
203typedef enum
204{
developera3511852023-06-14 14:12:59 +0800205 band_invalid = -1,
206 band_2_4 = 0,
207 band_5 = 1,
208 band_6 = 2,
developer72fb0bb2023-01-11 09:46:29 +0800209} wifi_band;
210
developer17038e62023-03-02 14:43:43 +0800211char* wifi_band_str[] = {
developera3511852023-06-14 14:12:59 +0800212 "2G",
213 "5G",
214 "6G",
developer17038e62023-03-02 14:43:43 +0800215};
216
developer72fb0bb2023-01-11 09:46:29 +0800217typedef enum {
developera3511852023-06-14 14:12:59 +0800218 WIFI_MODE_A = 0x01,
219 WIFI_MODE_B = 0x02,
220 WIFI_MODE_G = 0x04,
221 WIFI_MODE_N = 0x08,
222 WIFI_MODE_AC = 0x10,
223 WIFI_MODE_AX = 0x20,
224 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800225} wifi_ieee80211_Mode;
226
developer2f79c922023-06-02 17:33:42 +0800227typedef enum {
developera3511852023-06-14 14:12:59 +0800228 HT_BW_20,
229 HT_BW_40,
developer2f79c922023-06-02 17:33:42 +0800230} ht_config_bw;
developerd1824452023-05-18 12:30:04 +0800231
developer2f79c922023-06-02 17:33:42 +0800232typedef enum {
developera3511852023-06-14 14:12:59 +0800233 VHT_BW_2040,
234 VHT_BW_80,
235 VHT_BW_160,
236 VHT_BW_8080,
developer2f79c922023-06-02 17:33:42 +0800237} vht_config_bw;
developerd1824452023-05-18 12:30:04 +0800238
developer2f79c922023-06-02 17:33:42 +0800239typedef enum {
developera3511852023-06-14 14:12:59 +0800240 EHT_BW_20,
241 EHT_BW_40,
242 EHT_BW_80,
243 EHT_BW_160,
244 EHT_BW_320,
developer2f79c922023-06-02 17:33:42 +0800245} eht_config_bw;
developerd1824452023-05-18 12:30:04 +0800246
developer72fb0bb2023-01-11 09:46:29 +0800247#ifdef WIFI_HAL_VERSION_3
248
249// Return number of elements in array
250#ifndef ARRAY_SIZE
developera3511852023-06-14 14:12:59 +0800251#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
developer72fb0bb2023-01-11 09:46:29 +0800252#endif /* ARRAY_SIZE */
253
254#ifndef ARRAY_AND_SIZE
developera3511852023-06-14 14:12:59 +0800255#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
developer72fb0bb2023-01-11 09:46:29 +0800256#endif /* ARRAY_AND_SIZE */
257
developera3511852023-06-14 14:12:59 +0800258#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
developer72fb0bb2023-01-11 09:46:29 +0800259
260typedef struct {
developera3511852023-06-14 14:12:59 +0800261 int32_t value;
262 int32_t param;
263 intptr_t key;
264 intptr_t data;
developer72fb0bb2023-01-11 09:46:29 +0800265} wifi_secur_list;
266
developer0155a502023-06-19 20:33:57 +0800267typedef struct GNU_PACKED _wdev_extended_ap_metrics {
268 unsigned int uc_tx;
269 unsigned int uc_rx;
270 unsigned int mc_tx;
271 unsigned int mc_rx;
272 unsigned int bc_tx;
273 unsigned int bc_rx;
274} wdev_extended_ap_metric;
275
276typedef struct GNU_PACKED _wdev_ap_metric {
277 unsigned char bssid[6];
278 unsigned char cu;
279 unsigned char ESPI_AC[4][3];
280 wdev_extended_ap_metric ext_ap_metric;
281} wdev_ap_metric;
282
283
developer72fb0bb2023-01-11 09:46:29 +0800284static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
285static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
developera3511852023-06-14 14:12:59 +0800286wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
287wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
288char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
developer72fb0bb2023-01-11 09:46:29 +0800289static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developerd14dff12023-06-28 22:47:44 +0800290static void wifi_PrepareDefaultHostapdConfigs(bool reset);
developer47cc27a2023-05-17 23:09:58 +0800291static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800292static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800293static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer2f79c922023-06-02 17:33:42 +0800294int hostapd_raw_add_bss(int apIndex);
295int hostapd_raw_remove_bss(int apIndex);
developerd14dff12023-06-28 22:47:44 +0800296INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size);
297
developer86035662023-06-28 19:21:12 +0800298static inline int hal_strtol(char *src, int base, long int *out)
299{
300 long int res = 0;
301 char *end_ptr = NULL;
302
303 errno = 0;
304 res = strtol(src, &end_ptr, base);
305
306 if ((errno == ERANGE && (res == LONG_MIN || res == LONG_MAX))
307 || (errno != 0 && res == 0) || *end_ptr != '\0' || src == end_ptr )
308 return -1;
309 else
310 *out = res;
311
312 return 0;
313}
314
315static inline int hal_strtoul(char *src, int base, unsigned long *out)
316{
317 unsigned long res = 0;
318 char *end_ptr = NULL;
319
320 errno = 0;
321 res = strtoul(src, &end_ptr, base);
322
323 if ((errno == ERANGE && res == ULONG_MAX)
324 || (errno != 0 && res == 0) || *end_ptr != '\0' || src == end_ptr )
325 return -1;
326 else
327 *out = res;
328
329 return 0;
330}
developer47cc27a2023-05-17 23:09:58 +0800331
developercc5cbfb2023-06-13 18:29:52 +0800332static inline int os_snprintf_error(size_t size, int res)
333{
334 return res < 0 || (unsigned int) res >= size;
335}
336
developer49b17232023-05-19 16:35:19 +0800337/*type define the nl80211 call back func*/
338typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
339
340/**
341*struct mtk_nl80211_param
342* init mtk nl80211 using parameters
343* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
344* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
345* @if_idx: the index should match the interface or wiphy.
346* Note: NA
347**/
348struct mtk_nl80211_param {
349 unsigned int sub_cmd;
350 int if_type;
351 int if_idx;
352};
353
354/**
developer121a8e72023-05-22 09:19:39 +0800355*struct mtk_nl80211_cb_data
356* init mtk nl80211 call back parameters
357* @out_buf: store the mtk vendor output msg for wifi hal buffer.
358* @out_len: the output buffer length.
359* Note: NA
360**/
361struct mtk_nl80211_cb_data {
362 char * out_buf;
363 unsigned int out_len;
364};
365
366/**
developer49b17232023-05-19 16:35:19 +0800367*mtk_nl80211_init
368* init mtk nl80211 netlink and init the vendor msg common part.
369* @nl: netlink, just init it.
370* @msg: netlink message will alloc it.
371* the msg send success/fails is not free by app
372* only the nla_put etc api fails should use nlmsg_free.
373* @msg_data: vendor data msg attr pointer.
374* @param: init using interface and sub_cmd parameter.
375*
376*init the netlink context and mtk netlink vendor msg.
377*
378*return:
379* 0: success
380* other: fail
381**/
382
383int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
384 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
385 /*sanity check here*/
386 if (!nl || !param) {
387 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800388 "[%s][%d]:nl(%p) or param(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800389 __func__, __LINE__, nl, param);
390 return -1;
391 }
392 /*if_type check*/
393 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
394 (void)fprintf(stderr,
395 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
396 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
397 return -1;
398 }
399 /*init the nl*/
400 if (unl_genl_init(nl, "nl80211") < 0) {
401 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
402 __func__, __LINE__);
403 return -1;
404 }
405 /*init the msg*/
406 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
407
408 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
developera3511852023-06-14 14:12:59 +0800409 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
410 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
developer49b17232023-05-19 16:35:19 +0800411 (void)fprintf(stderr,
412 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
413 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
414 goto err;
415 }
416
417 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
418 if (!*msg_data) {
419 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
420 __func__, __LINE__);
421 goto err;
422 }
423
424 return 0;
425err:
developer49b17232023-05-19 16:35:19 +0800426 nlmsg_free(*msg);
427 unl_free(nl);
428 return -1;
429}
430
431/**
432*mtk_nl80211_send
433* set the vendor cmd call back and sent the vendor msg.
434* @nl: netlink.
435* @msg: netlink message.
436* @msg_data: vendor data msg attr pointer.
437* @handler: if the msg have call back shoud add the call back func
438* the event msg will handle by the call back func(exp:get cmd)
439* other set it as NULL(exp:set cmd).
440* @arg:call back func arg parameter.
441*add end of the netlink msg, set the call back and send msg
442*
443*return:
444* 0: success
445* other: fail
446**/
447int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
448 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
449 int ret = 0;
450 /*sanity check*/
451 if (!nl || !msg || !msg_data) {
452 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800453 "[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800454 __func__, __LINE__, nl, msg, msg_data);
455 return -1;
456 }
457 /*end the msg attr of vendor data*/
458 nla_nest_end(msg, msg_data);
459 /*send the msg and set call back */
460 ret = unl_genl_request(nl, msg, handler, arg);
461 if (ret)
462 (void)fprintf(stderr, "send nl80211 cmd fails\n");
463 return ret;
464}
465
466/**
467*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800468* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800469* @nl: netlink.
470*
developer2edaf012023-05-24 14:24:53 +0800471*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800472*
473*return:
474* 0: success
475**/
476
477int mtk_nl80211_deint(struct unl *nl) {
478 unl_free(nl);
479 return 0;
480}
481
developer72fb0bb2023-01-11 09:46:29 +0800482wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
483{
developera3511852023-06-14 14:12:59 +0800484 wifi_secur_list *item;
485 int i;
developer72fb0bb2023-01-11 09:46:29 +0800486
developera3511852023-06-14 14:12:59 +0800487 for (item = list,i = 0;i < list_sz; item++, i++) {
488 if ((int)(item->key) == key) {
489 return item;
490 }
491 }
developer72fb0bb2023-01-11 09:46:29 +0800492
developera3511852023-06-14 14:12:59 +0800493 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800494}
495
496char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
497{
developera3511852023-06-14 14:12:59 +0800498 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
developer72fb0bb2023-01-11 09:46:29 +0800499
developera3511852023-06-14 14:12:59 +0800500 if (!item) {
501 return "";
502 }
developer72fb0bb2023-01-11 09:46:29 +0800503
developera3511852023-06-14 14:12:59 +0800504 return (char *)(item->data);
developer72fb0bb2023-01-11 09:46:29 +0800505}
506
507wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
508{
developera3511852023-06-14 14:12:59 +0800509 wifi_secur_list *item;
510 int i;
developer72fb0bb2023-01-11 09:46:29 +0800511
developera3511852023-06-14 14:12:59 +0800512 for (item = list,i = 0;i < list_sz; item++, i++) {
513 if (strcmp((char *)(item->data), str) == 0) {
514 return item;
515 }
516 }
developer72fb0bb2023-01-11 09:46:29 +0800517
developera3511852023-06-14 14:12:59 +0800518 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800519}
520#endif /* WIFI_HAL_VERSION_3 */
521
developer96b38512023-02-22 11:17:45 +0800522
523static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800524char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
525char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
526#define MAX_SSID_LEN 64
527char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800528int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800529
530static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
531static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
532
developer96b38512023-02-22 11:17:45 +0800533
534static int
535get_value(const char *conf_file, const char *param, char *value, int len)
536{
developera3511852023-06-14 14:12:59 +0800537 FILE *fp;
538 int ret = -1;
539 int param_len = strlen(param);
540 int buf_len;
developer86035662023-06-28 19:21:12 +0800541 char buf[256] = {0};
developer96b38512023-02-22 11:17:45 +0800542
developera3511852023-06-14 14:12:59 +0800543 fp = fopen(conf_file, "r");
544 if (!fp) {
545 return -1;
546 }
developer96b38512023-02-22 11:17:45 +0800547
developera3511852023-06-14 14:12:59 +0800548 while (fgets(buf, sizeof(buf), fp)) {
549 buf_len = strlen(buf);
developer86035662023-06-28 19:21:12 +0800550 if (buf_len == 0) {
551 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
552 fclose(fp);
553 return RETURN_ERR;
554 }
developera3511852023-06-14 14:12:59 +0800555 if (buf[buf_len - 1] == '\n') {
556 buf_len--;
557 buf[buf_len] = '\0';
558 }
559 if ((buf_len > param_len) &&
560 (strncmp(buf, param, param_len) == 0) &&
561 (buf[param_len] == '=')) {
developer96b38512023-02-22 11:17:45 +0800562
developera3511852023-06-14 14:12:59 +0800563 if (buf_len == (param_len + 1)) {
564 value[0] = '\0';
565 ret = 0;
566 } else {
567 ret = snprintf(value, len, "%s", buf + (param_len + 1));
developer75bd10c2023-06-27 11:34:08 +0800568 if (os_snprintf_error(len, ret)) {
569 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
570 }
developera3511852023-06-14 14:12:59 +0800571 }
developerd14dff12023-06-28 22:47:44 +0800572 if (fclose(fp) != 0) {
573 ret = -1;
574 wifi_debug(DEBUG_ERROR, "fclose fail\n");
575 }
developera3511852023-06-14 14:12:59 +0800576 return ret;
577 }
578 }
developer37646972023-06-29 10:58:43 +0800579 if (fclose(fp) == EOF){
580 wifi_debug(DEBUG_ERROR, "fclose fail\n");
581 return RETURN_ERR;
582 }
developera3511852023-06-14 14:12:59 +0800583 return -1;
developer96b38512023-02-22 11:17:45 +0800584}
585
586static int
587get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
588{
developera3511852023-06-14 14:12:59 +0800589 char buf[256];
590 int ret;
591 char *save_ptr = NULL;
592 char *tok = NULL;
developer96b38512023-02-22 11:17:45 +0800593
developera3511852023-06-14 14:12:59 +0800594 ret = get_value(conf_file, param, buf, sizeof(buf));
595 if (ret < 0)
596 return ret;
developer96b38512023-02-22 11:17:45 +0800597
developera3511852023-06-14 14:12:59 +0800598 tok = strtok_r(buf, ";", &save_ptr);
599 do {
600 if (idx == 0 || tok == NULL)
601 break;
602 else
603 idx--;
developer96b38512023-02-22 11:17:45 +0800604
developera3511852023-06-14 14:12:59 +0800605 tok = strtok_r(NULL, ";", &save_ptr);
606 } while (tok != NULL);
developer96b38512023-02-22 11:17:45 +0800607
developera3511852023-06-14 14:12:59 +0800608 if (tok) {
609 ret = snprintf(value, len, "%s", tok);
developer75bd10c2023-06-27 11:34:08 +0800610 if (os_snprintf_error(len, ret)) {
611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
612 return -1;
613 }
developera3511852023-06-14 14:12:59 +0800614 } else {
615 ret = 0;
616 value[0] = '\0';
617 }
developer96b38512023-02-22 11:17:45 +0800618
developera3511852023-06-14 14:12:59 +0800619 return ret;
developer96b38512023-02-22 11:17:45 +0800620}
621
622
developer72fb0bb2023-01-11 09:46:29 +0800623#ifdef HAL_NETLINK_IMPL
624typedef struct {
developera3511852023-06-14 14:12:59 +0800625 int id;
626 struct nl_sock* socket;
627 struct nl_cb* cb;
developer72fb0bb2023-01-11 09:46:29 +0800628} Netlink;
629
630static int mac_addr_aton(unsigned char *mac_addr, char *arg)
631{
developera3511852023-06-14 14:12:59 +0800632 unsigned char mac_addr_int[6]={};
developer75bd10c2023-06-27 11:34:08 +0800633 unsigned int recv;
634
635 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);
636
637 if (recv != 6) {
638 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
639 return -1;
640 }
developera3511852023-06-14 14:12:59 +0800641 mac_addr[0] = mac_addr_int[0];
642 mac_addr[1] = mac_addr_int[1];
643 mac_addr[2] = mac_addr_int[2];
644 mac_addr[3] = mac_addr_int[3];
645 mac_addr[4] = mac_addr_int[4];
646 mac_addr[5] = mac_addr_int[5];
647 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800648}
649
650static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
651{
developera3511852023-06-14 14:12:59 +0800652 unsigned int mac_addr_int[6]={};
developere40952c2023-06-15 18:46:43 +0800653 int res;
654
developera3511852023-06-14 14:12:59 +0800655 mac_addr_int[0] = arg[0];
656 mac_addr_int[1] = arg[1];
657 mac_addr_int[2] = arg[2];
658 mac_addr_int[3] = arg[3];
659 mac_addr_int[4] = arg[4];
660 mac_addr_int[5] = arg[5];
developere40952c2023-06-15 18:46:43 +0800661 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]);
662 if (os_snprintf_error(20, res)) {
663 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
664 }
developera3511852023-06-14 14:12:59 +0800665 return;
developer72fb0bb2023-01-11 09:46:29 +0800666}
667
668static int ieee80211_frequency_to_channel(int freq)
669{
developera3511852023-06-14 14:12:59 +0800670 /* see 802.11-2007 17.3.8.3.2 and Annex J */
671 if (freq == 2484)
672 return 14;
673 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
674 else if (freq == 5935)
675 return 2;
676 else if (freq < 2484)
677 return (freq - 2407) / 5;
678 else if (freq >= 4910 && freq <= 4980)
679 return (freq - 4000) / 5;
680 else if (freq < 5950)
681 return (freq - 5000) / 5;
682 else if (freq <= 45000) /* DMG band lower limit */
683 /* see 802.11ax D6.1 27.3.23.2 */
684 return (freq - 5950) / 5;
685 else if (freq >= 58320 && freq <= 70200)
686 return (freq - 56160) / 2160;
687 else
688 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800689}
690
691static int initSock80211(Netlink* nl) {
developera3511852023-06-14 14:12:59 +0800692 nl->socket = nl_socket_alloc();
693 if (!nl->socket) {
developer75bd10c2023-06-27 11:34:08 +0800694 wifi_debug(DEBUG_ERROR, "Failing to allocate the sock\n");
developera3511852023-06-14 14:12:59 +0800695 return -ENOMEM;
696 }
developer72fb0bb2023-01-11 09:46:29 +0800697
developera3511852023-06-14 14:12:59 +0800698 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
developer72fb0bb2023-01-11 09:46:29 +0800699
developera3511852023-06-14 14:12:59 +0800700 if (genl_connect(nl->socket)) {
developer75bd10c2023-06-27 11:34:08 +0800701 wifi_debug(DEBUG_ERROR, "Failed to connect\n");
developera3511852023-06-14 14:12:59 +0800702 nl_close(nl->socket);
703 nl_socket_free(nl->socket);
704 return -ENOLINK;
705 }
developer72fb0bb2023-01-11 09:46:29 +0800706
developera3511852023-06-14 14:12:59 +0800707 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
708 if (nl->id< 0) {
developer75bd10c2023-06-27 11:34:08 +0800709 wifi_debug(DEBUG_ERROR, "interface not found.\n");
developera3511852023-06-14 14:12:59 +0800710 nl_close(nl->socket);
711 nl_socket_free(nl->socket);
712 return -ENOENT;
713 }
developer72fb0bb2023-01-11 09:46:29 +0800714
developera3511852023-06-14 14:12:59 +0800715 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
716 if ((!nl->cb)) {
developer75bd10c2023-06-27 11:34:08 +0800717 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink callback.\n");
developera3511852023-06-14 14:12:59 +0800718 nl_close(nl->socket);
719 nl_socket_free(nl->socket);
720 return ENOMEM;
721 }
developer72fb0bb2023-01-11 09:46:29 +0800722
developera3511852023-06-14 14:12:59 +0800723 return nl->id;
developer72fb0bb2023-01-11 09:46:29 +0800724}
725
726static int nlfree(Netlink *nl)
727{
developera3511852023-06-14 14:12:59 +0800728 nl_cb_put(nl->cb);
729 nl_close(nl->socket);
730 nl_socket_free(nl->socket);
731 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800732}
733
734static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
developera3511852023-06-14 14:12:59 +0800735 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
736 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
737 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
developer72fb0bb2023-01-11 09:46:29 +0800738};
739
740static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
741};
742
743static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
744};
745
746typedef struct _wifi_channelStats_loc {
developera3511852023-06-14 14:12:59 +0800747 INT array_size;
748 INT ch_number;
749 BOOL ch_in_pool;
750 INT ch_noise;
751 BOOL ch_radar_noise;
752 INT ch_max_80211_rssi;
753 INT ch_non_80211_noise;
754 INT ch_utilization;
755 ULLONG ch_utilization_total;
756 ULLONG ch_utilization_busy;
757 ULLONG ch_utilization_busy_tx;
758 ULLONG ch_utilization_busy_rx;
759 ULLONG ch_utilization_busy_self;
760 ULLONG ch_utilization_busy_ext;
developer72fb0bb2023-01-11 09:46:29 +0800761} wifi_channelStats_t_loc;
762
763typedef struct wifi_device_info {
developera3511852023-06-14 14:12:59 +0800764 INT wifi_devIndex;
765 UCHAR wifi_devMacAddress[6];
766 CHAR wifi_devIPAddress[64];
767 BOOL wifi_devAssociatedDeviceAuthentiationState;
768 INT wifi_devSignalStrength;
769 INT wifi_devTxRate;
770 INT wifi_devRxRate;
developer72fb0bb2023-01-11 09:46:29 +0800771} wifi_device_info_t;
772
773#endif
774
775//For 5g Alias Interfaces
developer72fb0bb2023-01-11 09:46:29 +0800776static BOOL Radio_flag = TRUE;
777//wifi_setApBeaconRate(1, beaconRate);
778
779BOOL multiple_set = FALSE;
780
781struct params
782{
developera3511852023-06-14 14:12:59 +0800783 char * name;
784 char * value;
developer72fb0bb2023-01-11 09:46:29 +0800785};
786
787static int _syscmd(char *cmd, char *retBuf, int retBufSize)
788{
developera3511852023-06-14 14:12:59 +0800789 FILE *f;
790 char *ptr = retBuf;
791 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
developer72fb0bb2023-01-11 09:46:29 +0800792
developera3511852023-06-14 14:12:59 +0800793 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
794 if((f = popen(cmd, "r")) == NULL) {
developer75bd10c2023-06-27 11:34:08 +0800795 wifi_debug(DEBUG_ERROR, "\npopen %s error\n", cmd);
developera3511852023-06-14 14:12:59 +0800796 return RETURN_ERR;
797 }
developer72fb0bb2023-01-11 09:46:29 +0800798
developera3511852023-06-14 14:12:59 +0800799 while(!feof(f))
800 {
801 *ptr = 0;
802 if(bufSize>=128) {
803 bufbytes=128;
804 } else {
805 bufbytes=bufSize-1;
806 }
developer72fb0bb2023-01-11 09:46:29 +0800807
developerd14dff12023-06-28 22:47:44 +0800808 if (fgets(ptr,bufbytes,f) == NULL)
809 break;
developera3511852023-06-14 14:12:59 +0800810 readbytes=strlen(ptr);
developer72fb0bb2023-01-11 09:46:29 +0800811
developera3511852023-06-14 14:12:59 +0800812 if(!readbytes)
813 break;
developer72fb0bb2023-01-11 09:46:29 +0800814
developera3511852023-06-14 14:12:59 +0800815 bufSize-=readbytes;
816 ptr += readbytes;
817 }
818 cmd_ret = pclose(f);
819 retBuf[retBufSize-1]=0;
820 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800821
developera3511852023-06-14 14:12:59 +0800822 return cmd_ret >> 8;
developer72fb0bb2023-01-11 09:46:29 +0800823}
824
825INT radio_index_to_phy(int radioIndex)
826{
developera3511852023-06-14 14:12:59 +0800827 /* TODO */
828 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800829}
830
831INT wifi_getMaxRadioNumber(INT *max_radio_num)
832{
developera3511852023-06-14 14:12:59 +0800833 char cmd[64] = {0};
834 char buf[4] = {0};
developere40952c2023-06-15 18:46:43 +0800835 int res;
developera3511852023-06-14 14:12:59 +0800836 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800837
developere40952c2023-06-15 18:46:43 +0800838 res = snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
839 if (os_snprintf_error(sizeof(cmd), res)) {
840 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
841 return RETURN_ERR;
842 }
developera3511852023-06-14 14:12:59 +0800843 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +0800844 res = strtoul(buf, NULL, 10);
845 if (res == 0 && buf[0] != '0') {
846 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
847 return RETURN_ERR;
848 }
849
850 *max_radio_num = res > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:res;
developer72fb0bb2023-01-11 09:46:29 +0800851
developera3511852023-06-14 14:12:59 +0800852 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800853
developera3511852023-06-14 14:12:59 +0800854 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +0800855}
856
developer17038e62023-03-02 14:43:43 +0800857wifi_band radio_index_to_band(int radioIndex)
858{
developera3511852023-06-14 14:12:59 +0800859 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800860}
861
developer72fb0bb2023-01-11 09:46:29 +0800862wifi_band wifi_index_to_band(int apIndex)
863{
developera3511852023-06-14 14:12:59 +0800864 char cmd[128] = {0};
865 char buf[64] = {0};
866 int nl80211_band = 0;
867 int i = 0;
868 int phyIndex = 0;
869 int radioIndex = 0;
870 int max_radio_num = 0;
871 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +0800872 int res;
developer72fb0bb2023-01-11 09:46:29 +0800873
developera3511852023-06-14 14:12:59 +0800874 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800875
developera3511852023-06-14 14:12:59 +0800876 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +0800877 if(max_radio_num == 0){
878 return RETURN_ERR;
879 }
developera3511852023-06-14 14:12:59 +0800880 radioIndex = apIndex % max_radio_num;
881 phyIndex = radio_index_to_phy(radioIndex);
882 while(i < 10){
developere40952c2023-06-15 18:46:43 +0800883 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
884 if (os_snprintf_error(sizeof(cmd), res)) {
885 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
886 }
developera3511852023-06-14 14:12:59 +0800887 _syscmd(cmd, buf, sizeof(buf));
888 nl80211_band = strtol(buf, NULL, 10);
889 if (nl80211_band == 1)
890 band = band_2_4;
891 else if (nl80211_band == 2)
892 band = band_5;
893 else if (nl80211_band == 4) // band == 3 is 60GHz
894 band = band_6;
developer72fb0bb2023-01-11 09:46:29 +0800895
developera3511852023-06-14 14:12:59 +0800896 if(band != band_invalid)
897 break;
developer69b61b02023-03-07 17:17:44 +0800898
developera3511852023-06-14 14:12:59 +0800899 i++;
900 sleep(1);
901 }
developer72fb0bb2023-01-11 09:46:29 +0800902
developera3511852023-06-14 14:12:59 +0800903 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
904 return band;
developer72fb0bb2023-01-11 09:46:29 +0800905}
906
907static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
908{
developer7e4a2a62023-04-06 19:56:03 +0800909 char cmd[MAX_CMD_SIZE] = {0};
910 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800911 int res = 0;
developer72fb0bb2023-01-11 09:46:29 +0800912
developere40952c2023-06-15 18:46:43 +0800913 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 +0800914 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800915
developere40952c2023-06-15 18:46:43 +0800916 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
917 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
918 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +0800919 }
developerb758dfd2023-06-21 17:32:07 +0800920
developere40952c2023-06-15 18:46:43 +0800921 res = _syscmd(cmd, buf, sizeof(buf));
922 if ((res != 0) && (strlen(buf) == 0)) {
developer7e4a2a62023-04-06 19:56:03 +0800923 printf("%s: _syscmd error!", __func__);
924 return -1;
925 }
926
developere40952c2023-06-15 18:46:43 +0800927 res = snprintf(output, output_size, "%s", buf);
928 if (os_snprintf_error(output_size, res)) {
929 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
930 return RETURN_ERR;
931 }
developer7e4a2a62023-04-06 19:56:03 +0800932
933 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800934}
935
936static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
937{
developera3511852023-06-14 14:12:59 +0800938 char cmd[MAX_CMD_SIZE] = {0};
939 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800940 int res;
developer72fb0bb2023-01-11 09:46:29 +0800941
developera3511852023-06-14 14:12:59 +0800942 for (int i = 0; i < item_count; i++) {
943 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
944 if (strlen(buf) == 0) /*no such item, insert it*/
developere40952c2023-06-15 18:46:43 +0800945 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 +0800946 else /*find the item, update it*/
developere40952c2023-06-15 18:46:43 +0800947 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 +0800948
developere40952c2023-06-15 18:46:43 +0800949 if (os_snprintf_error(sizeof(cmd), res)) {
950 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
951 return RETURN_ERR;
952 }
developera3511852023-06-14 14:12:59 +0800953 if(_syscmd(cmd, buf, sizeof(buf)))
954 return -1;
955 }
developer72fb0bb2023-01-11 09:46:29 +0800956
developera3511852023-06-14 14:12:59 +0800957 return 0;
developera1255e42023-05-13 17:45:02 +0800958}
developerfde01262023-05-22 15:15:24 +0800959
developera1255e42023-05-13 17:45:02 +0800960static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
961{
developera3511852023-06-14 14:12:59 +0800962 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800963 int res = 0;
developera3511852023-06-14 14:12:59 +0800964 int len;
developerfde01262023-05-22 15:15:24 +0800965
developere40952c2023-06-15 18:46:43 +0800966 res = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
967 if (os_snprintf_error(sizeof(cmd), res)) {
968 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
969 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800970 }
developerfde01262023-05-22 15:15:24 +0800971
developere40952c2023-06-15 18:46:43 +0800972
973 res = _syscmd(cmd, output, output_size);
974 if ((res != 0) && (strlen(output) == 0)) {
developera3511852023-06-14 14:12:59 +0800975 printf("%s: _syscmd error!", __func__);
976 return -1;
977 }
developera1255e42023-05-13 17:45:02 +0800978
developera3511852023-06-14 14:12:59 +0800979 len = strlen(output);
980 if ((len > 0) && (output[len - 1] == '\n')) {
981 output[len - 1] = '\0';
982 }
developerfde01262023-05-22 15:15:24 +0800983
developera3511852023-06-14 14:12:59 +0800984 return 0;
developerfde01262023-05-22 15:15:24 +0800985}
developera1255e42023-05-13 17:45:02 +0800986
developera1255e42023-05-13 17:45:02 +0800987static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
988{
developere40952c2023-06-15 18:46:43 +0800989 int res;
developera3511852023-06-14 14:12:59 +0800990 char cmd[MAX_CMD_SIZE] = {0};
991 char buf[MAX_BUF_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800992
developera3511852023-06-14 14:12:59 +0800993 for (int i = 0; i < item_count; i++) {
developere40952c2023-06-15 18:46:43 +0800994 res = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
995 if (os_snprintf_error(sizeof(cmd), res)) {
996 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
997 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800998 }
developera1255e42023-05-13 17:45:02 +0800999
developera3511852023-06-14 14:12:59 +08001000 if(_syscmd(cmd, buf, sizeof(buf)))
1001 return -1;
1002 }
developera1255e42023-05-13 17:45:02 +08001003
developera3511852023-06-14 14:12:59 +08001004 return 0;
developera1255e42023-05-13 17:45:02 +08001005}
1006
developerfde01262023-05-22 15:15:24 +08001007static int wifi_l1ProfileRead(char *param, char *output, int output_size)
1008{
developera3511852023-06-14 14:12:59 +08001009 int ret;
developerfde01262023-05-22 15:15:24 +08001010
developera3511852023-06-14 14:12:59 +08001011 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1012 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001013 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001014 return RETURN_ERR;
1015 }
developerfde01262023-05-22 15:15:24 +08001016
developera3511852023-06-14 14:12:59 +08001017 ret = wifi_datfileRead(l1profile, param, output, output_size);
1018 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001019 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, l1profile, ret);
developera3511852023-06-14 14:12:59 +08001020 return RETURN_ERR;
1021 }
developerfde01262023-05-22 15:15:24 +08001022
developera3511852023-06-14 14:12:59 +08001023 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1024 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001025}
1026
1027static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
1028{
developera3511852023-06-14 14:12:59 +08001029 char option[64];
1030 char card_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001031 int res;
developerfde01262023-05-22 15:15:24 +08001032
developera3511852023-06-14 14:12:59 +08001033 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerfde01262023-05-22 15:15:24 +08001034
developera3511852023-06-14 14:12:59 +08001035 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001036 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001037 return RETURN_ERR;
1038 }
developerfde01262023-05-22 15:15:24 +08001039
developere40952c2023-06-15 18:46:43 +08001040 res = snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
1041 if (os_snprintf_error(sizeof(option), res)) {
1042 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +08001043 return RETURN_ERR;
1044 }
developere40952c2023-06-15 18:46:43 +08001045 res = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
1046 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001047 wifi_debug(DEBUG_ERROR, "wifi_l1ProfileRead %s failed, ret:%d", option, res);
developere40952c2023-06-15 18:46:43 +08001048 return RETURN_ERR;
1049 }
developerfde01262023-05-22 15:15:24 +08001050
developere40952c2023-06-15 18:46:43 +08001051 res = wifi_datfileRead(card_profile_path, param, output, output_size);
1052 if (res != 0) {
developer75bd10c2023-06-27 11:34:08 +08001053 wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, card_profile_path, res);
developera3511852023-06-14 14:12:59 +08001054 return RETURN_ERR;
1055 }
developerfde01262023-05-22 15:15:24 +08001056
developera3511852023-06-14 14:12:59 +08001057 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1058 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001059}
1060
1061static int wifi_BandProfileRead(int card_idx,
developera3511852023-06-14 14:12:59 +08001062 int radio_idx,
1063 char *param,
1064 char *output,
1065 int output_size,
1066 char *default_value)
developerfde01262023-05-22 15:15:24 +08001067{
developera3511852023-06-14 14:12:59 +08001068 char option[64];
1069 char band_profile_path[64];
developere40952c2023-06-15 18:46:43 +08001070 int ret, res;
developerfde01262023-05-22 15:15:24 +08001071
developera3511852023-06-14 14:12:59 +08001072 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1073 if (!param || !output || (output_size <= 0)) {
developer75bd10c2023-06-27 11:34:08 +08001074 wifi_debug(DEBUG_ERROR, "invalid parameters");
developera3511852023-06-14 14:12:59 +08001075 return RETURN_ERR;
1076 }
developerfde01262023-05-22 15:15:24 +08001077
developere40952c2023-06-15 18:46:43 +08001078 res = snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1079 if (os_snprintf_error(sizeof(option), res)) {
1080 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1081 return RETURN_ERR;
1082 }
developera3511852023-06-14 14:12:59 +08001083 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1084 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08001085 wifi_debug(DEBUG_ERROR, "wifi_CardProfileRead %s failed, ret:%d", option, ret);
developera3511852023-06-14 14:12:59 +08001086 return RETURN_ERR;
1087 }
developerfde01262023-05-22 15:15:24 +08001088
developera3511852023-06-14 14:12:59 +08001089 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1090 if (ret != 0) {
1091 if (default_value) {
developere40952c2023-06-15 18:46:43 +08001092 res = snprintf(output, output_size, "%s", default_value);
1093 if (os_snprintf_error(output_size, res)) {
1094 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1095 return RETURN_ERR;
1096 }
developera3511852023-06-14 14:12:59 +08001097 } else {
1098 output[0] = '\0';
1099 }
1100 }
developerfde01262023-05-22 15:15:24 +08001101
developera3511852023-06-14 14:12:59 +08001102 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1103 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001104}
1105
developer72fb0bb2023-01-11 09:46:29 +08001106//For Getting Current Interface Name from corresponding hostapd configuration
1107static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1108{
developera3511852023-06-14 14:12:59 +08001109 char config_file[128] = {0};
developere40952c2023-06-15 18:46:43 +08001110 int res;
developer72fb0bb2023-01-11 09:46:29 +08001111
developera3511852023-06-14 14:12:59 +08001112 if (interface_name == NULL)
1113 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001114
developera3511852023-06-14 14:12:59 +08001115 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001116
developere40952c2023-06-15 18:46:43 +08001117 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1118 if (os_snprintf_error(sizeof(config_file), res)) {
1119 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1120 return RETURN_ERR;
1121 }
developera3511852023-06-14 14:12:59 +08001122 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1123 if (strlen(interface_name) == 0)
1124 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001125
developera3511852023-06-14 14:12:59 +08001126 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1127 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001128}
1129
developera1255e42023-05-13 17:45:02 +08001130static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1131{
developera3511852023-06-14 14:12:59 +08001132 char interface_name[IF_NAME_SIZE] = {0};
1133 char cmd[MAX_BUF_SIZE]={'\0'};
1134 char buf[MAX_CMD_SIZE]={'\0'};
1135 UCHAR channel = 0;
developere40952c2023-06-15 18:46:43 +08001136 int res;
developera1255e42023-05-13 17:45:02 +08001137
developera3511852023-06-14 14:12:59 +08001138 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1139 return RETURN_ERR;
1140 /*interface name to channel number*/
developere40952c2023-06-15 18:46:43 +08001141 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1142 if (os_snprintf_error(sizeof(cmd), res)) {
1143 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1144 return RETURN_ERR;
1145 }
1146
developera3511852023-06-14 14:12:59 +08001147 _syscmd(cmd, buf, sizeof(buf));
1148 channel = atoi(buf);
1149 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
developera1255e42023-05-13 17:45:02 +08001150 /*count dev number with the same channel*/
developere40952c2023-06-15 18:46:43 +08001151 res = snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1152 if (os_snprintf_error(sizeof(cmd), res)) {
1153 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1154 return RETURN_ERR;
1155 }
1156
developera3511852023-06-14 14:12:59 +08001157 _syscmd(cmd, buf, sizeof(buf));
1158 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1159 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1160 return RETURN_OK;
developera1255e42023-05-13 17:45:02 +08001161}
developer72fb0bb2023-01-11 09:46:29 +08001162
1163static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1164{
developera3511852023-06-14 14:12:59 +08001165 char interface_name[16] = {0};
1166 if (multiple_set == TRUE)
1167 return RETURN_OK;
1168 char cmd[MAX_CMD_SIZE]="", output[32]="";
1169 FILE *fp;
developere40952c2023-06-15 18:46:43 +08001170 int i, res;
developera3511852023-06-14 14:12:59 +08001171 //NOTE RELOAD should be done in ApplySSIDSettings
1172 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1173 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001174
1175 for (i=0; i<item_count; i++, list++) {
1176 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
1177 if (os_snprintf_error(sizeof(cmd), res)) {
1178 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1179 return RETURN_ERR;
1180 }
1181 if ((fp = popen(cmd, "r"))==NULL) {
developera3511852023-06-14 14:12:59 +08001182 perror("popen failed");
1183 return -1;
1184 }
developere40952c2023-06-15 18:46:43 +08001185 if (!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) {
1186 pclose(fp);
developera3511852023-06-14 14:12:59 +08001187 perror("fgets failed");
1188 return -1;
1189 }
developere40952c2023-06-15 18:46:43 +08001190 pclose(fp);
developera3511852023-06-14 14:12:59 +08001191 }
1192 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001193}
1194
developer7e4a2a62023-04-06 19:56:03 +08001195static int wifi_quick_reload_ap(int apIndex)
1196{
1197 char interface_name[IF_NAME_SIZE] = {0};
1198 char cmd[MAX_CMD_SIZE] = {0};
1199 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001200 int res;
developer7e4a2a62023-04-06 19:56:03 +08001201
1202 if (multiple_set == TRUE)
1203 return RETURN_OK;
1204
1205 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1206 return RETURN_ERR;
1207
developere40952c2023-06-15 18:46:43 +08001208 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1209 if (os_snprintf_error(sizeof(cmd), res)) {
1210 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1211 return RETURN_ERR;
1212 }
developer7e4a2a62023-04-06 19:56:03 +08001213 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1214 return RETURN_ERR;
1215
1216 return RETURN_OK;
1217}
1218
developer72fb0bb2023-01-11 09:46:29 +08001219static int wifi_reloadAp(int apIndex)
1220{
developera3511852023-06-14 14:12:59 +08001221 char interface_name[16] = {0};
developer22e0c672023-06-07 15:25:37 +08001222 int res;
1223
developera3511852023-06-14 14:12:59 +08001224 if (multiple_set == TRUE)
1225 return RETURN_OK;
1226 char cmd[MAX_CMD_SIZE]="";
1227 char buf[MAX_BUF_SIZE]="";
developer72fb0bb2023-01-11 09:46:29 +08001228
developera3511852023-06-14 14:12:59 +08001229 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1230 return RETURN_ERR;
1231 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
developer22e0c672023-06-07 15:25:37 +08001232 if (os_snprintf_error(sizeof(cmd), res)) {
1233 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1234 return RETURN_ERR;
1235 }
developera3511852023-06-14 14:12:59 +08001236 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1237 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001238
developera3511852023-06-14 14:12:59 +08001239 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001240 if (os_snprintf_error(sizeof(cmd), res)) {
1241 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1242 return RETURN_ERR;
1243 }
developera3511852023-06-14 14:12:59 +08001244 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1245 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001246
developera3511852023-06-14 14:12:59 +08001247 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001248 if (os_snprintf_error(sizeof(cmd), res)) {
1249 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1250 return RETURN_ERR;
1251 }
developera3511852023-06-14 14:12:59 +08001252 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1253 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001254
developera3511852023-06-14 14:12:59 +08001255 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001256}
1257
1258INT File_Reading(CHAR *file, char *Value)
1259{
developera3511852023-06-14 14:12:59 +08001260 FILE *fp = NULL;
1261 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1262 int count = 0;
developer72fb0bb2023-01-11 09:46:29 +08001263
developera3511852023-06-14 14:12:59 +08001264 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1265 fp = popen(file,"r");
1266 if(fp == NULL)
1267 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001268
developera3511852023-06-14 14:12:59 +08001269 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1270 {
1271 for(count=0;buf[count]!='\n';count++)
1272 copy_buf[count]=buf[count];
1273 copy_buf[count]='\0';
1274 }
1275 strcpy(Value,copy_buf);
1276 pclose(fp);
1277 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001278
developera3511852023-06-14 14:12:59 +08001279 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001280}
1281
1282void wifi_RestartHostapd_2G()
1283{
developera3511852023-06-14 14:12:59 +08001284 int Public2GApIndex = 4;
developer72fb0bb2023-01-11 09:46:29 +08001285
developera3511852023-06-14 14:12:59 +08001286 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1287 wifi_setApEnable(Public2GApIndex, FALSE);
1288 wifi_setApEnable(Public2GApIndex, TRUE);
1289 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001290}
1291
1292void wifi_RestartHostapd_5G()
1293{
developera3511852023-06-14 14:12:59 +08001294 int Public5GApIndex = 5;
developer72fb0bb2023-01-11 09:46:29 +08001295
developera3511852023-06-14 14:12:59 +08001296 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1297 wifi_setApEnable(Public5GApIndex, FALSE);
1298 wifi_setApEnable(Public5GApIndex, TRUE);
1299 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001300}
1301
1302void wifi_RestartPrivateWifi_2G()
1303{
developera3511852023-06-14 14:12:59 +08001304 int PrivateApIndex = 0;
developer72fb0bb2023-01-11 09:46:29 +08001305
developera3511852023-06-14 14:12:59 +08001306 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1307 wifi_setApEnable(PrivateApIndex, FALSE);
1308 wifi_setApEnable(PrivateApIndex, TRUE);
1309 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001310}
1311
1312void wifi_RestartPrivateWifi_5G()
1313{
developera3511852023-06-14 14:12:59 +08001314 int Private5GApIndex = 1;
developer72fb0bb2023-01-11 09:46:29 +08001315
developera3511852023-06-14 14:12:59 +08001316 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1317 wifi_setApEnable(Private5GApIndex, FALSE);
1318 wifi_setApEnable(Private5GApIndex, TRUE);
1319 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001320}
1321
1322static int writeBandWidth(int radioIndex,char *bw_value)
1323{
developera3511852023-06-14 14:12:59 +08001324 char buf[MAX_BUF_SIZE];
1325 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08001326 int res;
developer72fb0bb2023-01-11 09:46:29 +08001327
developere40952c2023-06-15 18:46:43 +08001328 res = snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1329 if (os_snprintf_error(sizeof(cmd), res)) {
1330 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1331 return RETURN_ERR;
1332 }
1333
1334 if (_syscmd(cmd, buf, sizeof(buf))) {
1335 res = snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1336 if (os_snprintf_error(sizeof(cmd), res)) {
1337 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1338 return RETURN_ERR;
1339 }
developera3511852023-06-14 14:12:59 +08001340 _syscmd(cmd, buf, sizeof(buf));
1341 return RETURN_OK;
1342 }
developer72fb0bb2023-01-11 09:46:29 +08001343
developer75bd10c2023-06-27 11:34:08 +08001344 res = snprintf(cmd, sizeof(cmd), "sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1345 if (os_snprintf_error(sizeof(cmd), res)) {
1346 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1347 return RETURN_ERR;
1348 }
developera3511852023-06-14 14:12:59 +08001349 _syscmd(cmd,buf,sizeof(buf));
1350 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001351}
1352
1353// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1354INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1355{
developera3511852023-06-14 14:12:59 +08001356 struct params params={'\0'};
1357 char config_file[MAX_BUF_SIZE] = {0};
1358 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08001359 int res;
developer72fb0bb2023-01-11 09:46:29 +08001360
developera3511852023-06-14 14:12:59 +08001361 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1362 // Copy the numeric value
1363 if (strlen (beaconRate) >= 5) {
1364 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1365 buf[strlen(beaconRate) - 4] = '\0';
developer9ce44382023-06-28 11:09:37 +08001366 } else if (strlen(beaconRate) > 0){
1367 strncpy(buf, beaconRate,sizeof(buf) - 1);
1368 buf[sizeof(buf) - 1] = '\0';
1369 } else
developera3511852023-06-14 14:12:59 +08001370 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001371
developera3511852023-06-14 14:12:59 +08001372 params.name = "beacon_rate";
1373 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1374 if (strncmp(buf, "5.5", 3) == 0) {
developere40952c2023-06-15 18:46:43 +08001375 res = snprintf(buf, sizeof(buf), "55");
1376 if (os_snprintf_error(sizeof(buf), res)) {
1377 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1378 return RETURN_ERR;
1379 }
developera3511852023-06-14 14:12:59 +08001380 params.value = buf;
1381 } else {
developer32f2a182023-06-27 19:50:41 +08001382 if (strlen(buf) >= (MAX_BUF_SIZE - 1)) {
1383 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
1384 return RETURN_ERR;
1385 }
1386 strncat(buf, "0", sizeof(buf) - strlen(buf) - 1);
developera3511852023-06-14 14:12:59 +08001387 params.value = buf;
1388 }
developer72fb0bb2023-01-11 09:46:29 +08001389
developer32f2a182023-06-27 19:50:41 +08001390 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
1391 if (os_snprintf_error(sizeof(config_file), res)) {
1392 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1393 return RETURN_ERR;
1394 }
1395
developera3511852023-06-14 14:12:59 +08001396 wifi_hostapdWrite(config_file, &params, 1);
1397 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1398 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001399
developera3511852023-06-14 14:12:59 +08001400 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001401}
1402
1403INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1404{
developera3511852023-06-14 14:12:59 +08001405 char config_file[128] = {'\0'};
1406 char temp_output[MAX_BUF_SIZE] = {'\0'};
1407 char buf[128] = {'\0'};
1408 char cmd[128] = {'\0'};
1409 int rate = 0;
developere40952c2023-06-15 18:46:43 +08001410 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08001411
developera3511852023-06-14 14:12:59 +08001412 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1413 if (NULL == beaconRate)
1414 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001415
developer75bd10c2023-06-27 11:34:08 +08001416 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
1417 if (os_snprintf_error(sizeof(config_file), res)) {
1418 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1419 return RETURN_ERR;
1420 }
developera3511852023-06-14 14:12:59 +08001421 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1422 phyId = radio_index_to_phy(radioIndex);
1423 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1424 if(strlen(buf) > 0) {
1425 if (strncmp(buf, "55", 2) == 0)
developere40952c2023-06-15 18:46:43 +08001426 res = snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
developera3511852023-06-14 14:12:59 +08001427 else {
1428 rate = strtol(buf, NULL, 10)/10;
developere40952c2023-06-15 18:46:43 +08001429 res = snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
developera3511852023-06-14 14:12:59 +08001430 }
developer75bd10c2023-06-27 11:34:08 +08001431 if (os_snprintf_error(sizeof(temp_output), res)) {
1432 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1433 return RETURN_ERR;
1434 }
developera3511852023-06-14 14:12:59 +08001435 } else {
1436 // config not set, so we would use lowest rate as default
developer75bd10c2023-06-27 11:34:08 +08001437 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1438 if (os_snprintf_error(sizeof(cmd), res)) {
1439 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1440 return RETURN_ERR;
1441 }
developera3511852023-06-14 14:12:59 +08001442 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08001443 res = snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
developer75bd10c2023-06-27 11:34:08 +08001444 if (os_snprintf_error(sizeof(temp_output), res)) {
1445 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1446 return RETURN_ERR;
1447 }
developera3511852023-06-14 14:12:59 +08001448 }
developer75bd10c2023-06-27 11:34:08 +08001449
developera3511852023-06-14 14:12:59 +08001450 strncpy(beaconRate, temp_output, strlen(temp_output));
1451 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001452
developera3511852023-06-14 14:12:59 +08001453 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001454}
1455
1456INT wifi_setLED(INT radioIndex, BOOL enable)
1457{
1458 return 0;
1459}
1460INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
1461{
1462 return RETURN_OK;
1463}
1464/**********************************************************************************
1465 *
developer69b61b02023-03-07 17:17:44 +08001466 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001467 *
1468**********************************************************************************/
1469//---------------------------------------------------------------------------------------------------
1470//Wifi system api
1471//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 +08001472INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001473{
developere40952c2023-06-15 18:46:43 +08001474 int res;
1475
developera3511852023-06-14 14:12:59 +08001476 if(!output_string)
1477 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001478 res = snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1479 if (os_snprintf_error(64, res)) {
1480 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1481 return RETURN_ERR;
1482 }
developer72fb0bb2023-01-11 09:46:29 +08001483
developera3511852023-06-14 14:12:59 +08001484 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001485}
1486
1487
1488/* wifi_factoryReset() function */
1489/**
developer69b61b02023-03-07 17:17:44 +08001490* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001491* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1492*
1493* @param None
1494*
1495* @return The status of the operation.
1496* @retval RETURN_OK if successful.
1497* @retval RETURN_ERR if any error is detected
1498*
1499* @execution Synchronous
1500* @sideeffect None
1501*
1502* @note This function must not suspend and must not invoke any blocking system
1503* calls. It should probably just send a message to a driver event handler task.
1504*
1505*/
1506INT wifi_factoryReset()
1507{
developer47cc27a2023-05-17 23:09:58 +08001508 char cmd[MAX_CMD_SIZE] = {0};
1509 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001510 int res;
developer72fb0bb2023-01-11 09:46:29 +08001511
developer47cc27a2023-05-17 23:09:58 +08001512 /*delete running hostapd conf files*/
1513 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
developere40952c2023-06-15 18:46:43 +08001514 res = snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1515 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1516 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1517 return RETURN_ERR;
1518 }
1519
developer47cc27a2023-05-17 23:09:58 +08001520 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001521
developerd14dff12023-06-28 22:47:44 +08001522 wifi_PrepareDefaultHostapdConfigs(TRUE);
developer47cc27a2023-05-17 23:09:58 +08001523 wifi_psk_file_reset();
1524
1525 memset(cmd, 0, MAX_CMD_SIZE);
1526 memset(buf, 0, MAX_BUF_SIZE);
1527
developere40952c2023-06-15 18:46:43 +08001528 res = snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1529 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1530 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1531 return RETURN_ERR;
1532 }
1533
developer47cc27a2023-05-17 23:09:58 +08001534 _syscmd(cmd, buf, sizeof(buf));
1535
1536 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001537}
1538
1539/* wifi_factoryResetRadios() function */
1540/**
1541* @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.
1542*
1543* @param None
1544* @return The status of the operation
1545* @retval RETURN_OK if successful
1546* @retval RETURN_ERR if any error is detected
1547*
1548* @execution Synchronous
1549*
1550* @sideeffect None
1551*
1552* @note This function must not suspend and must not invoke any blocking system
1553* calls. It should probably just send a message to a driver event handler task.
1554*
1555*/
1556INT wifi_factoryResetRadios()
1557{
developera3511852023-06-14 14:12:59 +08001558 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1559 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001560
developera3511852023-06-14 14:12:59 +08001561 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001562}
1563
developerfead3972023-05-25 20:15:02 +08001564ULONG get_radio_reset_cnt(int radioIndex)
1565{
1566 char cmd[MAX_CMD_SIZE] = {0};
1567 char buf[MAX_BUF_SIZE] = {0};
1568 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001569 int res;
developerfead3972023-05-25 20:15:02 +08001570
developere40952c2023-06-15 18:46:43 +08001571 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 +08001572 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001573 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1574 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1575 return RETURN_ERR;
1576 }
1577
developerfead3972023-05-25 20:15:02 +08001578 _syscmd(cmd, buf, sizeof(buf));
1579
1580 if (strlen(buf) == 0)
1581 return 0;
1582 else {
1583 reset_count = atol(buf);
1584 return reset_count;
1585 }
1586}
1587void update_radio_reset_cnt(int radioIndex)
1588{
1589 char cmd[MAX_CMD_SIZE] = {0};
1590 char buf[MAX_BUF_SIZE] = {0};
1591 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001592 int res;
developerfead3972023-05-25 20:15:02 +08001593
developere40952c2023-06-15 18:46:43 +08001594 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 +08001595 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001596 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1597 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1598 return;
1599 }
1600
developerfead3972023-05-25 20:15:02 +08001601 _syscmd(cmd, buf, sizeof(buf));
1602
1603 if (strlen(buf) == 0)
developere40952c2023-06-15 18:46:43 +08001604 res = snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
developerfead3972023-05-25 20:15:02 +08001605 else {
1606 reset_count = atol(buf);
1607 reset_count++;
developere40952c2023-06-15 18:46:43 +08001608 res = snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
1609 }
1610 if (os_snprintf_error(sizeof(cmd), res)) {
1611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1612 return;
developerfead3972023-05-25 20:15:02 +08001613 }
1614 _syscmd(cmd, buf, sizeof(buf));
1615}
developer72fb0bb2023-01-11 09:46:29 +08001616
1617/* wifi_factoryResetRadio() function */
1618/**
1619* @description Restore selected radio parameters without touching access point parameters
1620*
1621* @param radioIndex - Index of Wi-Fi Radio channel
1622*
1623* @return The status of the operation.
1624* @retval RETURN_OK if successful.
1625* @retval RETURN_ERR if any error is detected
1626*
1627* @execution Synchronous.
1628* @sideeffect None.
1629*
1630* @note This function must not suspend and must not invoke any blocking system
1631* calls. It should probably just send a message to a driver event handler task.
1632*
1633*/
1634INT wifi_factoryResetRadio(int radioIndex) //RDKB
1635{
developer47cc27a2023-05-17 23:09:58 +08001636 char cmd[MAX_CMD_SIZE] = {0};
1637 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001638 int res;
developer72fb0bb2023-01-11 09:46:29 +08001639
developer47cc27a2023-05-17 23:09:58 +08001640 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001641
developerb2977562023-05-24 17:54:12 +08001642 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001643
developerb2977562023-05-24 17:54:12 +08001644 /*reset gi setting*/
developere40952c2023-06-15 18:46:43 +08001645 res = snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
1646 if (os_snprintf_error(sizeof(cmd), res)) {
1647 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1648 return RETURN_ERR;
1649 }
1650
developer47cc27a2023-05-17 23:09:58 +08001651 _syscmd(cmd, buf, sizeof(buf));
1652
developerb2977562023-05-24 17:54:12 +08001653 /*TBD: check mbss issue*/
1654 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08001655 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08001656
developer47cc27a2023-05-17 23:09:58 +08001657 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1658 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001659}
1660
1661/* wifi_initRadio() function */
1662/**
1663* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001664* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001665* different hardware implementations may have different initilization requirements.
1666* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1667*
1668* @return The status of the operation.
1669* @retval RETURN_OK if successful.
1670* @retval RETURN_ERR if any error is detected
1671*
1672* @execution Synchronous.
1673* @sideeffect None.
1674*
1675* @note This function must not suspend and must not invoke any blocking system
1676* calls. It should probably just send a message to a driver event handler task.
1677*
1678*/
1679INT wifi_initRadio(INT radioIndex)
1680{
developera3511852023-06-14 14:12:59 +08001681 //TODO: Initializes the wifi subsystem (for specified radio)
1682 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001683}
1684
developer17038e62023-03-02 14:43:43 +08001685static void
1686wifi_ParseProfile(void)
1687{
developere40952c2023-06-15 18:46:43 +08001688 int i, res;
developera3511852023-06-14 14:12:59 +08001689 int max_radio_num = 0;
1690 int card_idx;
1691 int band_idx;
1692 int phy_idx = 0;
1693 int wireless_mode = 0;
1694 char buf[MAX_BUF_SIZE] = {0};
1695 char chip_name[12];
1696 char card_profile[MAX_BUF_SIZE] = {0};
1697 char band_profile[MAX_BUF_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001698
developera3511852023-06-14 14:12:59 +08001699 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001700
developera3511852023-06-14 14:12:59 +08001701 memset(main_prefix, 0, sizeof(main_prefix));
1702 memset(ext_prefix, 0, sizeof(ext_prefix));
1703 memset(default_ssid, 0, sizeof(default_ssid));
1704 for (i = 0; i < MAX_NUM_RADIOS; i++)
1705 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001706
developera3511852023-06-14 14:12:59 +08001707 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1708 /* LOG */
developer17038e62023-03-02 14:43:43 +08001709 return;
developera3511852023-06-14 14:12:59 +08001710 }
developer17038e62023-03-02 14:43:43 +08001711
developera3511852023-06-14 14:12:59 +08001712 for (card_idx = 0; card_idx < 3; card_idx++) {
developere40952c2023-06-15 18:46:43 +08001713 res = snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1714 if (os_snprintf_error(sizeof(buf), res)) {
1715 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1716 return;
1717 }
developera3511852023-06-14 14:12:59 +08001718 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1719 break;
1720 }
developere40952c2023-06-15 18:46:43 +08001721 res = snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1722 if (os_snprintf_error(sizeof(buf), res)) {
1723 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1724 return;
1725 }
developera3511852023-06-14 14:12:59 +08001726 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1727 break;
1728 }
1729 for (band_idx = 0; band_idx < 3; band_idx++) {
developere40952c2023-06-15 18:46:43 +08001730 res = snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1731 if (os_snprintf_error(sizeof(buf), res)) {
1732 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1733 return;
1734 }
developera3511852023-06-14 14:12:59 +08001735 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1736 /* LOG */
1737 break;
1738 }
developer17038e62023-03-02 14:43:43 +08001739
developere40952c2023-06-15 18:46:43 +08001740 res = snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1741 if (os_snprintf_error(sizeof(buf), res)) {
1742 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1743 return;
1744 }
developera3511852023-06-14 14:12:59 +08001745 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1746 /* LOG */
1747 }
developer17038e62023-03-02 14:43:43 +08001748
developere40952c2023-06-15 18:46:43 +08001749 res = snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1750 if (os_snprintf_error(sizeof(buf), res)) {
1751 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1752 return;
1753 }
developera3511852023-06-14 14:12:59 +08001754 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1755 /* LOG */
1756 }
developer17038e62023-03-02 14:43:43 +08001757
developera3511852023-06-14 14:12:59 +08001758 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1759 /* LOG */
1760 }
1761 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1762 /* LOG */
1763 }
developer745f0bd2023-03-06 14:32:53 +08001764
developera3511852023-06-14 14:12:59 +08001765 wireless_mode = atoi(buf);
1766 switch (wireless_mode) {
1767 case 22:
1768 case 16:
1769 case 6:
1770 case 4:
1771 case 1:
1772 radio_band[phy_idx] = band_2_4;
1773 break;
1774 case 23:
1775 case 17:
1776 case 14:
1777 case 11:
1778 case 2:
1779 radio_band[phy_idx] = band_5;
1780 break;
1781 case 24:
1782 case 18:
1783 radio_band[phy_idx] = band_6;
1784 break;
1785 }
1786 phy_idx++;
1787 }
1788 }
developer17038e62023-03-02 14:43:43 +08001789
developera3511852023-06-14 14:12:59 +08001790 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001791}
1792
1793static void
developerd14dff12023-06-28 22:47:44 +08001794wifi_PrepareDefaultHostapdConfigs(bool reset)
developer17038e62023-03-02 14:43:43 +08001795{
developere40952c2023-06-15 18:46:43 +08001796 int radio_idx, res;
developer0132ed92023-03-21 13:48:53 +08001797 int bss_idx;
1798 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001799 char buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001800 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer0132ed92023-03-21 13:48:53 +08001801 char ssid[MAX_BUF_SIZE] = {0};
1802 char interface[32] = {0};
1803 char ret_buf[MAX_BUF_SIZE] = {0};
1804 char psk_file[64] = {0};
1805 struct params params[3];
developer17038e62023-03-02 14:43:43 +08001806
developer0132ed92023-03-21 13:48:53 +08001807 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1808 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001809
developer0132ed92023-03-21 13:48:53 +08001810 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001811 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001812
developere40952c2023-06-15 18:46:43 +08001813 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1814 if (os_snprintf_error(sizeof(config_file), res)) {
1815 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1816 return;
1817 }
developerd14dff12023-06-28 22:47:44 +08001818 if (access(config_file, F_OK) == 0 && reset == FALSE)
1819 continue;
developere40952c2023-06-15 18:46:43 +08001820 res = snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
1821 if (os_snprintf_error(sizeof(buf), res)) {
1822 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1823 return;
1824 }
developer47cc27a2023-05-17 23:09:58 +08001825 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001826
developer47cc27a2023-05-17 23:09:58 +08001827 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08001828 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1829 if (os_snprintf_error(sizeof(ssid), res)) {
1830 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1831 return;
1832 }
1833 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1834 if (os_snprintf_error(sizeof(interface), res)) {
1835 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1836 return;
1837 }
developer47cc27a2023-05-17 23:09:58 +08001838 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08001839 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1840 if (os_snprintf_error(sizeof(ssid), res)) {
1841 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1842 return;
1843 }
1844 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1845 if (os_snprintf_error(sizeof(interface), res)) {
1846 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1847 return;
1848 }
developer47cc27a2023-05-17 23:09:58 +08001849 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08001850 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1851 if (os_snprintf_error(sizeof(ssid), res)) {
1852 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1853 return;
1854 }
1855 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1856 if (os_snprintf_error(sizeof(interface), res)) {
1857 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1858 return;
1859 }
developer47cc27a2023-05-17 23:09:58 +08001860 }
developer17038e62023-03-02 14:43:43 +08001861
developer47cc27a2023-05-17 23:09:58 +08001862 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08001863 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
1864 if (os_snprintf_error(sizeof(psk_file), res)) {
1865 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1866 return;
1867 }
developer17038e62023-03-02 14:43:43 +08001868
developer47cc27a2023-05-17 23:09:58 +08001869 params[0].name = "ssid";
1870 params[0].value = ssid;
1871 params[1].name = "interface";
1872 params[1].value = interface;
1873 params[2].name = "wpa_psk_file";
1874 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001875
developer47cc27a2023-05-17 23:09:58 +08001876 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001877 }
1878 }
1879 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001880}
1881
1882static void
developer17038e62023-03-02 14:43:43 +08001883wifi_BringDownInterfacesForRadio(int radio_idx)
1884{
developera3511852023-06-14 14:12:59 +08001885 char cmd[MAX_BUF_SIZE] = {0};
1886 char ret_buf[MAX_BUF_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08001887 int res;
developerb758dfd2023-06-21 17:32:07 +08001888
developera3511852023-06-14 14:12:59 +08001889 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001890
developere40952c2023-06-15 18:46:43 +08001891 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1892 if (os_snprintf_error(sizeof(cmd), res)) {
1893 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1894 return;
1895 }
developer8a3bbbf2023-03-15 17:47:23 +08001896 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1897
developera3511852023-06-14 14:12:59 +08001898 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001899}
1900
1901
1902static void
1903wifi_BringDownInterfaces(void)
1904{
developera3511852023-06-14 14:12:59 +08001905 int radio_idx;
1906 int band_idx;
developer17038e62023-03-02 14:43:43 +08001907
developera3511852023-06-14 14:12:59 +08001908 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1909 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1910 band_idx = radio_index_to_band(radio_idx);
1911 if (band_idx < 0) {
1912 break;
1913 }
1914 wifi_BringDownInterfacesForRadio(radio_idx);
1915 }
1916 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001917}
1918
developerb2977562023-05-24 17:54:12 +08001919static void wifi_dat_file_reset_by_radio(char radio_idx)
1920{
developerb149d9d2023-06-06 16:14:22 +08001921 char cmd[MAX_CMD_SIZE * 2] = {0};
developerb2977562023-05-24 17:54:12 +08001922 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001923 char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
1924 char dat_file[MAX_SUB_CMD_SIZE]= {0};
developere40952c2023-06-15 18:46:43 +08001925 int res;
developerb2977562023-05-24 17:54:12 +08001926
developere40952c2023-06-15 18:46:43 +08001927 res = snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1928 if (os_snprintf_error(sizeof(rom_dat_file), res)) {
1929 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1930 return;
1931 }
1932 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
1933 if (os_snprintf_error(sizeof(dat_file), res)) {
1934 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1935 return;
1936 }
1937 res = snprintf(cmd, (MAX_CMD_SIZE * 2), "cp -rf %s %s", rom_dat_file, dat_file);
1938 if (os_snprintf_error((MAX_CMD_SIZE * 2), res)) {
1939 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1940 return;
1941 }
developerb2977562023-05-24 17:54:12 +08001942 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1943
1944}
1945
developer47cc27a2023-05-17 23:09:58 +08001946static void wifi_psk_file_reset()
1947{
1948 char cmd[MAX_CMD_SIZE] = {0};
1949 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001950 char psk_file[MAX_SUB_CMD_SIZE]= {0};
developer47cc27a2023-05-17 23:09:58 +08001951 char vap_idx = 0;
developere40952c2023-06-15 18:46:43 +08001952 int res;
developer47cc27a2023-05-17 23:09:58 +08001953
1954 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
developere40952c2023-06-15 18:46:43 +08001955 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1956 if (os_snprintf_error(sizeof(psk_file), res)) {
1957 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1958 return;
1959 }
developer47cc27a2023-05-17 23:09:58 +08001960
1961 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001962 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1963 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1964 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1965 return;
1966 }
developer47cc27a2023-05-17 23:09:58 +08001967 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1968 } else {
developere40952c2023-06-15 18:46:43 +08001969 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1970 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1971 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1972 return;
1973 }
1974
developer47cc27a2023-05-17 23:09:58 +08001975 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1976 }
1977 }
developerb2977562023-05-24 17:54:12 +08001978}
1979
developer8a3bbbf2023-03-15 17:47:23 +08001980static void wifi_vap_status_reset()
1981{
developera3511852023-06-14 14:12:59 +08001982 char cmd[MAX_CMD_SIZE] = {0};
1983 char ret_buf[MAX_BUF_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08001984 int radio_idx = 0;
developer8a3bbbf2023-03-15 17:47:23 +08001985 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08001986 int res;
developer8666b312023-03-24 14:05:31 +08001987
developer8a3bbbf2023-03-15 17:47:23 +08001988 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001989 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
1990 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1991 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1992 return;
1993 }
developer8a3bbbf2023-03-15 17:47:23 +08001994 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1995 } else {
developere40952c2023-06-15 18:46:43 +08001996 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
1997 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1998 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1999 return;
2000 }
developer8a3bbbf2023-03-15 17:47:23 +08002001 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2002 }
2003
2004 memset(cmd, 0, MAX_CMD_SIZE);
2005 memset(ret_buf, 0, MAX_BUF_SIZE);
2006
2007 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
developera3511852023-06-14 14:12:59 +08002008 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developere40952c2023-06-15 18:46:43 +08002009 res = snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
2010 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2011 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2012 return;
2013 }
developer8a3bbbf2023-03-15 17:47:23 +08002014 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2015 }
2016
developerfead3972023-05-25 20:15:02 +08002017}
2018
2019static void wifi_radio_reset_count_reset()
2020{
developera3511852023-06-14 14:12:59 +08002021 char cmd[MAX_CMD_SIZE] = {0};
2022 char ret_buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002023 int res;
developerfead3972023-05-25 20:15:02 +08002024
2025 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08002026 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE);
2027 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2028 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2029 return;
2030 }
developerfead3972023-05-25 20:15:02 +08002031 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2032 } else {
developere40952c2023-06-15 18:46:43 +08002033 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE);
2034 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
2035 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2036 return;
2037 }
developerfead3972023-05-25 20:15:02 +08002038 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2039 }
developer8a3bbbf2023-03-15 17:47:23 +08002040}
developer17038e62023-03-02 14:43:43 +08002041
developer72fb0bb2023-01-11 09:46:29 +08002042// Initializes the wifi subsystem (all radios)
developera3511852023-06-14 14:12:59 +08002043INT wifi_init() //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002044{
developera3511852023-06-14 14:12:59 +08002045 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercc9a4f32023-05-30 17:40:02 +08002046 static int CallOnce = 1;
developera3511852023-06-14 14:12:59 +08002047 //Not intitializing macfilter for Turris-Omnia Platform for now
2048 //macfilter_init();
2049 if (CallOnce) {
developercc9a4f32023-05-30 17:40:02 +08002050 wifi_ParseProfile();
developerd14dff12023-06-28 22:47:44 +08002051 wifi_PrepareDefaultHostapdConfigs(FALSE);
developercc9a4f32023-05-30 17:40:02 +08002052 wifi_psk_file_reset();
2053 //system("/usr/sbin/iw reg set US");
2054 system("systemctl start hostapd.service");
2055 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002056
developercc9a4f32023-05-30 17:40:02 +08002057 wifi_vap_status_reset();
2058 wifi_radio_reset_count_reset();
2059 CallOnce = 0;
developera3511852023-06-14 14:12:59 +08002060 }
developer96b38512023-02-22 11:17:45 +08002061
developera3511852023-06-14 14:12:59 +08002062 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002063
developera3511852023-06-14 14:12:59 +08002064 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002065}
2066
2067/* wifi_reset() function */
2068/**
2069* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08002070* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08002071* different hardware implementations may have different requirements.
2072* Parameters : None
2073*
2074* @return The status of the operation.
2075* @retval RETURN_OK if successful.
2076* @retval RETURN_ERR if any error is detected
2077*
2078* @execution Synchronous.
2079* @sideeffect None.
2080*
2081* @note This function must not suspend and must not invoke any blocking system
2082* calls. It should probably just send a message to a driver event handler task.
2083*
2084*/
2085INT wifi_reset()
2086{
developer17038e62023-03-02 14:43:43 +08002087
developera3511852023-06-14 14:12:59 +08002088 wifi_BringDownInterfaces();
2089 sleep(2);
developer17038e62023-03-02 14:43:43 +08002090
developera3511852023-06-14 14:12:59 +08002091 //TODO: resets the wifi subsystem, deletes all APs
2092 system("systemctl stop hostapd.service");
2093 sleep(2);
developer17038e62023-03-02 14:43:43 +08002094
developera3511852023-06-14 14:12:59 +08002095 system("systemctl start hostapd.service");
2096 sleep(5);
developer17038e62023-03-02 14:43:43 +08002097
developerd14dff12023-06-28 22:47:44 +08002098 wifi_PrepareDefaultHostapdConfigs(TRUE);
developer47cc27a2023-05-17 23:09:58 +08002099 wifi_psk_file_reset();
developera3511852023-06-14 14:12:59 +08002100 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002101
2102 wifi_vap_status_reset();
2103
developera3511852023-06-14 14:12:59 +08002104 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002105}
2106
2107/* wifi_down() function */
2108/**
2109* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08002110* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08002111* different hardware implementations may have different requirements.
2112*
2113* @param None
2114*
2115* @return The status of the operation
2116* @retval RETURN_OK if successful
2117* @retval RETURN_ERR if any error is detected
2118*
2119* @execution Synchronous
2120* @sideeffect None
2121*
2122* @note This function must not suspend and must not invoke any blocking system
2123* calls. It should probably just send a message to a driver event handler task.
2124*
2125*/
2126INT wifi_down()
2127{
developera3511852023-06-14 14:12:59 +08002128 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
2129 int max_num_radios = 0;
developerb2977562023-05-24 17:54:12 +08002130 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08002131
developerb2977562023-05-24 17:54:12 +08002132 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
2133 wifi_setRadioEnable(radioIndex, FALSE);
2134
developera3511852023-06-14 14:12:59 +08002135 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002136}
2137
2138
2139/* wifi_createInitialConfigFiles() function */
2140/**
2141* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08002142* and content of these files are implementation dependent. This function call is
2143* used to trigger this task if necessary. Some implementations may not need this
2144* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08002145* do nothing and return RETURN_OK.
2146*
2147* @param None
2148*
2149* @return The status of the operation
2150* @retval RETURN_OK if successful
2151* @retval RETURN_ERR if any error is detected
2152*
2153* @execution Synchronous
2154* @sideeffect None
2155*
2156* @note This function must not suspend and must not invoke any blocking system
2157* calls. It should probably just send a message to a driver event handler task.
2158*
2159*/
2160INT wifi_createInitialConfigFiles()
2161{
developera3511852023-06-14 14:12:59 +08002162 //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)
2163 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002164}
2165
developer7e4a2a62023-04-06 19:56:03 +08002166/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08002167INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
2168{
developera3511852023-06-14 14:12:59 +08002169 int ret;
developer72fb0bb2023-01-11 09:46:29 +08002170
developera3511852023-06-14 14:12:59 +08002171 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002172
developera3511852023-06-14 14:12:59 +08002173 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
2174 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +08002175 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead CountryCode failed\n");
developera3511852023-06-14 14:12:59 +08002176 return RETURN_ERR;
2177 }
developer7e4a2a62023-04-06 19:56:03 +08002178
developera3511852023-06-14 14:12:59 +08002179 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002180
developera3511852023-06-14 14:12:59 +08002181 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002182}
2183
2184INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
2185{
developer7e4a2a62023-04-06 19:56:03 +08002186 /*Set wifi config. Wait for wifi reset to apply*/
developer7e4a2a62023-04-06 19:56:03 +08002187 struct params params;
2188 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002189 int ret = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002190
developer7e4a2a62023-04-06 19:56:03 +08002191 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002192
developer7e4a2a62023-04-06 19:56:03 +08002193 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
2194 printf("%s: input para error!!!\n", __func__);
2195 return RETURN_ERR;
2196 }
developer72fb0bb2023-01-11 09:46:29 +08002197
developerc79e9172023-06-06 19:48:03 +08002198 if (!strlen(CountryCode)) {
2199 memcpy(CountryCode, "US", strlen("US")); /*default set the code to US*/
2200 CountryCode[2] = '\0';
2201 }
developer72fb0bb2023-01-11 09:46:29 +08002202
developer7e4a2a62023-04-06 19:56:03 +08002203 params.name = "country_code";
2204 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08002205
developere40952c2023-06-15 18:46:43 +08002206 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2207 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
2208 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2209 return RETURN_ERR;
2210 }
developer7e4a2a62023-04-06 19:56:03 +08002211 ret = wifi_hostapdWrite(config_file, &params, 1);
2212
2213 if (ret) {
2214 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
2215 __func__, ret);
2216 }
2217
2218 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2219
2220 if (ret) {
2221 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
2222 __func__, ret);
2223 }
2224
2225 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2226
2227 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002228}
2229
2230INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
2231{
developera3511852023-06-14 14:12:59 +08002232 char interface_name[16] = {0};
2233 char channel_util_file[64] = {0};
2234 char cmd[128] = {0};
2235 char buf[128] = {0};
2236 char *line = NULL;
2237 char *param = NULL, *value = NULL;
developere40952c2023-06-15 18:46:43 +08002238 int read = 0, res;
developera3511852023-06-14 14:12:59 +08002239 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
developer86035662023-06-28 19:21:12 +08002240 unsigned long preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
developera3511852023-06-14 14:12:59 +08002241 size_t len = 0;
2242 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08002243
developera3511852023-06-14 14:12:59 +08002244 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002245
developera3511852023-06-14 14:12:59 +08002246 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2247 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002248 res = snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
2249 if (os_snprintf_error(sizeof(cmd), res)) {
2250 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2251 return RETURN_ERR;
2252 }
2253
developera3511852023-06-14 14:12:59 +08002254 _syscmd(cmd, buf, sizeof(buf));
2255 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
developer37646972023-06-29 10:58:43 +08002256 if ((buf[0] != '\0') && (outputChannelStats2->ch_Max80211Rssi == 0))
2257 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
developer72fb0bb2023-01-11 09:46:29 +08002258
developera3511852023-06-14 14:12:59 +08002259 memset(cmd, 0, sizeof(cmd));
2260 memset(buf, 0, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08002261 res = snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
2262 if (os_snprintf_error(sizeof(cmd), res)) {
2263 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2264 return RETURN_ERR;
2265 }
developera3511852023-06-14 14:12:59 +08002266 if ((f = popen(cmd, "r")) == NULL) {
2267 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
2268 return RETURN_ERR;
2269 }
developer72fb0bb2023-01-11 09:46:29 +08002270
developera3511852023-06-14 14:12:59 +08002271 read = getline(&line, &len, f);
2272 while (read != -1) {
2273 param = strtok(line, ":\t");
2274 value = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +08002275 if (!param || !value) {
2276 read = getline(&line, &len, f);
2277 continue;
2278 }
developera3511852023-06-14 14:12:59 +08002279 if(strstr(param, "frequency") != NULL) {
2280 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
developer37646972023-06-29 10:58:43 +08002281 if ((value[0] != '\0') && (outputChannelStats2->ch_Frequency == 0))
2282 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
developera3511852023-06-14 14:12:59 +08002283 }
2284 if(strstr(param, "noise") != NULL) {
2285 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
developer37646972023-06-29 10:58:43 +08002286 if ((value[0] != '\0') && (outputChannelStats2->ch_NoiseFloor == 0))
2287 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
2288
developera3511852023-06-14 14:12:59 +08002289 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
developer37646972023-06-29 10:58:43 +08002290 if ((value[0] != '\0') && (outputChannelStats2->ch_Non80211Noise == 0))
2291 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
developera3511852023-06-14 14:12:59 +08002292 }
2293 if(strstr(param, "channel active time") != NULL) {
2294 ActiveTime = strtol(value, NULL, 10);
developer37646972023-06-29 10:58:43 +08002295 if ((value[0] != '\0') && (ActiveTime == 0))
2296 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
developera3511852023-06-14 14:12:59 +08002297 }
2298 if(strstr(param, "channel busy time") != NULL) {
2299 BusyTime = strtol(value, NULL, 10);
developer37646972023-06-29 10:58:43 +08002300 if ((value[0] != '\0') && (BusyTime == 0))
2301 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
developera3511852023-06-14 14:12:59 +08002302 }
2303 if(strstr(param, "channel transmit time") != NULL) {
2304 TransmitTime = strtol(value, NULL, 10);
developer37646972023-06-29 10:58:43 +08002305 if ((value[0] != '\0') && (TransmitTime == 0))
2306 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
developera3511852023-06-14 14:12:59 +08002307 }
2308 read = getline(&line, &len, f);
2309 }
2310 pclose(f);
developer72fb0bb2023-01-11 09:46:29 +08002311
developera3511852023-06-14 14:12:59 +08002312 // The file should store the last active, busy and transmit time
developere40952c2023-06-15 18:46:43 +08002313 res = snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2314 if (os_snprintf_error(sizeof(channel_util_file), res)) {
2315 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2316 return RETURN_ERR;
2317 }
2318
developera3511852023-06-14 14:12:59 +08002319 f = fopen(channel_util_file, "r");
2320 if (f != NULL) {
2321 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002322 if (hal_strtoul(line, 10, &preActiveTime) < 0) {
2323 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2324 fclose(f);
2325 return RETURN_ERR;
2326 }
developera3511852023-06-14 14:12:59 +08002327 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002328 if (hal_strtoul(line, 10, &preBusyTime) < 0) {
2329 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2330 fclose(f);
2331 return RETURN_ERR;
2332 }
developera3511852023-06-14 14:12:59 +08002333 read = getline(&line, &len, f);
developer86035662023-06-28 19:21:12 +08002334 if (hal_strtoul(line, 10, &preTransmitTime) < 0) {
2335 wifi_debug(DEBUG_ERROR, "strtol fail\n");
2336 fclose(f);
2337 return RETURN_ERR;
2338 }
developera3511852023-06-14 14:12:59 +08002339 fclose(f);
2340 }
developer72fb0bb2023-01-11 09:46:29 +08002341
developera3511852023-06-14 14:12:59 +08002342 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2343 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
developer72fb0bb2023-01-11 09:46:29 +08002344
developera3511852023-06-14 14:12:59 +08002345 f = fopen(channel_util_file, "w");
2346 if (f != NULL) {
developer86035662023-06-28 19:21:12 +08002347 if (fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime) < 0) {
2348 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
2349 }
2350 if (fclose(f) != 0) {
2351 wifi_debug(DEBUG_ERROR, "fclose fail\n");
2352 }
developera3511852023-06-14 14:12:59 +08002353 }
2354 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2355 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002356}
2357
2358/**********************************************************************************
2359 *
2360 * Wifi radio level function prototypes
2361 *
2362**********************************************************************************/
2363
2364//Get the total number of radios in this wifi subsystem
2365INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2366{
developera3511852023-06-14 14:12:59 +08002367 if (NULL == output)
2368 return RETURN_ERR;
2369 *output = MAX_NUM_RADIOS;
developer72fb0bb2023-01-11 09:46:29 +08002370
developera3511852023-06-14 14:12:59 +08002371 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002372}
2373
developer69b61b02023-03-07 17:17:44 +08002374//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002375INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2376{
developera3511852023-06-14 14:12:59 +08002377 if (NULL == output)
2378 return RETURN_ERR;
2379 *output = MAX_APS;
developer72fb0bb2023-01-11 09:46:29 +08002380
developera3511852023-06-14 14:12:59 +08002381 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002382}
2383
2384//Get the Radio enable config parameter
developera3511852023-06-14 14:12:59 +08002385INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002386{
developer56fbedb2023-05-30 16:47:05 +08002387 char interface_name[16] = {0};
2388 char buf[128] = {0}, cmd[128] = {0};
2389 int apIndex;
2390 int max_radio_num = 0;
developer75bd10c2023-06-27 11:34:08 +08002391 int res;
developer3a85ab82023-05-25 11:59:38 +08002392
developer56fbedb2023-05-30 16:47:05 +08002393 if (NULL == output_bool)
2394 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002395
developer56fbedb2023-05-30 16:47:05 +08002396 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08002397
developer56fbedb2023-05-30 16:47:05 +08002398 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002399
developer56fbedb2023-05-30 16:47:05 +08002400 if (radioIndex >= max_radio_num)
2401 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002402
developer56fbedb2023-05-30 16:47:05 +08002403 /* loop all interface in radio, if any is enable, reture true, else return false */
2404 for(apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num)
2405 {
2406 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2407 continue;
2408 memset(cmd, 0, sizeof(cmd));
developer75bd10c2023-06-27 11:34:08 +08002409 res = snprintf(cmd, sizeof(cmd), "ifconfig %s 2> /dev/null | grep UP", interface_name);
2410 if (os_snprintf_error(sizeof(cmd), res)) {
2411 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2412 return RETURN_ERR;
2413 }
developer56fbedb2023-05-30 16:47:05 +08002414 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? FALSE : TRUE;
2415 if (*output_bool == TRUE)
2416 break;
2417 }
2418
2419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002420}
2421
developere82c0ca2023-05-10 16:25:35 +08002422typedef long time_t;
2423static time_t radio_up_time[MAX_NUM_RADIOS];
2424
developer72fb0bb2023-01-11 09:46:29 +08002425INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2426{
developera3511852023-06-14 14:12:59 +08002427 char interface_name[16] = {0};
2428 char cmd[MAX_CMD_SIZE] = {0};
2429 char buf[MAX_BUF_SIZE] = {0};
2430 int apIndex;
2431 int max_radio_num = 0;
developere40952c2023-06-15 18:46:43 +08002432 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002433
developera3511852023-06-14 14:12:59 +08002434 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002435
developera3511852023-06-14 14:12:59 +08002436 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002437
developera3511852023-06-14 14:12:59 +08002438 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002439
developera3511852023-06-14 14:12:59 +08002440 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002441
2442 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2443 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002444
2445 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
2446 if (os_snprintf_error(sizeof(cmd), res)) {
2447 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2448 return RETURN_ERR;
2449 }
developer47cc27a2023-05-17 23:09:58 +08002450
developer8a3bbbf2023-03-15 17:47:23 +08002451 _syscmd(cmd, buf, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +08002452 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08002453 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
2454 if (os_snprintf_error(sizeof(cmd), res)) {
2455 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2456 return RETURN_ERR;
2457 }
developer56fbedb2023-05-30 16:47:05 +08002458 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002459 if(strncmp(buf, "OK", 2))
developer75bd10c2023-06-27 11:34:08 +08002460 wifi_debug(DEBUG_ERROR, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002461 } else {
developere82c0ca2023-05-10 16:25:35 +08002462 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developera3511852023-06-14 14:12:59 +08002463 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2464 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002465
developer8a3bbbf2023-03-15 17:47:23 +08002466 memset(cmd, 0, MAX_CMD_SIZE);
2467 memset(buf, 0, MAX_BUF_SIZE);
2468
developere40952c2023-06-15 18:46:43 +08002469 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2470 if (os_snprintf_error(sizeof(cmd), res)) {
2471 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2472 return RETURN_ERR;
2473 }
developera3511852023-06-14 14:12:59 +08002474 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002475
developera3511852023-06-14 14:12:59 +08002476 if(*buf == '1') {
developere40952c2023-06-15 18:46:43 +08002477 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
2478 if (os_snprintf_error(sizeof(cmd), res)) {
2479 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2480 return RETURN_ERR;
2481 }
developer56fbedb2023-05-30 16:47:05 +08002482 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002483
2484 memset(cmd, 0, MAX_CMD_SIZE);
2485 memset(buf, 0, MAX_BUF_SIZE);
2486
developere40952c2023-06-15 18:46:43 +08002487 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 +08002488 phyId, apIndex);
developere40952c2023-06-15 18:46:43 +08002489 if (os_snprintf_error(sizeof(cmd), res)) {
2490 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2491 return RETURN_ERR;
2492 }
developera3511852023-06-14 14:12:59 +08002493 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002494
developera3511852023-06-14 14:12:59 +08002495 }
2496 }
developere82c0ca2023-05-10 16:25:35 +08002497 time(&radio_up_time[radioIndex]);
developera3511852023-06-14 14:12:59 +08002498 }
developer72fb0bb2023-01-11 09:46:29 +08002499
developera3511852023-06-14 14:12:59 +08002500 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2501 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002502}
2503
2504//Get the Radio enable status
2505INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2506{
developera3511852023-06-14 14:12:59 +08002507 if (NULL == output_bool)
2508 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002509
developera3511852023-06-14 14:12:59 +08002510 return wifi_getRadioEnable(radioIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08002511}
2512
2513//Get the Radio Interface name from platform, eg "wlan0"
2514INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2515{
developera3511852023-06-14 14:12:59 +08002516 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2517 return RETURN_ERR;
2518 return wifi_GetInterfaceName(radioIndex, output_string);
developer72fb0bb2023-01-11 09:46:29 +08002519}
2520
developer6e578302023-06-21 10:11:16 +08002521int mtk_get_vow_info_callback(struct nl_msg *msg, void *data)
2522{
2523 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2524 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX + 1];
2525 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2526 int err = 0;
2527 struct vow_info *vow_info = NULL;
2528 struct mtk_nl80211_cb_data *cb_data = data;
2529
2530 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2531 genlmsg_attrlen(gnlh, 0), NULL);
2532 if (err < 0) {
2533 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
2534 return err;
2535 }
2536
2537 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2538 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX,
2539 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2540 if (err < 0){
2541 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX fails\n");
2542 return err;
2543 }
2544
2545 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]) {
2546 vow_info = (struct vow_info *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]);
2547 memmove(cb_data->out_buf, vow_info, sizeof(struct vow_info));
2548 }
2549 }
2550
2551 return 0;
2552}
2553
2554INT mtk_wifi_set_air_time_management(
2555 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
2556 char* data, INT len, void *output)
2557{
2558 char inf_name[IF_NAME_SIZE] = {0};
2559 unsigned int if_idx = 0;
2560 int ret = -1;
2561 struct unl unl_ins;
2562 struct nl_msg *msg = NULL;
2563 struct nlattr * msg_data = NULL;
2564 struct mtk_nl80211_param param;
2565
2566 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
2567 return RETURN_ERR;
2568 if_idx = if_nametoindex(inf_name);
2569 if (!if_idx) {
2570 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
2571 return RETURN_ERR;
2572 }
2573 /*init mtk nl80211 vendor cmd*/
2574 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_VOW;
2575 param.if_type = NL80211_ATTR_IFINDEX;
2576 param.if_idx = if_idx;
2577
2578 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
2579 if (ret) {
2580 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
2581 return RETURN_ERR;
2582 }
2583 /*add mtk vendor cmd data*/
2584 if (nla_put(msg, vendor_data_attr, len, data)) {
2585 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
2586 nlmsg_free(msg);
2587 goto err;
2588 }
2589
2590 /*send mtk nl80211 vendor msg*/
2591 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
2592 if (ret) {
2593 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
2594 goto err;
2595 }
2596 /*deinit mtk nl80211 vendor msg*/
2597 mtk_nl80211_deint(&unl_ins);
2598 wifi_debug(DEBUG_INFO, "send cmd success.\n");
2599
2600 return RETURN_OK;
2601err:
2602 mtk_nl80211_deint(&unl_ins);
2603 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
2604 return RETURN_ERR;
2605}
2606
2607//Get the ATM(Air Time Management) Capable.
2608INT wifi_getATMCapable(BOOL *output_bool)
2609{
2610 if (NULL == output_bool)
2611 return RETURN_ERR;
2612 *output_bool = TRUE;
2613
2614 return RETURN_OK;
2615}
2616
2617INT wifi_setATMEnable(BOOL enable)
2618{
2619 int max_radio_num = 0;
2620 int radio_idx = 0;
2621 char dat_file[MAX_BUF_SIZE] = {0};
2622 int res;
2623 struct params params[2];
2624
2625 wifi_getMaxRadioNumber(&max_radio_num);
2626 for (radio_idx = 0; radio_idx < max_radio_num; radio_idx++) {
2627 if (mtk_wifi_set_air_time_management
2628 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO,
2629 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
2630 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
2631 return RETURN_ERR;
2632 }
2633
2634 if (mtk_wifi_set_air_time_management
2635 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_BW_EN_INFO,
2636 NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
2637 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
2638 return RETURN_ERR;
2639 }
2640
2641 params[0].name = "VOW_Airtime_Fairness_En";
2642 params[0].value = enable ? "1" : "0";
2643 params[1].name = "VOW_BW_Ctrl";
2644 params[1].value = enable ? "1" : "0";
2645
2646 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
2647 if (os_snprintf_error(sizeof(dat_file), res)) {
2648 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2649 return RETURN_ERR;
2650 }
2651 wifi_datfileWrite(dat_file, params, 2);
2652 }
2653
2654 return RETURN_OK;
2655}
2656
2657INT wifi_getATMEnable(BOOL *output_enable)
2658{
2659 int max_radio_num = 0;
2660 int radio_idx = 0;
2661 struct vow_info vow_info;
2662 struct vow_info get_vow_info;
2663 struct mtk_nl80211_cb_data cb_data;
2664
2665 if (output_enable == NULL)
2666 return RETURN_ERR;
2667
2668 wifi_getMaxRadioNumber(&max_radio_num);
2669
2670 *output_enable = FALSE;
2671
2672 memset(&vow_info, 0, sizeof(struct vow_info));
2673
2674 cb_data.out_buf = (char *)&vow_info;
2675 cb_data.out_len = sizeof(struct vow_info);
2676
2677 for (radio_idx = 0; radio_idx < max_radio_num; radio_idx++) {
2678 if (mtk_wifi_set_air_time_management
2679 (radio_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2680 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2681 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2682 return RETURN_ERR;
2683 }
2684
2685 if (vow_info.atf_en == TRUE || vow_info.bw_en == TRUE) {
2686 *output_enable = TRUE;
2687 break;
2688 }
2689 }
2690
2691 return RETURN_OK;
2692}
2693
2694UINT apidx_to_group(INT apIndex)
2695{
2696 int max_radio_num = 0;
2697 unsigned int group = 0;
2698
2699 wifi_getMaxRadioNumber(&max_radio_num);
2700 group = apIndex / max_radio_num + 5 * (apIndex % max_radio_num);
2701
2702 return group;
2703}
2704
2705INT wifi_setApATMAirTimePercent(INT apIndex, UINT ap_AirTimePercent)
2706{
2707 struct vow_group_en_param atc_en_param;
2708 struct vow_ratio_param radio_param;
2709 unsigned int group = 0;
2710 //BOOL ATM_enable = FALSE;
2711
2712 if (ap_AirTimePercent < 5 || ap_AirTimePercent > 100) {
2713 wifi_debug(DEBUG_ERROR, "invalid ait time percent!\n");
2714 return RETURN_ERR;
2715 }
2716
2717 /* mt7990 support 15 group now*/
2718 group = apidx_to_group(apIndex);
2719
2720 if (group > 15) {
2721 wifi_debug(DEBUG_ERROR, "invalid group!\n");
2722 return RETURN_ERR;
2723 }
2724
2725 atc_en_param.group = group;
2726 atc_en_param.en = 1;
2727 if (mtk_wifi_set_air_time_management
2728 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO,
2729 NULL, (char *)&atc_en_param, sizeof(struct vow_group_en_param), NULL)!= RETURN_OK) {
2730 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO cmd fails\n");
2731 return RETURN_ERR;
2732 }
2733
2734 radio_param.group = group;
2735 radio_param.ratio = ap_AirTimePercent;
2736 if (mtk_wifi_set_air_time_management
2737 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO,
2738 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
2739 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO cmd fails\n");
2740 return RETURN_ERR;
2741 }
2742
2743 if (mtk_wifi_set_air_time_management
2744 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO,
2745 NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
2746 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO cmd fails\n");
2747 return RETURN_ERR;
2748 }
2749
2750 return RETURN_OK;
2751}
2752
2753INT wifi_getApATMAirTimePercent(INT apIndex, UINT *output_ap_AirTimePercent)
2754{
2755 unsigned int group = 0;
2756 struct vow_info get_vow_info, vow_info;
2757 struct mtk_nl80211_cb_data cb_data;
2758
2759 if (output_ap_AirTimePercent == NULL)
2760 return RETURN_ERR;
2761
2762 group = apidx_to_group(apIndex);
2763 if (group > 15) {
2764 wifi_debug(DEBUG_ERROR, "invalid group!\n");
2765 return RETURN_ERR;
2766 }
2767
2768 memset(&vow_info, 0, sizeof(struct vow_info));
2769 memset(&get_vow_info, 0, sizeof(struct vow_info));
2770
2771 cb_data.out_buf = (char *)&vow_info;
2772 cb_data.out_len = sizeof(struct vow_info);
2773
2774 get_vow_info.group = group;
2775
2776 if (mtk_wifi_set_air_time_management
2777 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2778 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2779 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2780 return RETURN_ERR;
2781 }
2782
2783 *output_ap_AirTimePercent = vow_info.ratio;
2784
2785 return RETURN_ERR;
2786}
2787
developerd14dff12023-06-28 22:47:44 +08002788INT wifi_getApATMSta(INT apIndex, UCHAR *output_sta_MAC_ATM_array, UINT buf_size)
2789{
2790 ULONG dev_num = 0;
2791 struct vow_info vow_info;
2792 struct vow_info get_vow_info;
2793 struct mtk_nl80211_cb_data cb_data;
2794 unsigned int percent;
2795 char assocArray[MAX_BUF_SIZE] = {0};
2796 char *mac = NULL;
2797 unsigned char output_len = 0;
2798 int res;
2799 char buf[MAX_BUF_SIZE] = {0};
2800
2801 memset(&vow_info, 0, sizeof(struct vow_info));
2802 memset(&get_vow_info, 0, sizeof(struct vow_info));
2803
2804 cb_data.out_buf = (char *)&vow_info;
2805 cb_data.out_len = sizeof(struct vow_info);
2806
2807 if (mtk_wifi_set_air_time_management
2808 (apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
2809 mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
2810 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
2811 return RETURN_ERR;
2812 }
2813
2814 if (vow_info.atf_en == FALSE) {
2815 wifi_debug(DEBUG_ERROR, "ATF disable!\n");
2816 return RETURN_ERR;
2817 }
2818
2819 if (wifi_getApNumDevicesAssociated(apIndex, &dev_num) != RETURN_OK) {
2820 wifi_debug(DEBUG_ERROR, "get sta num fail!\n");
2821 return RETURN_ERR;;
2822 }
2823
2824 percent = 100 / dev_num;
2825
2826 if (wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray)) != RETURN_OK){
2827 wifi_debug(DEBUG_ERROR, "get sta mac fail!\n");
2828 return RETURN_ERR;;
2829 }
2830
2831 memset(output_sta_MAC_ATM_array, 0, MAX_BUF_SIZE);
2832
2833 mac = strtok(assocArray, "\n");
2834 while (mac != NULL) {
2835 if (strlen(mac) >= 17) {
2836 res = snprintf(buf, sizeof(buf), "%s %d|", mac, percent);
2837
2838 if (os_snprintf_error(sizeof(buf), res)) {
2839 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2840 return RETURN_ERR;
2841 }
2842
2843 if (output_len + strlen(buf) > buf_size)
2844 break;
2845
2846 strncat((char *)output_sta_MAC_ATM_array, buf, strlen(buf));
2847
2848 output_len += strlen(buf);
2849 }
2850
2851 mac = strtok(NULL, "\n");
2852 }
2853
2854 /* Remove the last | */
2855 if (strlen((char *)output_sta_MAC_ATM_array) != 0)
2856 output_sta_MAC_ATM_array[strlen((char *)output_sta_MAC_ATM_array)-1] = '\0';
2857
2858 return RETURN_OK;
2859}
2860
2861INT wifi_setApATMSta(INT apIndex, UCHAR *sta_MAC_ATM_array, UINT ap_AirTimePercent)
2862{
2863 return RETURN_ERR;
2864}
developer9ce44382023-06-28 11:09:37 +08002865
developer72fb0bb2023-01-11 09:46:29 +08002866//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2867//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.
2868INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2869{
developera3511852023-06-14 14:12:59 +08002870 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2871 // For max bit rate, we should always choose the best MCS
2872 char mode[64] = {0};
2873 char channel_bandwidth_str[64] = {0};
2874 UINT mode_map = 0;
2875 UINT num_subcarrier = 0;
2876 UINT code_bits = 0;
2877 float code_rate = 0; // use max code rate
2878 int NSS = 0;
2879 UINT Symbol_duration = 0;
2880 UINT GI_duration = 0;
2881 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2882 BOOL enable = FALSE;
2883 float bit_rate = 0;
developere40952c2023-06-15 18:46:43 +08002884 int ant_bitmap = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002885
developera3511852023-06-14 14:12:59 +08002886 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2887 if (NULL == output_string)
2888 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002889
developera3511852023-06-14 14:12:59 +08002890 wifi_getRadioEnable(radioIndex, &enable);
2891 if (enable == FALSE) {
developere40952c2023-06-15 18:46:43 +08002892 res = snprintf(output_string, 64, "0 Mb/s");
2893 if (os_snprintf_error(64, res)) {
2894 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2895 return RETURN_ERR;
2896 }
developera3511852023-06-14 14:12:59 +08002897 return RETURN_OK;
2898 }
developer72fb0bb2023-01-11 09:46:29 +08002899
developera3511852023-06-14 14:12:59 +08002900 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08002901 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +08002902 return RETURN_ERR;
2903 }
developer72fb0bb2023-01-11 09:46:29 +08002904
developera3511852023-06-14 14:12:59 +08002905 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08002906 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +08002907 return RETURN_ERR;
2908 }
developer72fb0bb2023-01-11 09:46:29 +08002909
developera3511852023-06-14 14:12:59 +08002910 if (gi == wifi_guard_interval_3200)
2911 GI_duration = 32;
2912 else if (gi == wifi_guard_interval_1600)
2913 GI_duration = 16;
2914 else if (gi == wifi_guard_interval_800)
2915 GI_duration = 8;
2916 else // auto, 400
2917 GI_duration = 4;
developer72fb0bb2023-01-11 09:46:29 +08002918
developera3511852023-06-14 14:12:59 +08002919 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08002920 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error\n");
developera3511852023-06-14 14:12:59 +08002921 return RETURN_ERR;
2922 }
developer72fb0bb2023-01-11 09:46:29 +08002923
developera3511852023-06-14 14:12:59 +08002924 if (strstr(channel_bandwidth_str, "80+80") != NULL)
developer32f2a182023-06-27 19:50:41 +08002925 memcpy(channel_bandwidth_str, "160", strlen("160"));
developer72fb0bb2023-01-11 09:46:29 +08002926
developera3511852023-06-14 14:12:59 +08002927 if (mode_map & WIFI_MODE_AX) {
2928 if (strstr(channel_bandwidth_str, "160") != NULL)
2929 num_subcarrier = 1960;
2930 else if (strstr(channel_bandwidth_str, "80") != NULL)
2931 num_subcarrier = 980;
2932 else if (strstr(channel_bandwidth_str, "40") != NULL)
2933 num_subcarrier = 468;
2934 else if (strstr(channel_bandwidth_str, "20") != NULL)
2935 num_subcarrier = 234;
2936 code_bits = 10;
2937 code_rate = (float)5/6;
2938 Symbol_duration = 128;
2939 GI_duration = 8;/*HE no GI 400ns*/
2940 } else if (mode_map & WIFI_MODE_AC) {
2941 if (strstr(channel_bandwidth_str, "160") != NULL)
2942 num_subcarrier = 468;
2943 else if (strstr(channel_bandwidth_str, "80") != NULL)
2944 num_subcarrier = 234;
2945 else if (strstr(channel_bandwidth_str, "40") != NULL)
2946 num_subcarrier = 108;
2947 else if (strstr(channel_bandwidth_str, "20") != NULL)
2948 num_subcarrier = 52;
2949 code_bits = 8;
2950 code_rate = (float)5/6;
2951 Symbol_duration = 32;
2952 } else if (mode_map & WIFI_MODE_N) {
2953 if (strstr(channel_bandwidth_str, "160") != NULL)
2954 num_subcarrier = 468;
2955 else if (strstr(channel_bandwidth_str, "80") != NULL)
2956 num_subcarrier = 234;
2957 else if (strstr(channel_bandwidth_str, "40") != NULL)
2958 num_subcarrier = 108;
2959 else if (strstr(channel_bandwidth_str, "20") != NULL)
2960 num_subcarrier = 52;
2961 code_bits = 6;
2962 code_rate = (float)3/4;
2963 Symbol_duration = 32;
2964 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2965 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
developere40952c2023-06-15 18:46:43 +08002966 res = snprintf(output_string, 64, "65 Mb/s");
2967 if (os_snprintf_error(64, res)) {
2968 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2969 return RETURN_ERR;
2970 }
developera3511852023-06-14 14:12:59 +08002971 return RETURN_OK;
2972 } else {
developere40952c2023-06-15 18:46:43 +08002973 res = snprintf(output_string, 64, "0 Mb/s");
2974 if (os_snprintf_error(64, res)) {
2975 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2976 return RETURN_ERR;
2977 }
developera3511852023-06-14 14:12:59 +08002978 return RETURN_OK;
2979 }
developer72fb0bb2023-01-11 09:46:29 +08002980
developera3511852023-06-14 14:12:59 +08002981 // Spatial streams
2982 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +08002983 wifi_debug(DEBUG_ERROR, "wifi_getRadioTxChainMask return error\n");
developera3511852023-06-14 14:12:59 +08002984 return RETURN_ERR;
2985 }
2986 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2987 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002988
developera3511852023-06-14 14:12:59 +08002989 // multiple 10 is to align duration unit (0.1 us)
2990 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
developere40952c2023-06-15 18:46:43 +08002991 res = snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
2992 if (os_snprintf_error(64, res)) {
2993 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2994 return RETURN_ERR;
2995 }
developera3511852023-06-14 14:12:59 +08002996 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2997 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
2998 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002999
developera3511852023-06-14 14:12:59 +08003000 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003001}
developer72fb0bb2023-01-11 09:46:29 +08003002
3003//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
3004//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.
3005INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
3006{
developera3511852023-06-14 14:12:59 +08003007 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003008
developera3511852023-06-14 14:12:59 +08003009 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3010 if (NULL == output_string)
3011 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003012
developera3511852023-06-14 14:12:59 +08003013 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003014
developera3511852023-06-14 14:12:59 +08003015 memset(output_string, 0, 10);
3016 if (band == band_2_4)
developer32f2a182023-06-27 19:50:41 +08003017 memcpy(output_string, "2.4GHz", strlen("2.4GHz"));
developera3511852023-06-14 14:12:59 +08003018 else if (band == band_5)
developer32f2a182023-06-27 19:50:41 +08003019 memcpy(output_string, "5GHz", strlen("5GHz"));
developera3511852023-06-14 14:12:59 +08003020 else if (band == band_6)
developer32f2a182023-06-27 19:50:41 +08003021 memcpy(output_string, "6GHz", strlen("6GHz"));
developera3511852023-06-14 14:12:59 +08003022 else
3023 return RETURN_ERR;
3024 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003025
developera3511852023-06-14 14:12:59 +08003026 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003027}
3028
3029//Get the frequency band at which the radio is operating, eg: "2.4GHz"
3030//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.
3031INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
3032{
developera3511852023-06-14 14:12:59 +08003033 wifi_band band = band_invalid;
developer9ce44382023-06-28 11:09:37 +08003034 int res = -1;
developere40952c2023-06-15 18:46:43 +08003035
developera3511852023-06-14 14:12:59 +08003036 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3037 if (NULL == output_string)
3038 return RETURN_ERR;
3039 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003040
developera3511852023-06-14 14:12:59 +08003041 if (band == band_2_4)
developere40952c2023-06-15 18:46:43 +08003042 res = snprintf(output_string, 64, "2.4GHz");
developera3511852023-06-14 14:12:59 +08003043 else if (band == band_5)
developere40952c2023-06-15 18:46:43 +08003044 res = snprintf(output_string, 64, "5GHz");
developera3511852023-06-14 14:12:59 +08003045 else if (band == band_6)
developere40952c2023-06-15 18:46:43 +08003046 res = snprintf(output_string, 64, "6GHz");
developer72fb0bb2023-01-11 09:46:29 +08003047
developere40952c2023-06-15 18:46:43 +08003048 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 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003053
developera3511852023-06-14 14:12:59 +08003054 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003055}
3056
3057//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
3058//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.
3059INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
3060{
developera3511852023-06-14 14:12:59 +08003061 char cmd[128]={0};
3062 char buf[128]={0};
3063 char temp_output[128] = {0};
3064 wifi_band band;
developere40952c2023-06-15 18:46:43 +08003065 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08003066
developera3511852023-06-14 14:12:59 +08003067 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3068 if (NULL == output_string)
3069 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003070
developera3511852023-06-14 14:12:59 +08003071 band = wifi_index_to_band(radioIndex);
3072 if (band == band_2_4) {
developer32f2a182023-06-27 19:50:41 +08003073 strncat(temp_output, "b,g,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003074 } else if (band == band_5) {
developer32f2a182023-06-27 19:50:41 +08003075 strncat(temp_output, "a,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003076 }
3077 phyId = radio_index_to_phy(radioIndex);
3078 // ht capabilities
developere40952c2023-06-15 18:46:43 +08003079 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);
3080 if (os_snprintf_error(sizeof(cmd), res)) {
3081 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3082 return RETURN_ERR;
3083 }
developera3511852023-06-14 14:12:59 +08003084 _syscmd(cmd, buf, sizeof(buf));
3085 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
developer32f2a182023-06-27 19:50:41 +08003086 if (strlen(temp_output) >= sizeof(temp_output) - 2)
3087 return RETURN_ERR;
3088 strncat(temp_output, "n,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003089 }
developer72fb0bb2023-01-11 09:46:29 +08003090
developera3511852023-06-14 14:12:59 +08003091 // vht capabilities
3092 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08003093 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
3094 if (os_snprintf_error(sizeof(cmd), res)) {
3095 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3096 return RETURN_ERR;
3097 }
3098 _syscmd(cmd, buf, sizeof(buf));
3099 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
developer32f2a182023-06-27 19:50:41 +08003100 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3101 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003102 strcat(temp_output, "ac,");
3103 }
3104 }
developer72fb0bb2023-01-11 09:46:29 +08003105
developera3511852023-06-14 14:12:59 +08003106 // he capabilities
developere40952c2023-06-15 18:46:43 +08003107 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);
3108 if (os_snprintf_error(sizeof(cmd), res)) {
3109 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3110 return RETURN_ERR;
3111 }
developera3511852023-06-14 14:12:59 +08003112 _syscmd(cmd, buf, sizeof(buf));
3113 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08003114 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3115 return RETURN_ERR;
3116 strncat(temp_output, "ax,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003117 }
developer72fb0bb2023-01-11 09:46:29 +08003118
developere82c0ca2023-05-10 16:25:35 +08003119 // eht capabilities
developere40952c2023-06-15 18:46:43 +08003120 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);
3121 if (os_snprintf_error(sizeof(cmd), res)) {
3122 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3123 return RETURN_ERR;
3124 }
developera3511852023-06-14 14:12:59 +08003125 _syscmd(cmd, buf, sizeof(buf));
3126 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
developer32f2a182023-06-27 19:50:41 +08003127 if (strlen(temp_output) >= sizeof(temp_output) - 3)
3128 return RETURN_ERR;
3129 strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08003130 }
developere82c0ca2023-05-10 16:25:35 +08003131
developera3511852023-06-14 14:12:59 +08003132 // Remove the last comma
3133 if (strlen(temp_output) != 0)
3134 temp_output[strlen(temp_output)-1] = '\0';
3135 strncpy(output_string, temp_output, strlen(temp_output));
3136 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3137 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003138}
3139
3140//Get the radio operating mode, and pure mode flag. eg: "ac"
3141//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.
3142INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
3143{
developere40952c2023-06-15 18:46:43 +08003144 int res;
3145
developera3511852023-06-14 14:12:59 +08003146 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3147 if (NULL == output_string)
3148 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003149
developera3511852023-06-14 14:12:59 +08003150 if (radioIndex == 0) {
developere40952c2023-06-15 18:46:43 +08003151 res = snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
3152 if (os_snprintf_error(64, res)) {
3153 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3154 return RETURN_ERR;
3155 }
developera3511852023-06-14 14:12:59 +08003156 *gOnly = FALSE;
3157 *nOnly = TRUE;
3158 *acOnly = FALSE;
3159 } else {
developere40952c2023-06-15 18:46:43 +08003160 res = snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
3161 if (os_snprintf_error(64, res)) {
3162 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3163 return RETURN_ERR;
3164 }
developera3511852023-06-14 14:12:59 +08003165 *gOnly = FALSE;
3166 *nOnly = FALSE;
3167 *acOnly = FALSE;
3168 }
3169 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003170
developera3511852023-06-14 14:12:59 +08003171 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003172}
3173
developer0f10c772023-05-16 21:43:39 +08003174enum WIFI_MODE {
3175 WMODE_INVALID = 0,
3176 WMODE_A = 1 << 0,
3177 WMODE_B = 1 << 1,
3178 WMODE_G = 1 << 2,
3179 WMODE_GN = 1 << 3,
3180 WMODE_AN = 1 << 4,
3181 WMODE_AC = 1 << 5,
3182 WMODE_AX_24G = 1 << 6,
3183 WMODE_AX_5G = 1 << 7,
3184 WMODE_AX_6G = 1 << 8,
3185 WMODE_BE_24G = 1 << 9,
3186 WMODE_BE_5G = 1 << 10,
3187 WMODE_BE_6G = 1 << 11,
3188 /*
3189 * total types of supported wireless mode,
3190 * add this value once yow add new type
3191 */
3192 WMODE_COMP = 12,
3193};
3194
3195#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08003196
3197int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08003198{
developerfead3972023-05-25 20:15:02 +08003199 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3200 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
3201 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3202 unsigned int *phymode;
3203 int err = 0;
3204 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08003205
developerfead3972023-05-25 20:15:02 +08003206 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08003207 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developerfead3972023-05-25 20:15:02 +08003208 return NL_SKIP;
3209 }
developer72fb0bb2023-01-11 09:46:29 +08003210
developerfead3972023-05-25 20:15:02 +08003211 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3212 genlmsg_attrlen(gnlh, 0), NULL);
3213 if (err < 0) {
3214 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
3215 return NL_SKIP;
3216 }
developer0f10c772023-05-16 21:43:39 +08003217
developerfead3972023-05-25 20:15:02 +08003218 if (tb[NL80211_ATTR_VENDOR_DATA]) {
3219 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
3220 tb[NL80211_ATTR_VENDOR_DATA], NULL);
3221 if (err < 0)
3222 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08003223
developerfead3972023-05-25 20:15:02 +08003224 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
3225 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
3226
3227 memset(cb_data->out_buf, 0, cb_data->out_len);
3228 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
3229 }
3230 } else
3231 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
3232
3233 return NL_OK;
3234}
developer0f10c772023-05-16 21:43:39 +08003235
developerfead3972023-05-25 20:15:02 +08003236void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
3237{
3238 wifi_band band;
3239 unsigned char radio_mode_tem_len;
developere40952c2023-06-15 18:46:43 +08003240 int res;
developerfead3972023-05-25 20:15:02 +08003241
3242 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08003243 // puremode is a bit map
developera3511852023-06-14 14:12:59 +08003244 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08003245 memset(output_string, 0, RADIO_MODE_LEN);
3246
3247 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3248
3249 switch (band) {
3250 case band_2_4:
3251 if (phymode & WMODE_B) {
developere40952c2023-06-15 18:46:43 +08003252 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
3253 if (os_snprintf_error(radio_mode_tem_len, res)) {
3254 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3255 return;
3256 }
developer0f10c772023-05-16 21:43:39 +08003257 *pureMode |= WIFI_MODE_B;
3258 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3259 }
3260 if (phymode & WMODE_G) {
developere40952c2023-06-15 18:46:43 +08003261 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
3262 if (os_snprintf_error(radio_mode_tem_len, res)) {
3263 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3264 return;
3265 }
developer0f10c772023-05-16 21:43:39 +08003266 *pureMode |= WIFI_MODE_G;
3267 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3268 }
3269 if (phymode & WMODE_GN) {
developere40952c2023-06-15 18:46:43 +08003270 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3271 if (os_snprintf_error(radio_mode_tem_len, res)) {
3272 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3273 return;
3274 }
developer0f10c772023-05-16 21:43:39 +08003275 *pureMode |= WIFI_MODE_N;
3276 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3277 }
3278 if (phymode & WMODE_AX_24G) {
developere40952c2023-06-15 18:46:43 +08003279 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3280 if (os_snprintf_error(radio_mode_tem_len, res)) {
3281 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3282 return;
3283 }
developer0f10c772023-05-16 21:43:39 +08003284 *pureMode |= WIFI_MODE_AX;
3285 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3286 }
3287 if (phymode & WMODE_BE_24G) {
developere40952c2023-06-15 18:46:43 +08003288 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3289 if (os_snprintf_error(radio_mode_tem_len, res)) {
3290 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3291 return;
3292 }
developer0f10c772023-05-16 21:43:39 +08003293 *pureMode |= WIFI_MODE_BE;
3294 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3295 }
3296 break;
3297 case band_5:
3298 if (phymode & WMODE_A) {
developere40952c2023-06-15 18:46:43 +08003299 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
3300 if (os_snprintf_error(radio_mode_tem_len, res)) {
3301 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3302 return;
3303 }
developer0f10c772023-05-16 21:43:39 +08003304 *pureMode |= WIFI_MODE_A;
3305 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3306 }
3307 if (phymode & WMODE_AN) {
developere40952c2023-06-15 18:46:43 +08003308 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3309 if (os_snprintf_error(radio_mode_tem_len, res)) {
3310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3311 return;
3312 }
developer0f10c772023-05-16 21:43:39 +08003313 *pureMode |= WIFI_MODE_N;
3314 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3315 }
3316 if (phymode & WMODE_AC) {
developere40952c2023-06-15 18:46:43 +08003317 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
3318 if (os_snprintf_error(radio_mode_tem_len, res)) {
3319 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3320 return;
3321 }
developer0f10c772023-05-16 21:43:39 +08003322 *pureMode |= WIFI_MODE_AC;
3323 }
3324 if (phymode & WMODE_AX_5G) {
developere40952c2023-06-15 18:46:43 +08003325 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3326 if (os_snprintf_error(radio_mode_tem_len, res)) {
3327 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3328 return;
3329 }
developer0f10c772023-05-16 21:43:39 +08003330 *pureMode |= WIFI_MODE_AX;
3331 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3332 }
3333 if (phymode & WMODE_BE_5G) {
developere40952c2023-06-15 18:46:43 +08003334 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3335 if (os_snprintf_error(radio_mode_tem_len, res)) {
3336 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3337 return;
3338 }
developer0f10c772023-05-16 21:43:39 +08003339 *pureMode |= WIFI_MODE_BE;
3340 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3341 }
3342 break;
3343 case band_6:
3344 if (phymode & WMODE_AX_6G) {
developere40952c2023-06-15 18:46:43 +08003345 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3346 if (os_snprintf_error(radio_mode_tem_len, res)) {
3347 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3348 return;
3349 }
developer0f10c772023-05-16 21:43:39 +08003350 *pureMode |= WIFI_MODE_AX;
3351 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3352 }
3353 if (phymode & WMODE_BE_6G) {
developere40952c2023-06-15 18:46:43 +08003354 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3355 if (os_snprintf_error(radio_mode_tem_len, res)) {
3356 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3357 return;
3358 }
developer0f10c772023-05-16 21:43:39 +08003359 *pureMode |= WIFI_MODE_BE;
3360 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3361 }
3362 break;
3363 default:
developer86035662023-06-28 19:21:12 +08003364 wifi_debug(DEBUG_ERROR, "%s band_idx invalid\n", __func__);
developer0f10c772023-05-16 21:43:39 +08003365 break;
3366 }
3367
3368 /* Remove the last comma */
3369 if (strlen(output_string) != 0)
developera3511852023-06-14 14:12:59 +08003370 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08003371
developerfead3972023-05-25 20:15:02 +08003372}
3373
3374INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
3375{
3376 unsigned int phymode;
3377 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003378 int ret = -1;
3379 unsigned int if_idx = 0;
3380 struct unl unl_ins;
3381 struct nl_msg *msg = NULL;
3382 struct nlattr * msg_data = NULL;
3383 struct mtk_nl80211_param param;
3384 struct mtk_nl80211_cb_data cb_data;
3385
developera3511852023-06-14 14:12:59 +08003386 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3387 if (NULL == output_string || NULL == pureMode)
developerdaf24792023-06-06 11:40:04 +08003388 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003389
3390 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3391 return RETURN_ERR;
3392
3393 if_idx = if_nametoindex(interface_name);
3394 if (!if_idx) {
3395 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
3396 return RETURN_ERR;
3397 }
3398 /*init mtk nl80211 vendor cmd*/
3399 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
3400 param.if_type = NL80211_ATTR_IFINDEX;
3401 param.if_idx = if_idx;
3402
3403 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3404 if (ret) {
3405 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3406 return RETURN_ERR;
3407 }
3408
3409 /*add mtk vendor cmd data*/
3410 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
3411 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
3412 nlmsg_free(msg);
3413 goto err;
3414 }
3415
3416 /*send mtk nl80211 vendor msg*/
3417 cb_data.out_buf = (char *)&phymode;
3418 cb_data.out_len = sizeof(unsigned int);
3419
3420 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
3421
3422 if (ret) {
3423 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3424 goto err;
3425 }
3426 /*deinit mtk nl80211 vendor msg*/
3427 mtk_nl80211_deint(&unl_ins);
3428
3429 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
developer6e578302023-06-21 10:11:16 +08003430 wifi_debug(DEBUG_INFO,"send cmd success\n");
developerfead3972023-05-25 20:15:02 +08003431
developera3511852023-06-14 14:12:59 +08003432 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3433 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003434err:
3435 mtk_nl80211_deint(&unl_ins);
3436 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
3437 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003438}
3439
3440// Set the radio operating mode, and pure mode flag.
3441INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
3442{
developera3511852023-06-14 14:12:59 +08003443 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
3444 if (strcmp (channelMode,"11A") == 0)
3445 {
3446 writeBandWidth(radioIndex,"20MHz");
3447 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3448 printf("\nChannel Mode is 802.11a (5GHz)\n");
3449 }
3450 else if (strcmp (channelMode,"11NAHT20") == 0)
3451 {
3452 writeBandWidth(radioIndex,"20MHz");
3453 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3454 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
3455 }
3456 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
3457 {
3458 writeBandWidth(radioIndex,"40MHz");
3459 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3460 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3461 }
3462 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
3463 {
3464 writeBandWidth(radioIndex,"40MHz");
3465 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3466 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3467 }
3468 else if (strcmp (channelMode,"11ACVHT20") == 0)
3469 {
3470 writeBandWidth(radioIndex,"20MHz");
3471 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3472 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
3473 }
3474 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
3475 {
3476 writeBandWidth(radioIndex,"40MHz");
3477 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3478 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3479 }
3480 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
3481 {
3482 writeBandWidth(radioIndex,"40MHz");
3483 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3484 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3485 }
3486 else if (strcmp (channelMode,"11ACVHT80") == 0)
3487 {
3488 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
3489 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
3490 }
3491 else if (strcmp (channelMode,"11ACVHT160") == 0)
3492 {
3493 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
3494 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
3495 }
3496 else if (strcmp (channelMode,"11B") == 0)
3497 {
3498 writeBandWidth(radioIndex,"20MHz");
3499 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3500 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
3501 }
3502 else if (strcmp (channelMode,"11G") == 0)
3503 {
3504 writeBandWidth(radioIndex,"20MHz");
3505 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3506 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
3507 }
3508 else if (strcmp (channelMode,"11NGHT20") == 0)
3509 {
3510 writeBandWidth(radioIndex,"20MHz");
3511 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3512 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3513 }
3514 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3515 {
3516 writeBandWidth(radioIndex,"40MHz");
3517 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3518 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3519 }
3520 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3521 {
3522 writeBandWidth(radioIndex,"40MHz");
3523 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3524 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3525 }
3526 else
3527 {
3528 return RETURN_ERR;
3529 }
3530 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003531
developera3511852023-06-14 14:12:59 +08003532 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003533}
3534
developer0f10c772023-05-16 21:43:39 +08003535typedef enum _RT_802_11_PHY_MODE {
3536 PHY_11BG_MIXED = 0,
3537 PHY_11B = 1,
3538 PHY_11A = 2,
3539 PHY_11ABG_MIXED = 3,
3540 PHY_11G = 4,
3541 PHY_11ABGN_MIXED = 5, /* both band 5 */
developera3511852023-06-14 14:12:59 +08003542 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3543 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3544 PHY_11AN_MIXED = 8, /* 5G band 8 */
3545 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3546 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3547 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
developer0f10c772023-05-16 21:43:39 +08003548 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3549 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3550 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3551 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3552 PHY_11AX_24G = 16,
3553 PHY_11AX_5G = 17,
3554 PHY_11AX_6G = 18,
3555 PHY_11AX_24G_6G = 19,
3556 PHY_11AX_5G_6G = 20,
3557 PHY_11AX_24G_5G_6G = 21,
3558 PHY_11BE_24G = 22,
3559 PHY_11BE_5G = 23,
3560 PHY_11BE_6G = 24,
3561 PHY_11BE_24G_6G = 25,
3562 PHY_11BE_5G_6G = 26,
3563 PHY_11BE_24G_5G_6G = 27,
3564 PHY_MODE_MAX,
3565} RT_802_11_PHY_MODE;
3566
3567unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3568{
3569 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003570 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003571
3572 band_idx = radio_index_to_band(radioIndex);
3573
3574 switch (band_idx) {
3575 case band_2_4:
3576 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3577 wireless_mode = PHY_11GN_MIXED;
3578 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3579 wireless_mode = PHY_11BGN_MIXED;
3580 if (pureMode & WIFI_MODE_AX)
3581 wireless_mode = PHY_11AX_24G;
3582 if (pureMode & WIFI_MODE_BE)
3583 wireless_mode = PHY_11BE_24G;
3584 break;
3585 case band_5:
3586 if (pureMode == WIFI_MODE_N)
3587 wireless_mode = PHY_11N_5G;
3588 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3589 wireless_mode = PHY_11VHT_N_MIXED;
3590 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3591 wireless_mode = PHY_11VHT_N_A_MIXED;
3592 if (pureMode & WIFI_MODE_AX)
3593 wireless_mode = PHY_11AX_5G;
3594 if (pureMode & WIFI_MODE_BE)
3595 wireless_mode = PHY_11BE_5G;
3596 break;
3597 case band_6:
3598 if (pureMode & WIFI_MODE_AX)
3599 wireless_mode = PHY_11AX_6G;
3600 if (pureMode & WIFI_MODE_BE)
3601 wireless_mode = PHY_11BE_6G;
3602 break;
3603 default:
developer37646972023-06-29 10:58:43 +08003604 if (fprintf(stderr, "%s band_idx invalid\n", __func__) < 0)
3605 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developer0f10c772023-05-16 21:43:39 +08003606 break;
3607 }
3608
3609 return wireless_mode;
3610}
3611
developer72fb0bb2023-01-11 09:46:29 +08003612// Set the radio operating mode, and pure mode flag.
3613INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3614{
developerfead3972023-05-25 20:15:02 +08003615 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003616
developer0f10c772023-05-16 21:43:39 +08003617 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003618 int ret = -1;
3619 unsigned int if_idx = 0;
3620 struct unl unl_ins;
3621 struct nl_msg *msg = NULL;
3622 struct nlattr * msg_data = NULL;
3623 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003624
developer0f10c772023-05-16 21:43:39 +08003625 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003626
developer0f10c772023-05-16 21:43:39 +08003627 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003628
developera3511852023-06-14 14:12:59 +08003629 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08003630 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08003631 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003632 }
developer72fb0bb2023-01-11 09:46:29 +08003633
developer0f10c772023-05-16 21:43:39 +08003634 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08003635 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003636
3637 if_idx = if_nametoindex(interface_name);
3638 if (!if_idx) {
3639 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3640 return RETURN_ERR;
3641 }
3642 /*init mtk nl80211 vendor cmd*/
3643 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3644 param.if_type = NL80211_ATTR_IFINDEX;
3645 param.if_idx = if_idx;
3646
3647 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3648 if (ret) {
3649 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3650 return RETURN_ERR;
3651 }
3652
3653 /*add mtk vendor cmd data*/
3654 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3655 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3656 nlmsg_free(msg);
3657 goto err;
3658 }
3659 /*send mtk nl80211 vendor msg*/
3660 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3661 if (ret) {
3662 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3663 goto err;
3664 }
3665 /*deinit mtk nl80211 vendor msg*/
3666 mtk_nl80211_deint(&unl_ins);
3667 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003668
developera3511852023-06-14 14:12:59 +08003669 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer0f10c772023-05-16 21:43:39 +08003670
developera3511852023-06-14 14:12:59 +08003671 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003672err:
3673 mtk_nl80211_deint(&unl_ins);
3674 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3675 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003676}
3677
3678INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3679{
developerfead3972023-05-25 20:15:02 +08003680 unsigned char wireless_mode = PHY_MODE_MAX;
developera3511852023-06-14 14:12:59 +08003681 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003682 char dat_file[MAX_BUF_SIZE] = {0};
3683 struct params params={0};
developere40952c2023-06-15 18:46:43 +08003684 int res;
developer0f10c772023-05-16 21:43:39 +08003685
3686 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3687
3688 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3689
developera3511852023-06-14 14:12:59 +08003690 if (wireless_mode == PHY_MODE_MAX) {
developer75bd10c2023-06-27 11:34:08 +08003691 wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
developer0f10c772023-05-16 21:43:39 +08003692 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003693 }
developer0f10c772023-05-16 21:43:39 +08003694
3695 params.name = "WirelessMode";
developere40952c2023-06-15 18:46:43 +08003696 res = snprintf(buf, sizeof(buf), "%d", wireless_mode);
3697 if (os_snprintf_error(sizeof(buf), res)) {
3698 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3699 return RETURN_ERR;
3700 }
3701
developera3511852023-06-14 14:12:59 +08003702 params.value = buf;
developer0f10c772023-05-16 21:43:39 +08003703
developere40952c2023-06-15 18:46:43 +08003704 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3705 if (os_snprintf_error(sizeof(dat_file), res)) {
3706 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3707 return RETURN_ERR;
3708 }
developera3511852023-06-14 14:12:59 +08003709 wifi_datfileWrite(dat_file, &params, 1);
developer0f10c772023-05-16 21:43:39 +08003710
developera3511852023-06-14 14:12:59 +08003711 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003712
developera3511852023-06-14 14:12:59 +08003713 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003714}
3715
3716INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3717
developera3511852023-06-14 14:12:59 +08003718 char config_file[64] = {0};
3719 char buf[64] = {0};
3720 struct params params = {0};
3721 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003722 int res;
developer72fb0bb2023-01-11 09:46:29 +08003723
developera3511852023-06-14 14:12:59 +08003724 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003725
developera3511852023-06-14 14:12:59 +08003726 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003727
developera3511852023-06-14 14:12:59 +08003728 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3729 return RETURN_ERR;
3730 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3731 return RETURN_ERR;
3732 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3733 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003734
developer75bd10c2023-06-27 11:34:08 +08003735 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
3736 if (os_snprintf_error(sizeof(config_file), res)) {
3737 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3738 return RETURN_ERR;
3739 }
developera3511852023-06-14 14:12:59 +08003740 params.name = "hw_mode";
3741 params.value = hw_mode;
3742 wifi_hostapdWrite(config_file, &params, 1);
3743 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003744
developera3511852023-06-14 14:12:59 +08003745 if (band == band_2_4) {
3746 if (strncmp(hw_mode, "b", 1) == 0) {
3747 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
developere40952c2023-06-15 18:46:43 +08003748 res = snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3749 if (os_snprintf_error(sizeof(buf), res)) {
3750 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3751 return RETURN_ERR;
3752 }
developera3511852023-06-14 14:12:59 +08003753 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003754 res = snprintf(buf, sizeof(buf), "%s", "1,2");
3755 if (os_snprintf_error(sizeof(buf), res)) {
3756 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3757 return RETURN_ERR;
3758 }
developera3511852023-06-14 14:12:59 +08003759 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3760 } else {
3761 // 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 +08003762
developere40952c2023-06-15 18:46:43 +08003763 res = snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3764 if (os_snprintf_error(sizeof(buf), res)) {
3765 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3766 return RETURN_ERR;
3767 }
developera3511852023-06-14 14:12:59 +08003768 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003769 res = snprintf(buf, sizeof(buf), "%s", "6,12,24");
3770 if (os_snprintf_error(sizeof(buf), res)) {
3771 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3772 return RETURN_ERR;
3773 }
developera3511852023-06-14 14:12:59 +08003774 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3775 }
3776 }
developer72fb0bb2023-01-11 09:46:29 +08003777
developera3511852023-06-14 14:12:59 +08003778 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3779 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003780}
3781
3782INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3783{
developera3511852023-06-14 14:12:59 +08003784 char config_file[64] = {0};
3785 struct params params = {0};
3786 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08003787 int res;
developer72fb0bb2023-01-11 09:46:29 +08003788
developera3511852023-06-14 14:12:59 +08003789 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003790
developera3511852023-06-14 14:12:59 +08003791 band = wifi_index_to_band(radioIndex);
3792 if (band != band_2_4)
3793 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003794
developer75bd10c2023-06-27 11:34:08 +08003795 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
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 params.name = "noscan";
3801 params.value = noscan;
3802 wifi_hostapdWrite(config_file, &params, 1);
3803 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003804
developera3511852023-06-14 14:12:59 +08003805 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3806 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003807}
3808
3809//Get the list of supported channel. eg: "1-11"
3810//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.
3811INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3812{
developera3511852023-06-14 14:12:59 +08003813 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3814 if (NULL == output_string)
3815 return RETURN_ERR;
3816 char cmd[256] = {0};
3817 char buf[128] = {0};
3818 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +08003819 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08003820
developera3511852023-06-14 14:12:59 +08003821 // Parse possible channel number and separate them with commas.
3822 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3823 phyId = radio_index_to_phy(radioIndex);
3824 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3825 if (dfs_enable)
developere40952c2023-06-15 18:46:43 +08003826 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 +08003827 else
developere40952c2023-06-15 18:46:43 +08003828 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 +08003829
developere40952c2023-06-15 18:46:43 +08003830 if (os_snprintf_error(sizeof(cmd), res)) {
3831 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3832 return RETURN_ERR;
3833 }
developera3511852023-06-14 14:12:59 +08003834 _syscmd(cmd,buf,sizeof(buf));
3835 strncpy(output_string, buf, strlen(buf) < sizeof(buf) ? strlen(buf) : sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003836
developera3511852023-06-14 14:12:59 +08003837 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3838 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003839}
developerd1824452023-05-18 12:30:04 +08003840//Getting current radio extension channel
3841INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3842{
developera3511852023-06-14 14:12:59 +08003843 CHAR buf[150] = {0};
developer32f2a182023-06-27 19:50:41 +08003844 int len;
developerd1824452023-05-18 12:30:04 +08003845
developera3511852023-06-14 14:12:59 +08003846 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08003847 if (strncmp(buf, "Below", 5) == 0) {
3848 len = strlen("BelowControlChannel");
3849 memcpy(Value, "BelowControlChannel", len);
3850 }
3851 else if(strncmp(buf, "Above", 5) == 0) {
3852 len = strlen("AboveControlChannel");
3853 memcpy(Value, "AboveControlChannel", len);
3854 }
3855 Value[len] = '\0';
developera3511852023-06-14 14:12:59 +08003856 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08003857}
developerf6a87542023-05-16 15:47:28 +08003858
developer72fb0bb2023-01-11 09:46:29 +08003859//Get the list for used channel. eg: "1,6,9,11"
3860//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.
3861INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3862{
developera3511852023-06-14 14:12:59 +08003863 char interface_name[16] = {0};
3864 char cmd[128] = {0};
3865 char buf[128] = {0};
3866 char config_file[64] = {0};
3867 int channel = 0;
3868 int freq = 0;
3869 int bandwidth = 0;
3870 int center_freq = 0;
3871 int center_channel = 0;
3872 int channel_delta = 0;
3873 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003874 int res;
developer72fb0bb2023-01-11 09:46:29 +08003875
developera3511852023-06-14 14:12:59 +08003876 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003877
developera3511852023-06-14 14:12:59 +08003878 if (NULL == output_string)
3879 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003880
developera3511852023-06-14 14:12:59 +08003881 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3882 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08003883
3884 res = snprintf(cmd, sizeof(cmd), "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3885 if (os_snprintf_error(sizeof(cmd), res)) {
3886 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3887 return RETURN_ERR;
3888 }
developera3511852023-06-14 14:12:59 +08003889 _syscmd(cmd, buf, sizeof(buf));
3890 if (strlen(buf) == 0) {
developer75bd10c2023-06-27 11:34:08 +08003891 wifi_debug(DEBUG_ERROR, "failed to get channel information from iw.\n");
developera3511852023-06-14 14:12:59 +08003892 return RETURN_ERR;
3893 }
developerd14dff12023-06-28 22:47:44 +08003894 if (sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq) != 4) {
3895 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
3896 return RETURN_ERR;
3897 }
developer72fb0bb2023-01-11 09:46:29 +08003898
developera3511852023-06-14 14:12:59 +08003899 if (bandwidth == 20) {
developere40952c2023-06-15 18:46:43 +08003900 res = snprintf(output_string, 256, "%d", channel);
3901 if (os_snprintf_error(256, res)) {
3902 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3903 return RETURN_ERR;
3904 }
developera3511852023-06-14 14:12:59 +08003905 return RETURN_OK;
3906 }
developer72fb0bb2023-01-11 09:46:29 +08003907
developera3511852023-06-14 14:12:59 +08003908 center_channel = ieee80211_frequency_to_channel(center_freq);
developer72fb0bb2023-01-11 09:46:29 +08003909
developera3511852023-06-14 14:12:59 +08003910 band = wifi_index_to_band(radioIndex);
3911 if (band == band_2_4 && bandwidth == 40) {
developer32f2a182023-06-27 19:50:41 +08003912 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3913 if (os_snprintf_error(sizeof(config_file), res)) {
3914 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3915 return RETURN_ERR;
3916 }
developera3511852023-06-14 14:12:59 +08003917 memset(buf, 0, sizeof(buf));
3918 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
developer72fb0bb2023-01-11 09:46:29 +08003919
developera3511852023-06-14 14:12:59 +08003920 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
developere40952c2023-06-15 18:46:43 +08003921 res = snprintf(output_string, 256, "%d,%d", channel, channel+4);
developera3511852023-06-14 14:12:59 +08003922 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
developere40952c2023-06-15 18:46:43 +08003923 res = snprintf(output_string, 256, "%d,%d", channel-4, channel);
developera3511852023-06-14 14:12:59 +08003924 } else {
developer37646972023-06-29 10:58:43 +08003925 if (fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf) < 0)
3926 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08003927 return RETURN_ERR;
3928 }
developerb758dfd2023-06-21 17:32:07 +08003929
developere40952c2023-06-15 18:46:43 +08003930 if (os_snprintf_error(256, res)) {
3931 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3932 return RETURN_ERR;
3933 }
developera3511852023-06-14 14:12:59 +08003934 } else if (band == band_5 || band == band_6){
3935 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
3936 // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6.
3937 channel_delta = (bandwidth-20)/10;
3938 memset(output_string, 0, 256);
3939 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3940 // If i is not the last channel, we add a comma.
developere40952c2023-06-15 18:46:43 +08003941 res = snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
developer32f2a182023-06-27 19:50:41 +08003942
developere40952c2023-06-15 18:46:43 +08003943 if (os_snprintf_error(sizeof(buf), res)) {
3944 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3945 return RETURN_ERR;
3946 }
developer32f2a182023-06-27 19:50:41 +08003947 strncat(output_string, buf, sizeof(output_string) - strlen(output_string) - 1);
developera3511852023-06-14 14:12:59 +08003948 }
3949 } else
3950 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003951
developera3511852023-06-14 14:12:59 +08003952 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3953 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003954}
3955
developer69b61b02023-03-07 17:17:44 +08003956//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003957INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003958{
developera3511852023-06-14 14:12:59 +08003959 char channel_str[16] = {0};
3960 char config_file[128] = {0};
3961 char buf[MAX_BUF_SIZE] = {0};
3962 char cmd[MAX_CMD_SIZE] = {0};
3963 char interface_name[IF_NAME_SIZE] = {0};
3964 wifi_band band = band_invalid;
3965 ULONG iwChannel = 0;
developere40952c2023-06-15 18:46:43 +08003966 int res;
developer47a56bf2023-05-30 13:38:57 +08003967
developera3511852023-06-14 14:12:59 +08003968 if (output_ulong == NULL)
3969 return RETURN_ERR;
3970 band = wifi_index_to_band(radioIndex);
developerb758dfd2023-06-21 17:32:07 +08003971 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08003972 if (os_snprintf_error(sizeof(config_file), res)) {
3973 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3974 return RETURN_ERR;
3975 }
3976
developera3511852023-06-14 14:12:59 +08003977 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
3978 *output_ulong = strtoul(channel_str, NULL, 10);
3979 if (*output_ulong == 0) {
3980 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3981 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08003982 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
3983 if (os_snprintf_error(sizeof(cmd), res)) {
3984 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3985 return RETURN_ERR;
3986 }
3987
developera3511852023-06-14 14:12:59 +08003988 _syscmd(cmd,buf,sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08003989 if (sscanf(buf, "%lu", &iwChannel) != 1) {
3990 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
3991 return RETURN_ERR;
3992 }
developera3511852023-06-14 14:12:59 +08003993 *output_ulong = iwChannel;
3994 }
developer72fb0bb2023-01-11 09:46:29 +08003995
developera3511852023-06-14 14:12:59 +08003996 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003997}
3998
developer72fb0bb2023-01-11 09:46:29 +08003999INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
4000{
developera3511852023-06-14 14:12:59 +08004001 char cmd[1024] = {0}, buf[5] = {0};
4002 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08004003 int res;
developer72fb0bb2023-01-11 09:46:29 +08004004
developera3511852023-06-14 14:12:59 +08004005 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4006 if (NULL == output_ulong)
4007 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004008
developera3511852023-06-14 14:12:59 +08004009 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
4010 return RETURN_ERR;
developer47a56bf2023-05-30 13:38:57 +08004011
developere40952c2023-06-15 18:46:43 +08004012 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
4013 if (os_snprintf_error(sizeof(cmd), res)) {
4014 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4015 return RETURN_ERR;
4016 }
developera3511852023-06-14 14:12:59 +08004017 _syscmd(cmd,buf,sizeof(buf));
4018 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
4019 if (*output_ulong == 0) {
4020 return RETURN_ERR;
4021 }
developer72fb0bb2023-01-11 09:46:29 +08004022
developera3511852023-06-14 14:12:59 +08004023 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4024 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004025}
developer72fb0bb2023-01-11 09:46:29 +08004026//Storing the previous channel value
4027INT wifi_storeprevchanval(INT radioIndex)
4028{
developera3511852023-06-14 14:12:59 +08004029 char buf[256] = {0};
4030 char output[4]={'\0'};
4031 char config_file[MAX_BUF_SIZE] = {0};
4032 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004033 int res;
developerd1824452023-05-18 12:30:04 +08004034
developera3511852023-06-14 14:12:59 +08004035 band = wifi_index_to_band(radioIndex);
4036 if (band == band_invalid) {
4037 return RETURN_ERR;
4038 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
4039 }
developere40952c2023-06-15 18:46:43 +08004040 res = snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
4041 if (os_snprintf_error(sizeof(config_file), res)) {
4042 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4043 return RETURN_ERR;
4044 }
4045
developera3511852023-06-14 14:12:59 +08004046 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
developerd1824452023-05-18 12:30:04 +08004047
developera3511852023-06-14 14:12:59 +08004048 if(band == band_2_4)
developer75bd10c2023-06-27 11:34:08 +08004049 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developera3511852023-06-14 14:12:59 +08004050 else if(band == band_5)
developer75bd10c2023-06-27 11:34:08 +08004051 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developera3511852023-06-14 14:12:59 +08004052 else
developer75bd10c2023-06-27 11:34:08 +08004053 res = snprintf(buf, sizeof(buf), "%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
4054
4055 if (os_snprintf_error(sizeof(buf), res)) {
4056 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4057 return RETURN_ERR;
4058 }
developera3511852023-06-14 14:12:59 +08004059 system(buf);
4060 Radio_flag = FALSE;
4061 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004062}
4063
4064//Set the running channel number
4065INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
4066{
developera3511852023-06-14 14:12:59 +08004067 // We only write hostapd config here
4068 char str_channel[8]={0};
4069 char *list_channel;
4070 char possible_channels[256] = {0};
4071 char config_file_dat[128] = {0};
4072 struct params dat = {0};
4073 struct params acs = {0};
4074 wifi_band band = band_invalid;
4075 bool acs_channel = false;
developere40952c2023-06-15 18:46:43 +08004076 int res;
developer72fb0bb2023-01-11 09:46:29 +08004077
developera3511852023-06-14 14:12:59 +08004078 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004079
developera3511852023-06-14 14:12:59 +08004080 if (channel == 0)
4081 acs_channel = true;
4082 // Check valid
developer75bd10c2023-06-27 11:34:08 +08004083 res = snprintf(str_channel, sizeof(str_channel), "%lu", channel);
4084 if (os_snprintf_error(sizeof(str_channel), res)) {
4085 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4086 return RETURN_ERR;
4087 }
developer47a56bf2023-05-30 13:38:57 +08004088
developera3511852023-06-14 14:12:59 +08004089 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
4090 list_channel = strtok(possible_channels, ",");
4091 while(true)
4092 {
4093 if(list_channel == NULL) { // input not in the list
developer75bd10c2023-06-27 11:34:08 +08004094 wifi_debug(DEBUG_ERROR, "Channel %s is not in possible list\n", str_channel);
developera3511852023-06-14 14:12:59 +08004095 return RETURN_ERR;
4096 }
4097 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
4098 break;
4099 list_channel = strtok(NULL, ",");
4100 }
4101 /*
4102 list.name = "channel";
4103 list.value = str_channel;
4104 wifi_getMaxRadioNumber(&max_radio_num);
4105 for(int i=0; i<=MAX_APS/max_radio_num;i++)
4106 {
4107 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
4108 wifi_hostapdWrite(config_file, &list, 1);
4109 }
4110 */
4111 dat.name = "Channel";
4112 dat.value = str_channel;
4113 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004114 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4115 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4116 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4117 return RETURN_ERR;
4118 }
4119
developera3511852023-06-14 14:12:59 +08004120 wifi_datfileWrite(config_file_dat, &dat, 1);
4121 if (acs_channel == true) {
4122 acs.name = "AutoChannelSelect";
4123 acs.value = "3";
4124 } else {
4125 acs.name = "AutoChannelSelect";
4126 acs.value = "0";
4127 }
4128 wifi_datfileWrite(config_file_dat, &acs, 1);
4129 wifi_reloadAp(radioIndex);
4130 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4131 return RETURN_OK;
4132}
4133
4134INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
4135{
4136 struct params list[2];
4137 char str_idx[16];
4138 char config_file[64];
developere40952c2023-06-15 18:46:43 +08004139 int max_num_radios = 0, res;
developera3511852023-06-14 14:12:59 +08004140 wifi_band band = band_invalid;
4141
4142 band = wifi_index_to_band(radioIndex);
4143 if (band == band_2_4)
4144 return RETURN_OK;
4145
developere40952c2023-06-15 18:46:43 +08004146 res = snprintf(str_idx, sizeof(str_idx), "%lu", channel);
4147 if (os_snprintf_error(sizeof(str_idx), res)) {
4148 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4149 return RETURN_ERR;
4150 }
4151
developera3511852023-06-14 14:12:59 +08004152 list[0].name = "vht_oper_centr_freq_seg0_idx";
4153 list[0].value = str_idx;
4154 list[1].name = "he_oper_centr_freq_seg0_idx";
4155 list[1].value = str_idx;
4156
4157 wifi_getMaxRadioNumber(&max_num_radios);
developer9ce44382023-06-28 11:09:37 +08004158 if(max_num_radios== 0){
4159 return RETURN_ERR;
4160 }
developera3511852023-06-14 14:12:59 +08004161 for(int i=0; i<=MAX_APS/max_num_radios; i++)
4162 {
developere40952c2023-06-15 18:46:43 +08004163 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
4164 if (os_snprintf_error(sizeof(config_file), res)) {
4165 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4166 return RETURN_ERR;
4167 }
developera3511852023-06-14 14:12:59 +08004168 if (band == band_6)
4169 wifi_hostapdWrite(config_file, &list[1], 1);
4170 else
4171 wifi_hostapdWrite(config_file, list, 2);
4172 }
4173
4174 return RETURN_OK;
4175}
4176
4177//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
4178//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
4179INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
4180{
4181 //Set to wifi config only. Wait for wifi reset to apply.
4182 ULONG Value = 0;
4183 char config_file_dat[128] = {0};
4184 struct params acs = {0};
4185 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004186 int res;
developera3511852023-06-14 14:12:59 +08004187
4188 if(enable == TRUE) {
4189 wifi_setRadioChannel(radioIndex,Value);
4190 } else {
4191 acs.name = "AutoChannelSelect";
4192 acs.value = "0";
4193 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004194 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4195 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4196 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4197 return RETURN_ERR;
4198 }
developera3511852023-06-14 14:12:59 +08004199 wifi_datfileWrite(config_file_dat, &acs, 1);
4200 }
4201 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004202}
4203
4204INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
4205{
developera3511852023-06-14 14:12:59 +08004206 if (output_bool == NULL)
4207 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004208
developera3511852023-06-14 14:12:59 +08004209 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004210
developera3511852023-06-14 14:12:59 +08004211 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004212}
4213
4214INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
4215{
developera3511852023-06-14 14:12:59 +08004216 if (NULL == output_bool)
4217 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004218 *output_bool=TRUE;
developera3511852023-06-14 14:12:59 +08004219 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004220}
4221
4222INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
4223{
developer326d4232023-06-15 16:45:30 +08004224 unsigned long period = 0;
4225
developera3511852023-06-14 14:12:59 +08004226 if (NULL == output_bool)
4227 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004228
4229 if (wifi_getRadioAutoChannelRefreshPeriod(radioIndex, &period) != RETURN_OK)
developerb758dfd2023-06-21 17:32:07 +08004230 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08004231
4232 *output_bool = (period > 0) ? TRUE : FALSE;
4233
developera3511852023-06-14 14:12:59 +08004234 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004235}
4236
developer326d4232023-06-15 16:45:30 +08004237INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08004238{
developer326d4232023-06-15 16:45:30 +08004239 ULONG period = 1800;
4240
4241 if (enable == TRUE) {
4242 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, period) != RETURN_OK)
4243 return RETURN_ERR;
4244 }
4245 else {
4246 if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, 0) != RETURN_OK)
4247 return RETURN_ERR;
4248 }
developera3511852023-06-14 14:12:59 +08004249 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004250}
4251
4252INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
4253{
developera3511852023-06-14 14:12:59 +08004254 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004255}
4256
4257INT wifi_factoryResetAP(int apIndex)
4258{
developerb149d9d2023-06-06 16:14:22 +08004259 char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08004260 char cmd[MAX_CMD_SIZE] = {0};
4261 char ret_buf[MAX_BUF_SIZE] = {0};
4262 int radio_idx = 0;
4263 int bss_idx = 0;
4264 char ssid[32] = {0};
4265 char interface[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08004266 char psk_file[MAX_SUB_CMD_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08004267 struct params params[3] = {0};
developere40952c2023-06-15 18:46:43 +08004268 int res;
developer72fb0bb2023-01-11 09:46:29 +08004269
developera3511852023-06-14 14:12:59 +08004270 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004271
developer47cc27a2023-05-17 23:09:58 +08004272 /*del old config file*/
developer9ce44382023-06-28 11:09:37 +08004273 res = snprintf(ap_config_file, sizeof(ap_config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd14dff12023-06-28 22:47:44 +08004274 if (os_snprintf_error(sizeof(ap_config_file), res)) {
developere40952c2023-06-15 18:46:43 +08004275 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4276 return RETURN_ERR;
4277 }
4278
4279 res = snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
4280 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4281 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4282 return RETURN_ERR;
4283 }
4284
developer47cc27a2023-05-17 23:09:58 +08004285 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08004286
developer47cc27a2023-05-17 23:09:58 +08004287 memset(cmd, 0, sizeof(cmd));
4288 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08004289
developer47cc27a2023-05-17 23:09:58 +08004290 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
4291
4292 /*prepare new config file*/
developere40952c2023-06-15 18:46:43 +08004293 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
4294 if (os_snprintf_error(sizeof(cmd), res)) {
4295 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4296 return RETURN_ERR;
4297 }
4298
developer47cc27a2023-05-17 23:09:58 +08004299 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4300
4301 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08004302 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
4303 if (os_snprintf_error(sizeof(ssid), res)) {
4304 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4305 return RETURN_ERR;
4306 }
4307
4308 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
4309 if (os_snprintf_error(sizeof(interface), res)) {
4310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4311 return RETURN_ERR;
4312 }
developer47cc27a2023-05-17 23:09:58 +08004313 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08004314 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
4315 if (os_snprintf_error(sizeof(ssid), res)) {
4316 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4317 return RETURN_ERR;
4318 }
4319
4320 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
4321 if (os_snprintf_error(sizeof(interface), res)) {
4322 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4323 return RETURN_ERR;
4324 }
developer47cc27a2023-05-17 23:09:58 +08004325 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08004326 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
4327 if (os_snprintf_error(sizeof(ssid), res)) {
4328 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4329 return RETURN_ERR;
4330 }
4331
4332 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
4333 if (os_snprintf_error(sizeof(interface), res)) {
4334 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4335 return RETURN_ERR;
4336 }
developer47cc27a2023-05-17 23:09:58 +08004337 }
4338
4339 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08004340 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
4341 if (os_snprintf_error(sizeof(psk_file), res)) {
4342 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4343 return RETURN_ERR;
4344 }
developer47cc27a2023-05-17 23:09:58 +08004345
4346 params[0].name = "ssid";
4347 params[0].value = ssid;
4348 params[1].name = "interface";
4349 params[1].value = interface;
4350 params[2].name = "wpa_psk_file";
4351 params[2].value = psk_file;
4352
4353 wifi_hostapdWrite(ap_config_file, params, 3);
4354
4355 /*clear psk file*/
4356 memset(cmd, 0, sizeof(cmd));
4357 memset(ret_buf, 0, sizeof(ret_buf));
4358
developere40952c2023-06-15 18:46:43 +08004359 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
4360 if (os_snprintf_error(sizeof(psk_file), res)) {
4361 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4362 return RETURN_ERR;
4363 }
developer47cc27a2023-05-17 23:09:58 +08004364
4365 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08004366 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
4367 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4368 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4369 return RETURN_ERR;
4370 }
4371
developer47cc27a2023-05-17 23:09:58 +08004372 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4373 } else {
developere40952c2023-06-15 18:46:43 +08004374 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
4375 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
4376 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4377 return RETURN_ERR;
4378 }
4379
developer47cc27a2023-05-17 23:09:58 +08004380 _syscmd(cmd, ret_buf, sizeof(ret_buf));
4381 }
4382
developer429ba832023-05-31 11:03:35 +08004383 wifi_setApEnable(apIndex, FALSE);
4384 wifi_setApEnable(apIndex, TRUE);
developer47cc27a2023-05-17 23:09:58 +08004385 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4386
4387 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004388}
4389
developer72fb0bb2023-01-11 09:46:29 +08004390INT wifi_setBandSteeringApGroup(char *ApGroup)
4391{
developera3511852023-06-14 14:12:59 +08004392 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004393}
4394
4395INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
4396{
developera3511852023-06-14 14:12:59 +08004397 char config_file[128] = {'\0'};
4398 char buf[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004399 int res;
developer72fb0bb2023-01-11 09:46:29 +08004400
developera3511852023-06-14 14:12:59 +08004401 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4402 if (dtimInterval == NULL)
4403 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004404
4405 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
4406 if (os_snprintf_error(sizeof(config_file), res)) {
4407 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4408 return RETURN_ERR;
4409 }
developer72fb0bb2023-01-11 09:46:29 +08004410
developera3511852023-06-14 14:12:59 +08004411 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004412
developera3511852023-06-14 14:12:59 +08004413 if (strlen(buf) == 0) {
4414 *dtimInterval = 2;
4415 } else {
4416 *dtimInterval = strtoul(buf, NULL, 10);
developerd14dff12023-06-28 22:47:44 +08004417 if (*dtimInterval == 0 && buf[0] != '0') {
4418 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
4419 return RETURN_ERR;
4420 }
developera3511852023-06-14 14:12:59 +08004421 }
developer72fb0bb2023-01-11 09:46:29 +08004422
developera3511852023-06-14 14:12:59 +08004423 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4424 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004425}
4426
4427INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
4428{
developera3511852023-06-14 14:12:59 +08004429 struct params params={0};
4430 char config_file[MAX_BUF_SIZE] = {'\0'};
4431 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004432 int res;
developer72fb0bb2023-01-11 09:46:29 +08004433
developera3511852023-06-14 14:12:59 +08004434 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4435 if (dtimInterval < 1 || dtimInterval > 255) {
4436 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
4437 return RETURN_ERR;
4438 }
developer69b61b02023-03-07 17:17:44 +08004439
developera3511852023-06-14 14:12:59 +08004440 params.name = "dtim_period";
developere40952c2023-06-15 18:46:43 +08004441 res = snprintf(buf, sizeof(buf), "%d", dtimInterval);
4442 if (os_snprintf_error(sizeof(buf), res)) {
4443 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4444 return RETURN_ERR;
4445 }
developera3511852023-06-14 14:12:59 +08004446 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08004447
developer75bd10c2023-06-27 11:34:08 +08004448 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
4449 if (os_snprintf_error(sizeof(config_file), res)) {
4450 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4451 return RETURN_ERR;
4452 }
developera3511852023-06-14 14:12:59 +08004453 wifi_hostapdWrite(config_file, &params, 1);
4454 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08004455
developera3511852023-06-14 14:12:59 +08004456 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4457 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004458}
4459
4460//Check if the driver support the Dfs
4461INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
4462{
developera3511852023-06-14 14:12:59 +08004463 wifi_band band = band_invalid;
4464 if (NULL == output_bool)
4465 return RETURN_ERR;
4466 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +08004467
developera3511852023-06-14 14:12:59 +08004468 band = wifi_index_to_band(radioIndex);
4469 if (band == band_5)
4470 *output_bool = TRUE;
4471 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004472}
4473
4474//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.
4475//The value of this parameter is a comma seperated list of channel number
4476INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
4477{
developer326d4232023-06-15 16:45:30 +08004478
4479 #define CHANNEL_AVAILABLE 0
4480 #define CHANNEL_INVALID 1
4481 #define CHANNEL_LIST_MAX_LENGTH 256
4482 #define MAX_CHANNEL_NUMBER 255
4483
4484 char config_file[MAX_BUF_SIZE] = {0};
4485 char possible_channels[CHANNEL_LIST_MAX_LENGTH] = {0};
4486 char skip_list[CHANNEL_LIST_MAX_LENGTH] = {0};
4487 int skip_table[MAX_CHANNEL_NUMBER +1] = {0};
4488 wifi_band band = band_invalid;
4489 char *token_channel = NULL, *token_skip = NULL;
developer75bd10c2023-06-27 11:34:08 +08004490 int res;
developere40952c2023-06-15 18:46:43 +08004491
developera3511852023-06-14 14:12:59 +08004492 if (NULL == output_pool)
4493 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004494 // get skiplist, possible_channels list
4495 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
4496 band = wifi_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08004497 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4498 if (os_snprintf_error(sizeof(config_file), res)) {
4499 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4500 return RETURN_ERR;
4501 }
developer326d4232023-06-15 16:45:30 +08004502 wifi_datfileRead(config_file, "AutoChannelSkipList", skip_list, sizeof(skip_list));
4503
4504 if (skip_list[0] != '\0') {
4505 int len = strlen(skip_list);
4506 for (int i = 0; i < len; i++) {
4507 if (skip_list[i] == ';') {
4508 skip_list[i] = ',';
4509 }
4510 }
4511 // skip list
4512 token_skip = strtok(skip_list, ",");
4513 while (token_skip != NULL) {
4514 int channel = atoi(token_skip);
4515 if (channel <= MAX_CHANNEL_NUMBER && strstr(possible_channels, token_skip) != NULL)
4516 skip_table[atoi(token_skip)] = CHANNEL_INVALID;
4517 token_skip = strtok(NULL, ",");
4518 }
developere40952c2023-06-15 18:46:43 +08004519 }
developer72fb0bb2023-01-11 09:46:29 +08004520
developer326d4232023-06-15 16:45:30 +08004521 int count = 0;
4522 token_channel = strtok(possible_channels, ",");
4523 while (token_channel != NULL) {
4524 int channel = atoi(token_channel);
4525 if (channel <= MAX_CHANNEL_NUMBER && skip_table[channel] == CHANNEL_AVAILABLE) {
4526 count += snprintf(&output_pool[count], CHANNEL_LIST_MAX_LENGTH-count, "%d,", channel);
4527 if (count >= CHANNEL_LIST_MAX_LENGTH-1)
4528 break;
4529 }
4530 token_channel = strtok(NULL, ",");
4531 }
4532 //delete the last one ','
4533 if (count >0 && output_pool[count-1] == ',')
4534 output_pool[count-1] = '\0';
developera3511852023-06-14 14:12:59 +08004535 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004536}
4537
4538INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
4539{
developer326d4232023-06-15 16:45:30 +08004540 char config_file_dat[128] = {0};
4541 struct params dat = {0};
4542 wifi_band band = band_invalid;
4543 char new_pool[128] = {0};
developer75bd10c2023-06-27 11:34:08 +08004544 int res;
developer326d4232023-06-15 16:45:30 +08004545
4546 if (NULL == pool)
4547 return RETURN_ERR;
4548
developer9ce44382023-06-28 11:09:37 +08004549 strncpy(new_pool, pool, sizeof(new_pool) - 1);
4550 new_pool[sizeof(new_pool) - 1] = '\0';
developer326d4232023-06-15 16:45:30 +08004551 for (int i = 0; new_pool[i] != '\0'; i++) {
4552 if (new_pool[i] == ',')
4553 new_pool[i] = ';';
4554 }
4555
4556 dat.name = "AutoChannelSkipList";
4557 dat.value = new_pool;
4558 band = wifi_index_to_band(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08004559 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4560 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4561 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4562 return RETURN_ERR;
4563 }
developer326d4232023-06-15 16:45:30 +08004564 if (wifi_datfileWrite(config_file_dat, &dat, 1) != 0)
4565 return RETURN_ERR;
4566 wifi_reloadAp(radioIndex);
4567
developera3511852023-06-14 14:12:59 +08004568 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004569}
4570
4571INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
4572{
developera3511852023-06-14 14:12:59 +08004573 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
4574 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004575 //Should refresh period time be filled in here? output_interval_seconds is INT type
4576 //wifi_getRadioAutoChannelRefreshPeriod is Ulong type
4577 *output_interval_seconds = 1800;
4578 *output_dwell_milliseconds = 200;
developer72fb0bb2023-01-11 09:46:29 +08004579
developera3511852023-06-14 14:12:59 +08004580 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004581}
4582
4583INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
4584{
developera3511852023-06-14 14:12:59 +08004585 //Set to wifi config. And apply instantly.
4586 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004587}
4588
4589INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
4590{
developera3511852023-06-14 14:12:59 +08004591 if (output_bool == NULL)
4592 return RETURN_ERR;
4593 *output_bool = true;
4594 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004595}
4596
4597INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
4598{
developera3511852023-06-14 14:12:59 +08004599 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004600}
4601
4602//Get the Dfs enable status
4603INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
4604{
developera3511852023-06-14 14:12:59 +08004605 char buf[16] = {0};
4606 char config_file_dat[128] = {0};
4607 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004608 int res;
developer72fb0bb2023-01-11 09:46:29 +08004609
developera3511852023-06-14 14:12:59 +08004610 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004611
developera3511852023-06-14 14:12:59 +08004612 if (output_bool == NULL)
4613 return RETURN_ERR;
4614 *output_bool = TRUE; // default
4615 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004616 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4617 if (os_snprintf_error(sizeof(config_file_dat), res)) {
4618 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4619 return RETURN_ERR;
4620 }
developerd1824452023-05-18 12:30:04 +08004621
developera3511852023-06-14 14:12:59 +08004622 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08004623
developera3511852023-06-14 14:12:59 +08004624 if (strncmp(buf, "0", 1) == 0)
4625 *output_bool = FALSE;
4626 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4627 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004628}
4629
4630//Set the Dfs enable status
4631INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
4632{
developera3511852023-06-14 14:12:59 +08004633 char config_dat_file[128] = {0};
4634 FILE *f = NULL;
4635 struct params dat = {0};
4636 wifi_band band = band_invalid;
developer75bd10c2023-06-27 11:34:08 +08004637 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +08004638
developera3511852023-06-14 14:12:59 +08004639 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004640
developera3511852023-06-14 14:12:59 +08004641 f = fopen(DFS_ENABLE_FILE, "w");
4642 if (f == NULL)
4643 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08004644 ret = fprintf(f, "%d", enable);
4645 if (ret < 0)
4646 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developerd14dff12023-06-28 22:47:44 +08004647 if (fclose(f) != 0) {
4648 wifi_debug(DEBUG_ERROR, "fclose fail\n");
4649 return RETURN_ERR;
4650 }
developer72fb0bb2023-01-11 09:46:29 +08004651
developera3511852023-06-14 14:12:59 +08004652 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08004653
developera3511852023-06-14 14:12:59 +08004654 dat.name = "DfsEnable";
4655 dat.value = enable?"1":"0";
4656 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004657 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4658 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4659 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4660 return RETURN_ERR;
4661 }
4662
developera3511852023-06-14 14:12:59 +08004663 wifi_datfileWrite(config_dat_file, &dat, 1);
4664 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4665 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004666}
4667
4668//Check if the driver support the AutoChannelRefreshPeriod
4669INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
4670{
developera3511852023-06-14 14:12:59 +08004671 if (NULL == output_bool)
4672 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004673 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004674
developera3511852023-06-14 14:12:59 +08004675 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004676}
4677
developer326d4232023-06-15 16:45:30 +08004678
4679int get_ACS_RefreshPeriod_callback(struct nl_msg *msg, void *arg)
4680{
4681 ULONG *data = (ULONG *)arg;
4682 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4683 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
4684 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4685 int err = 0;
4686
4687 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4688 genlmsg_attrlen(gnlh, 0), NULL);
4689 if (err < 0)
4690 return NL_SKIP;
4691
4692 if (tb[NL80211_ATTR_VENDOR_DATA]) {
4693 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
4694 tb[NL80211_ATTR_VENDOR_DATA], NULL);
4695 if (err < 0)
4696 return NL_SKIP;
4697
4698 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]) {
4699 *data = nla_get_u32(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]);
4700 }
4701 }
4702
4703 return NL_OK;
4704}
4705
developer72fb0bb2023-01-11 09:46:29 +08004706//Get the ACS refresh period in seconds
4707INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
4708{
developer326d4232023-06-15 16:45:30 +08004709 char interface_name[IF_NAME_SIZE] = {0};
4710 int ret = -1;
4711 unsigned int if_idx = 0;
4712 struct unl unl_ins;
4713 struct nl_msg *msg = NULL;
4714 struct nlattr * msg_data = NULL;
4715 struct mtk_nl80211_param param;
4716 unsigned long checktime = 0;
4717
4718 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08004719 if (NULL == output_ulong)
4720 return RETURN_ERR;
developer326d4232023-06-15 16:45:30 +08004721
4722 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4723 return RETURN_ERR;
4724
4725 if_idx = if_nametoindex(interface_name);
4726 if (!if_idx) {
4727 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4728 return RETURN_ERR;
4729 }
4730 /*init mtk nl80211 vendor cmd*/
4731 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
4732 param.if_type = NL80211_ATTR_IFINDEX;
4733 param.if_idx = if_idx;
developer72fb0bb2023-01-11 09:46:29 +08004734
developer326d4232023-06-15 16:45:30 +08004735 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4736 if (ret) {
4737 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4738 return RETURN_ERR;
4739 }
4740
4741 /*add mtk vendor cmd data*/
4742 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD, 0)) {
4743 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD attribute error\n");
4744 nlmsg_free(msg);
4745 goto err;
4746 }
4747
4748 /*send mtk nl80211 vendor msg*/
4749 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ACS_RefreshPeriod_callback, &checktime);
4750
4751 if (ret) {
4752 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4753 goto err;
4754 }
4755 /*deinit mtk nl80211 vendor msg*/
4756 mtk_nl80211_deint(&unl_ins);
4757 *output_ulong = checktime;
4758 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
4759
4760 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera3511852023-06-14 14:12:59 +08004761 return RETURN_OK;
developer326d4232023-06-15 16:45:30 +08004762err:
4763 mtk_nl80211_deint(&unl_ins);
4764 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
4765 return RETURN_ERR;
4766
developer72fb0bb2023-01-11 09:46:29 +08004767}
4768
4769//Set the ACS refresh period in seconds
4770INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
4771{
developer326d4232023-06-15 16:45:30 +08004772 char interface_name[IF_NAME_SIZE] = {0};
4773 int ret = -1;
4774 unsigned int if_idx = 0;
4775 struct unl unl_ins;
4776 struct nl_msg *msg = NULL;
4777 struct nlattr * msg_data = NULL;
4778 struct mtk_nl80211_param param;
4779
4780 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4781
4782 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4783 return RETURN_ERR;
4784
4785 if_idx = if_nametoindex(interface_name);
4786 if (!if_idx) {
4787 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
4788 return RETURN_ERR;
4789 }
4790 /*init mtk nl80211 vendor cmd*/
4791 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
4792 param.if_type = NL80211_ATTR_IFINDEX;
4793 param.if_idx = if_idx;
4794
4795 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4796 if (ret) {
4797 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4798 return RETURN_ERR;
4799 }
4800
4801 /*add mtk vendor cmd data*/
4802 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
4803 wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME attribute error\n");
4804 nlmsg_free(msg);
4805 goto err;
4806 }
4807
4808 /*send mtk nl80211 vendor msg*/
4809 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4810
4811 if (ret) {
4812 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4813 goto err;
4814 }
4815 /*deinit mtk nl80211 vendor msg*/
4816 mtk_nl80211_deint(&unl_ins);
4817 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
4818
4819 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4820 return RETURN_OK;
4821err:
4822 mtk_nl80211_deint(&unl_ins);
4823 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developera3511852023-06-14 14:12:59 +08004824 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004825}
4826
4827//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
4828//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.
4829INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
4830{
developera3511852023-06-14 14:12:59 +08004831 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
4832 char extchannel[128] = {0};
4833 char interface_name[64] = {0};
developere40952c2023-06-15 18:46:43 +08004834 int ret = 0, len=0, res;
developera3511852023-06-14 14:12:59 +08004835 BOOL radio_enable = FALSE;
4836 wifi_band band;
developer72fb0bb2023-01-11 09:46:29 +08004837
developera3511852023-06-14 14:12:59 +08004838 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004839
developera3511852023-06-14 14:12:59 +08004840 if (NULL == output_string) {
4841 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
4842 return RETURN_ERR;
4843 }
4844 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
4845 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
4846 return RETURN_ERR;
4847 }
4848 if (radio_enable != TRUE) {
4849 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
4850 return RETURN_OK;
4851 }
4852 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4853 return RETURN_ERR;
4854 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08004855
developere40952c2023-06-15 18:46:43 +08004856 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
4857 if (os_snprintf_error(sizeof(cmd), res)) {
4858 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4859 return RETURN_ERR;
4860 }
developera3511852023-06-14 14:12:59 +08004861 ret = _syscmd(cmd, buf, sizeof(buf));
4862 len = strlen(buf);
4863 if((ret != 0) || (len == 0))
4864 {
4865 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4866 return RETURN_ERR;
4867 }
developer8666b312023-03-24 14:05:31 +08004868
developera3511852023-06-14 14:12:59 +08004869 band = wifi_index_to_band(radioIndex);
4870 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
4871 wifi_getRadioExtChannel(radioIndex, extchannel);
developere40952c2023-06-15 18:46:43 +08004872 if (strncmp(extchannel, "Auto", 4) != 0) {
4873 res = snprintf(buf, sizeof(buf), "40");
4874 if (os_snprintf_error(sizeof(buf), res)) {
4875 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4876 return RETURN_ERR;
4877 }
4878 }
4879 }
4880 res = snprintf(output_string, 64, "%sMHz", buf);
4881 if (os_snprintf_error(64, res)) {
4882 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4883 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08004884 }
developera3511852023-06-14 14:12:59 +08004885 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004886
developera3511852023-06-14 14:12:59 +08004887 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004888}
4889
4890enum mwctl_chan_width {
4891 MWCTL_CHAN_WIDTH_20,
4892 MWCTL_CHAN_WIDTH_40,
4893 MWCTL_CHAN_WIDTH_80,
4894 MWCTL_CHAN_WIDTH_160,
4895 MWCTL_CHAN_WIDTH_320,
4896};
4897
4898struct bw_option {
4899 unsigned int bandwith;
4900 enum mwctl_chan_width mode;
4901};
4902
4903struct bw_option bw_opt[] = {
4904 {20, MWCTL_CHAN_WIDTH_20},
4905 {40, MWCTL_CHAN_WIDTH_40},
4906 {80, MWCTL_CHAN_WIDTH_80},
4907 {160, MWCTL_CHAN_WIDTH_160},
4908 {320, MWCTL_CHAN_WIDTH_320},
4909};
4910
4911INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
4912{
4913 int ret = -1;
4914 int i;
4915 struct unl unl_ins;
4916 struct nl_msg *msg = NULL;
4917 struct nlattr * msg_data = NULL;
4918 struct mtk_nl80211_param param;
4919 bool b_match = FALSE;
4920
4921 /*init mtk nl80211 vendor cmd*/
4922 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
4923 param.if_type = NL80211_ATTR_WIPHY;
4924 param.if_idx = radio_index_to_phy(radioIndex);
4925
4926 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4927 if (ret) {
4928 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4929 return RETURN_ERR;
4930 }
4931
4932 /*add mtk vendor cmd data*/
4933 if (channel != NULL)
4934 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
4935 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
4936 nlmsg_free(msg);
4937 goto err;
4938 }
4939
4940 if (bandwidth != NULL) {
4941 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
4942 if (bw_opt[i].bandwith == *bandwidth) {
4943 b_match = true;
4944 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
4945 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
4946 nlmsg_free(msg);
4947 goto err;
4948 }
4949 break;
4950 }
4951 }
4952
4953 if (!b_match) {
4954 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
4955 nlmsg_free(msg);
4956 goto err;
4957 }
4958 }
4959
4960 /*send mtk nl80211 vendor msg*/
4961 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4962 if (ret) {
4963 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4964 goto err;
4965 }
4966 /*deinit mtk nl80211 vendor msg*/
4967 mtk_nl80211_deint(&unl_ins);
4968 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developera3511852023-06-14 14:12:59 +08004969 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developerfead3972023-05-25 20:15:02 +08004970
developera3511852023-06-14 14:12:59 +08004971 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004972err:
4973 mtk_nl80211_deint(&unl_ins);
4974 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4975 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004976}
developerfead3972023-05-25 20:15:02 +08004977
developer72fb0bb2023-01-11 09:46:29 +08004978//Set the Operating Channel Bandwidth.
4979INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
4980{
developera3511852023-06-14 14:12:59 +08004981 char config_file[128];
4982 char ht_value[16];
4983 char vht_value[16];
4984 char eht_value[16];
4985 struct params dat[3];
4986 wifi_band band = band_invalid;
4987 unsigned int bw = 20;
developere40952c2023-06-15 18:46:43 +08004988 int ret = 0, res1, res2, res3;
developer72fb0bb2023-01-11 09:46:29 +08004989
developera3511852023-06-14 14:12:59 +08004990 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004991
developera3511852023-06-14 14:12:59 +08004992 if(NULL == bandwidth)
4993 return RETURN_ERR;
4994 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004995
developera3511852023-06-14 14:12:59 +08004996 if(strstr(bandwidth,"320") != NULL) {
developere40952c2023-06-15 18:46:43 +08004997 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4998 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4999 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developera3511852023-06-14 14:12:59 +08005000 bw = 320;
5001 } else if(strstr(bandwidth,"160") != NULL) {
developere40952c2023-06-15 18:46:43 +08005002 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5003 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
5004 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developera3511852023-06-14 14:12:59 +08005005 bw = 160;
5006 } else if(strstr(bandwidth,"80") != NULL) {
developere40952c2023-06-15 18:46:43 +08005007 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5008 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
5009 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developera3511852023-06-14 14:12:59 +08005010 bw = 80;
5011 } else if(strstr(bandwidth,"40") != NULL) {
developere40952c2023-06-15 18:46:43 +08005012 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
5013 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
5014 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developera3511852023-06-14 14:12:59 +08005015 bw = 40;
5016 } else if(strstr(bandwidth,"20") != NULL) {
developere40952c2023-06-15 18:46:43 +08005017 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
5018 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
5019 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developera3511852023-06-14 14:12:59 +08005020 bw = 20;
5021 } else {
developer37646972023-06-29 10:58:43 +08005022 if (fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth) < 0)
5023 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08005024 return RETURN_ERR;
5025 }
developer72fb0bb2023-01-11 09:46:29 +08005026
developer37646972023-06-29 10:58:43 +08005027 if (os_snprintf_error(sizeof(ht_value), res1) ||
5028 os_snprintf_error(sizeof(vht_value), res2) ||
5029 os_snprintf_error(sizeof(eht_value), res3)) {
developere40952c2023-06-15 18:46:43 +08005030 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5031 return RETURN_ERR;
5032 }
5033
5034 res1 = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5035 if (os_snprintf_error(sizeof(config_file), res1)) {
5036 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5037 return RETURN_ERR;
5038 }
developera3511852023-06-14 14:12:59 +08005039 dat[0].name = "HT_BW";
5040 dat[0].value = ht_value;
5041 dat[1].name = "VHT_BW";
5042 dat[1].value = vht_value;
5043 dat[2].name = "EHT_ApBw";
5044 dat[2].value = eht_value;
5045 wifi_datfileWrite(config_file, dat, 3);
5046 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
developerfead3972023-05-25 20:15:02 +08005047 if (ret != RETURN_OK) {
developer37646972023-06-29 10:58:43 +08005048 if (fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__) < 0)
5049 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +08005050 return RETURN_ERR;
5051 }
developer72fb0bb2023-01-11 09:46:29 +08005052
developera3511852023-06-14 14:12:59 +08005053 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5054 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005055}
5056
developer72fb0bb2023-01-11 09:46:29 +08005057//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
5058//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.
5059INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
5060{
developera3511852023-06-14 14:12:59 +08005061 char config_file[64] = {0};
5062 char config_dat_file[64] = {0};
5063 char mode_str[16] = {0};
5064 char buf[64] = {0};
5065 char cmd[MAX_CMD_SIZE] = {0};
5066 char interface_name[64] = {0};
5067 int ret = 0, len=0;
5068 wifi_band band;
5069 ULONG channel = 0;
5070 int centr_channel = 0;
5071 UINT mode_map = 0;
developere40952c2023-06-15 18:46:43 +08005072 int freq=0, res;
developer72fb0bb2023-01-11 09:46:29 +08005073
developera3511852023-06-14 14:12:59 +08005074 if (output_string == NULL)
5075 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005076
developer86035662023-06-28 19:21:12 +08005077 if (wifi_getRadioMode(radioIndex, mode_str, &mode_map) != RETURN_OK) {
5078 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode fail\n");
5079 }
developer72fb0bb2023-01-11 09:46:29 +08005080
developera3511852023-06-14 14:12:59 +08005081 band = wifi_index_to_band(radioIndex);
5082 if (band == band_invalid)
5083 return RETURN_ERR;
5084 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5085 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005086
developere40952c2023-06-15 18:46:43 +08005087 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5088 if (os_snprintf_error(sizeof(config_file), res)) {
5089 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5090 return RETURN_ERR;
5091 }
5092
5093 res = snprintf(output_string, 64, "Auto");
5094 if (os_snprintf_error(64, res)) {
5095 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5096 return RETURN_ERR;
5097 }
developer72fb0bb2023-01-11 09:46:29 +08005098
developera3511852023-06-14 14:12:59 +08005099 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
5100 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
developere40952c2023-06-15 18:46:43 +08005101 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5102 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5103 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5104 return RETURN_ERR;
5105 }
developerb758dfd2023-06-21 17:32:07 +08005106
developera3511852023-06-14 14:12:59 +08005107 wifi_halgetRadioExtChannel(config_dat_file, output_string);
developer37646972023-06-29 10:58:43 +08005108 if (!(mode_map&WIFI_MODE_N)) {
developere40952c2023-06-15 18:46:43 +08005109 res = snprintf(output_string, 64, "Auto");
developer37646972023-06-29 10:58:43 +08005110 if (os_snprintf_error(64, res)) {
5111 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5112 return RETURN_ERR;
5113 }
5114 }
developera3511852023-06-14 14:12:59 +08005115 } else {
5116 // 5G and 6G band with ac or ax mode.
5117 wifi_getRadioChannel(radioIndex, &channel);
developere40952c2023-06-15 18:46:43 +08005118 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
5119 if (os_snprintf_error(sizeof(cmd), res)) {
5120 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5121 return RETURN_ERR;
5122 }
developerd1824452023-05-18 12:30:04 +08005123
developera3511852023-06-14 14:12:59 +08005124 ret = _syscmd(cmd, buf, sizeof(buf));
5125 len = strlen(buf);
5126 if((ret != 0) || (len == 0))
5127 {
5128 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
5129 return RETURN_ERR;
5130 }
5131 sscanf(buf, "%d", &freq);
5132 centr_channel = ieee80211_frequency_to_channel(freq);
5133 if (centr_channel > (int)channel)
developere40952c2023-06-15 18:46:43 +08005134 res = snprintf(output_string, 64, "AboveControlChannel");
developera3511852023-06-14 14:12:59 +08005135 else
developere40952c2023-06-15 18:46:43 +08005136 res = snprintf(output_string, 64, "BelowControlChannel");
5137
5138 if (os_snprintf_error(64, res)) {
5139 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5140 return RETURN_ERR;
5141 }
developera3511852023-06-14 14:12:59 +08005142 }
developer72fb0bb2023-01-11 09:46:29 +08005143
developera3511852023-06-14 14:12:59 +08005144 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005145}
5146
5147//Set the extension channel.
5148INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08005149{
developera3511852023-06-14 14:12:59 +08005150 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5151 struct params params={0};
5152 char config_file[64] = {0};
5153 char config_dat_file[64] = {0};
5154 char ext_channel[64] = {0};
5155 char buf[128] = {0};
5156 char cmd[128] = {0};
5157 int max_radio_num =0, ret = 0, bandwidth = 0;
5158 unsigned long channel = 0;
5159 bool stbcEnable = FALSE;
5160 params.name = "ht_capab";
5161 wifi_band band;
developere40952c2023-06-15 18:46:43 +08005162 int res;
developer72fb0bb2023-01-11 09:46:29 +08005163
developer75bd10c2023-06-27 11:34:08 +08005164 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5165 if (os_snprintf_error(sizeof(config_file), res)) {
5166 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5167 return RETURN_ERR;
5168 }
5169
developere40952c2023-06-15 18:46:43 +08005170 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
5171 if (os_snprintf_error(sizeof(cmd), res)) {
5172 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5173 return RETURN_ERR;
5174 }
developera3511852023-06-14 14:12:59 +08005175 _syscmd(cmd, buf, sizeof(buf));
5176 if (strlen(buf) != 0)
5177 stbcEnable = TRUE;
5178 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
5179 return RETURN_ERR;
5180 bandwidth = strtol(buf, NULL, 10);
5181 // TDK expected to get error with 20MHz
5182 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
5183 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
5184 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005185
developera3511852023-06-14 14:12:59 +08005186 band = wifi_index_to_band(radioIndex);
5187 if (band == band_invalid)
5188 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005189
developera3511852023-06-14 14:12:59 +08005190 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
5191 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005192
developere40952c2023-06-15 18:46:43 +08005193 res = snprintf(buf, sizeof(buf), "HT%d", bandwidth);
5194 if (os_snprintf_error(sizeof(buf), res)) {
5195 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5196 return RETURN_ERR;
5197 }
developera3511852023-06-14 14:12:59 +08005198 ret = util_get_sec_chan_offset(channel, buf);
5199 if (ret == -EINVAL)
5200 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005201
developera3511852023-06-14 14:12:59 +08005202 if(NULL!= strstr(string,"Above")) {
5203 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
5204 return RETURN_OK;
developer32f2a182023-06-27 19:50:41 +08005205 memcpy(ext_channel, "Above", strlen("Above"));
developera3511852023-06-14 14:12:59 +08005206 } else if(NULL!= strstr(string,"Below")) {
5207 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
5208 return RETURN_OK;
developer32f2a182023-06-27 19:50:41 +08005209 memcpy(ext_channel, "Below", strlen("Below"));
developera3511852023-06-14 14:12:59 +08005210 } else {
5211 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08005212 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08005213 }
5214 params.name = "HT_EXTCHA";
5215 params.value = ext_channel;
developer72fb0bb2023-01-11 09:46:29 +08005216
developera3511852023-06-14 14:12:59 +08005217 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08005218 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5219 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5220 return RETURN_ERR;
5221 }
developera3511852023-06-14 14:12:59 +08005222 wifi_datfileWrite(config_dat_file, &params, 1);
developerd1824452023-05-18 12:30:04 +08005223
developera3511852023-06-14 14:12:59 +08005224 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08005225 if(max_radio_num== 0){
5226 return RETURN_ERR;
5227 }
developera3511852023-06-14 14:12:59 +08005228 for(int i=0; i<=MAX_APS/max_radio_num; i++)
5229 {
developer32f2a182023-06-27 19:50:41 +08005230 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
5231 if (os_snprintf_error(sizeof(config_file), res)) {
5232 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5233 return RETURN_ERR;
5234 }
developera3511852023-06-14 14:12:59 +08005235 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
5236 }
developer72fb0bb2023-01-11 09:46:29 +08005237
developera3511852023-06-14 14:12:59 +08005238 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
5239 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5240 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005241}
5242
5243//Get the guard interval value. eg "400nsec" or "800nsec"
5244//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.
5245INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
5246{
developera3511852023-06-14 14:12:59 +08005247 wifi_guard_interval_t GI;
developer32f2a182023-06-27 19:50:41 +08005248 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08005249
developera3511852023-06-14 14:12:59 +08005250 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005251
developera3511852023-06-14 14:12:59 +08005252 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
5253 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005254
developer32f2a182023-06-27 19:50:41 +08005255 if (GI == wifi_guard_interval_400) {
5256 len = strlen("400nsec");
5257 memcpy(output_string, "400nsec", len);
5258 } else if (GI == wifi_guard_interval_800) {
5259 len = strlen("800nsec");
5260 memcpy(output_string, "800nsec", strlen("800nsec"));
5261 } else if (GI == wifi_guard_interval_1600) {
5262 len = strlen("1600nsec");
5263 memcpy(output_string, "1600nsec", strlen("1600nsec"));
5264 } else if (GI == wifi_guard_interval_3200) {
5265 len = strlen("3200nsec");
5266 memcpy(output_string, "3200nsec", strlen("3200nsec"));
5267 } else {
5268 len = strlen("Auto");
5269 memcpy(output_string, "Auto", strlen("Auto"));
5270 }
5271 output_string[len] = '\0';
developera3511852023-06-14 14:12:59 +08005272 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5273 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005274}
5275
5276//Set the guard interval value.
5277INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
5278{
developera3511852023-06-14 14:12:59 +08005279 wifi_guard_interval_t GI;
5280 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08005281
developera3511852023-06-14 14:12:59 +08005282 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005283
developera3511852023-06-14 14:12:59 +08005284 if (strcmp(string, "400nsec") == 0)
5285 GI = wifi_guard_interval_400;
5286 else if (strcmp(string , "800nsec") == 0)
5287 GI = wifi_guard_interval_800;
5288 else if (strcmp(string , "1600nsec") == 0)
5289 GI = wifi_guard_interval_1600;
5290 else if (strcmp(string , "3200nsec") == 0)
5291 GI = wifi_guard_interval_3200;
5292 else
5293 GI = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +08005294
developera3511852023-06-14 14:12:59 +08005295 ret = wifi_setGuardInterval(radioIndex, GI);
developer72fb0bb2023-01-11 09:46:29 +08005296
developera3511852023-06-14 14:12:59 +08005297 if (ret == RETURN_ERR) {
5298 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
5299 return RETURN_ERR;
5300 }
developer72fb0bb2023-01-11 09:46:29 +08005301
developera3511852023-06-14 14:12:59 +08005302 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5303 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005304}
5305
5306//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
5307INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
5308{
developera3511852023-06-14 14:12:59 +08005309 char buf[32]={0};
5310 char mcs_file[64] = {0};
5311 char cmd[MAX_CMD_SIZE] = {0};
5312 UINT mode_bitmap = 0;
developere40952c2023-06-15 18:46:43 +08005313 int res;
developer72fb0bb2023-01-11 09:46:29 +08005314
developera3511852023-06-14 14:12:59 +08005315 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5316 if(output_int == NULL)
5317 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005318 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
5319 if (os_snprintf_error(sizeof(mcs_file), res)) {
5320 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5321 return RETURN_ERR;
5322 }
5323
5324 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
5325 if (os_snprintf_error(sizeof(cmd), res)) {
5326 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5327 return RETURN_ERR;
5328 }
developer72fb0bb2023-01-11 09:46:29 +08005329
developera3511852023-06-14 14:12:59 +08005330 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08005331 if (strlen(buf) > 0) {
developera3511852023-06-14 14:12:59 +08005332 *output_int = strtol(buf, NULL, 10);
developerd14dff12023-06-28 22:47:44 +08005333 if (*output_int == 0 && buf[0] != '0') {
5334 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
5335 return RETURN_ERR;
5336 }
5337 } else {
developera3511852023-06-14 14:12:59 +08005338 // output the max MCS for the current radio mode
5339 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
5340 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
5341 return RETURN_ERR;
5342 }
5343 if (mode_bitmap & WIFI_MODE_AX) {
5344 *output_int = 11;
5345 } else if (mode_bitmap & WIFI_MODE_AC) {
5346 *output_int = 9;
5347 } else if (mode_bitmap & WIFI_MODE_N) {
5348 *output_int = 7;
5349 }
5350 }
5351 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005352
developera3511852023-06-14 14:12:59 +08005353 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005354}
5355
5356//Set the Modulation Coding Scheme index
5357INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
5358{
developera3511852023-06-14 14:12:59 +08005359 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
5360 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
5361 char config_file[64] = {0};
5362 char set_value[16] = {0};
5363 char mcs_file[32] = {0};
5364 struct params set_config = {0};
5365 FILE *f = NULL;
5366 INT nss = 0;
5367 int ant_bitmap = 0;
5368 unsigned short cal_value = 0;
5369 UCHAR tval = 0, i = 0;
developere40952c2023-06-15 18:46:43 +08005370 int res;
developer72fb0bb2023-01-11 09:46:29 +08005371
developera3511852023-06-14 14:12:59 +08005372 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005373
developere40952c2023-06-15 18:46:43 +08005374 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5375 if (os_snprintf_error(sizeof(config_file), res)) {
5376 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5377 return RETURN_ERR;
5378 }
developer72fb0bb2023-01-11 09:46:29 +08005379
developera3511852023-06-14 14:12:59 +08005380 // -1 means auto
5381 if (MCS > 15 || MCS < -1) {
developer75bd10c2023-06-27 11:34:08 +08005382 wifi_debug(DEBUG_ERROR, "invalid MCS %d\n", MCS);
developera3511852023-06-14 14:12:59 +08005383 return RETURN_ERR;
5384 }
5385 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
5386 for(; ant_bitmap > 0; ant_bitmap >>= 1)
5387 nss += 1;
5388 //printf("%s:nss = %d\n", __func__, nss);
5389 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
5390 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
5391 if (MCS > 9 || MCS == -1)
5392 tval = 2;/*one stream value*/
5393 else if (MCS > 7)
5394 tval = 1;
5395 else
5396 tval = 0;
5397 for (i = 0; i < nss; i++)
5398 cal_value |= (tval << (2*i));
developere40952c2023-06-15 18:46:43 +08005399 res = snprintf(set_value, sizeof(set_value), "%x", cal_value);
5400 if (os_snprintf_error(sizeof(set_value), res)) {
5401 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5402 return RETURN_ERR;
5403 }
5404
developera3511852023-06-14 14:12:59 +08005405 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
5406 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
5407 set_config.value = set_value;
developer72fb0bb2023-01-11 09:46:29 +08005408
developera3511852023-06-14 14:12:59 +08005409 wifi_hostapdWrite(config_file, &set_config, 1);
5410 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
developer72fb0bb2023-01-11 09:46:29 +08005411
developera3511852023-06-14 14:12:59 +08005412 // 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 +08005413 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
5414 if (os_snprintf_error(sizeof(mcs_file), res)) {
5415 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5416 return RETURN_ERR;
5417 }
5418
developera3511852023-06-14 14:12:59 +08005419 f = fopen(mcs_file, "w");
5420 if (f == NULL) {
5421 fprintf(stderr, "%s: fopen failed\n", __func__);
5422 return RETURN_ERR;
5423 }
5424 fprintf(f, "%d", MCS);
5425 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08005426
developera3511852023-06-14 14:12:59 +08005427 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5428 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005429}
5430
5431//Get supported Transmit Power list, eg : "0,25,50,75,100"
5432//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.
5433INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
5434{
developere40952c2023-06-15 18:46:43 +08005435 int res;
5436 if (NULL == output_list)
5437 return RETURN_ERR;
5438 res = snprintf(output_list, 64,"0,25,50,75,100");
5439 if (os_snprintf_error(64, res)) {
5440 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5441 return RETURN_ERR;
5442 }
5443
5444 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005445}
5446
5447//Get current Transmit Power in dBm units.
5448//The transmite power level is in units of full power for this radio.
5449INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
5450{
developera3511852023-06-14 14:12:59 +08005451 char interface_name[16] = {0};
5452 char cmd[MAX_CMD_SIZE]={0};
5453 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08005454 char pwr_file[128]={0};
developere40952c2023-06-15 18:46:43 +08005455 int res;
developera1255e42023-05-13 17:45:02 +08005456
developera3511852023-06-14 14:12:59 +08005457 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005458
developera3511852023-06-14 14:12:59 +08005459 if(output_ulong == NULL)
5460 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005461
developera3511852023-06-14 14:12:59 +08005462 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5463 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005464 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
5465 if (os_snprintf_error(sizeof(pwr_file), res)) {
5466 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5467 return RETURN_ERR;
5468 }
5469
5470 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
5471 if (os_snprintf_error(sizeof(cmd), res)) {
5472 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5473 return RETURN_ERR;
5474 }
5475
developera1255e42023-05-13 17:45:02 +08005476 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08005477 if (strlen(buf) > 0) {
developera1255e42023-05-13 17:45:02 +08005478 *output_ulong = strtol(buf, NULL, 10);
developerd14dff12023-06-28 22:47:44 +08005479 if (*output_ulong == 0 && buf[0] != '0') {
5480 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
5481 return RETURN_ERR;
5482 }
5483 } else
developera1255e42023-05-13 17:45:02 +08005484 *output_ulong = 100;
developera3511852023-06-14 14:12:59 +08005485 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5486 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005487}
5488
5489//Set Transmit Power
5490//The transmite power level is in units of full power for this radio.
5491INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
5492{
developera3511852023-06-14 14:12:59 +08005493 char interface_name[16] = {0};
5494 char *support;
5495 char buf[128]={0};
5496 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08005497 char pwr_file[128]={0};
developera3511852023-06-14 14:12:59 +08005498 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08005499 int if_idx, ret = 0;
5500 struct nl_msg *msg = NULL;
5501 struct nlattr * msg_data = NULL;
5502 struct mtk_nl80211_param param;
5503 struct unl unl_ins;
developere40952c2023-06-15 18:46:43 +08005504 int res;
developer72fb0bb2023-01-11 09:46:29 +08005505
developera3511852023-06-14 14:12:59 +08005506 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005507
developera3511852023-06-14 14:12:59 +08005508 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5509 return RETURN_ERR;
5510 // Get the Tx power supported list and check that is the input in the list
developere40952c2023-06-15 18:46:43 +08005511 res = snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
5512 if (os_snprintf_error(sizeof(txpower_str), res)) {
5513 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5514 return RETURN_ERR;
5515 }
developera3511852023-06-14 14:12:59 +08005516 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
5517 support = strtok(buf, ",");
5518 while(true)
5519 {
5520 if(support == NULL) { // input not in the list
5521 wifi_dbg_printf("Input value is invalid.\n");
5522 return RETURN_ERR;
5523 }
5524 if (strncmp(txpower_str, support, strlen(support)) == 0) {
5525 break;
5526 }
5527 support = strtok(NULL, ",");
5528 }
developerfead3972023-05-25 20:15:02 +08005529
5530 if_idx = if_nametoindex(interface_name);
5531 /*init mtk nl80211 vendor cmd*/
5532 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
5533 param.if_type = NL80211_ATTR_IFINDEX;
5534 param.if_idx = if_idx;
5535 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
5536 if (ret) {
5537 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
5538 return RETURN_ERR;
5539 }
5540 /*add mtk vendor cmd data*/
5541 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
5542 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
5543 nlmsg_free(msg);
5544 goto err;
5545 }
5546
5547 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
5548 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
5549 nlmsg_free(msg);
5550 goto err;
5551 }
5552
5553 /*send mtk nl80211 vendor msg*/
5554 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
5555 if (ret) {
5556 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
5557 goto err;
5558 }
5559 /*deinit mtk nl80211 vendor msg*/
5560 mtk_nl80211_deint(&unl_ins);
5561 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
5562
developere40952c2023-06-15 18:46:43 +08005563 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
5564 if (os_snprintf_error(sizeof(pwr_file), res)) {
5565 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5566 return RETURN_ERR;
5567 }
5568
developera3511852023-06-14 14:12:59 +08005569 f = fopen(pwr_file, "w");
5570 if (f == NULL) {
5571 fprintf(stderr, "%s: fopen failed\n", __func__);
5572 return RETURN_ERR;
5573 }
5574 fprintf(f, "%lu", TransmitPower);
5575 fclose(f);
developera1255e42023-05-13 17:45:02 +08005576 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08005577err:
5578 mtk_nl80211_deint(&unl_ins);
5579 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
5580 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005581}
5582
5583//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
5584INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
5585{
developera3511852023-06-14 14:12:59 +08005586 if (NULL == Supported)
5587 return RETURN_ERR;
5588 *Supported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08005589
developera3511852023-06-14 14:12:59 +08005590 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005591}
5592
5593//Get 80211h feature enable
5594INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
5595{
developera3511852023-06-14 14:12:59 +08005596 char buf[64]={'\0'};
5597 char config_file[64] = {'\0'};
developer75bd10c2023-06-27 11:34:08 +08005598 int res;
developer72fb0bb2023-01-11 09:46:29 +08005599
developera3511852023-06-14 14:12:59 +08005600 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5601 if(enable == NULL)
5602 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005603
developer75bd10c2023-06-27 11:34:08 +08005604 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5605 if (os_snprintf_error(sizeof(config_file), res)) {
5606 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5607 return RETURN_ERR;
5608 }
developera3511852023-06-14 14:12:59 +08005609 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
5610 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005611
developera3511852023-06-14 14:12:59 +08005612 if (strncmp(buf, "1", 1) == 0)
5613 *enable = TRUE;
5614 else
5615 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08005616
developera3511852023-06-14 14:12:59 +08005617 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5618 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005619}
5620
5621//Set 80211h feature enable
5622INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
5623{
developera3511852023-06-14 14:12:59 +08005624 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5625 struct params params={'\0'};
5626 struct params dat={0};
5627 char config_file[MAX_BUF_SIZE] = {0};
5628 char config_dat_file[MAX_BUF_SIZE] = {0};
5629 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08005630 int res;
developer72fb0bb2023-01-11 09:46:29 +08005631
developera3511852023-06-14 14:12:59 +08005632 params.name = "ieee80211h";
developer72fb0bb2023-01-11 09:46:29 +08005633
developera3511852023-06-14 14:12:59 +08005634 if (enable) {
5635 params.value = "1";
5636 } else {
5637 params.value = "0";
5638 }
developer72fb0bb2023-01-11 09:46:29 +08005639
developera3511852023-06-14 14:12:59 +08005640 dat.name = "IEEE80211H";
5641 dat.value = params.value;
developerd1824452023-05-18 12:30:04 +08005642
developera3511852023-06-14 14:12:59 +08005643 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08005644 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5645 if (os_snprintf_error(sizeof(config_file), res)) {
5646 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5647 return RETURN_ERR;
5648 }
5649
5650 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
5651 if (os_snprintf_error(sizeof(config_dat_file), res)) {
5652 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5653 return RETURN_ERR;
5654 }
developer69b61b02023-03-07 17:17:44 +08005655
developera3511852023-06-14 14:12:59 +08005656 wifi_hostapdWrite(config_file, &params, 1);
5657 wifi_datfileWrite(config_dat_file, &dat, 1);
5658 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
5659 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005661}
5662
5663//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.
5664INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
5665{
developera3511852023-06-14 14:12:59 +08005666 if (NULL == output)
5667 return RETURN_ERR;
5668 *output=100;
developer72fb0bb2023-01-11 09:46:29 +08005669
developera3511852023-06-14 14:12:59 +08005670 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005671}
5672
5673//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.
5674INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
5675{
developera3511852023-06-14 14:12:59 +08005676 if (NULL == output)
5677 return RETURN_ERR;
5678 *output = -99;
developer72fb0bb2023-01-11 09:46:29 +08005679
developera3511852023-06-14 14:12:59 +08005680 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005681}
5682
5683INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
5684{
developera3511852023-06-14 14:12:59 +08005685 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005686}
5687
5688
5689//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
5690INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
5691{
developera3511852023-06-14 14:12:59 +08005692 char interface_name[16] = {0};
5693 char cmd[MAX_BUF_SIZE]={'\0'};
5694 char buf[MAX_CMD_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08005695 int res;
developer72fb0bb2023-01-11 09:46:29 +08005696
developera3511852023-06-14 14:12:59 +08005697 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5698 if(output == NULL)
5699 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005700
developera3511852023-06-14 14:12:59 +08005701 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5702 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005703 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
5704 if (os_snprintf_error(sizeof(cmd), res)) {
5705 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5706 return RETURN_ERR;
5707 }
5708
developera3511852023-06-14 14:12:59 +08005709 _syscmd(cmd, buf, sizeof(buf));
5710 *output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08005711
developera3511852023-06-14 14:12:59 +08005712 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5713 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005714}
developer69b61b02023-03-07 17:17:44 +08005715
developer72fb0bb2023-01-11 09:46:29 +08005716INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
5717{
developera3511852023-06-14 14:12:59 +08005718 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5719 struct params params={'\0'};
5720 char buf[MAX_BUF_SIZE] = {'\0'};
5721 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08005722 int res;
developer72fb0bb2023-01-11 09:46:29 +08005723
developera3511852023-06-14 14:12:59 +08005724 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
5725 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005726
developera3511852023-06-14 14:12:59 +08005727 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08005728 res = snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
5729 if (os_snprintf_error(sizeof(buf), res)) {
5730 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5731 return RETURN_ERR;
5732 }
5733
developera3511852023-06-14 14:12:59 +08005734 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08005735
developer75bd10c2023-06-27 11:34:08 +08005736 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5737 if (os_snprintf_error(sizeof(config_file), res)) {
5738 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5739 return RETURN_ERR;
5740 }
developera3511852023-06-14 14:12:59 +08005741 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08005742
developera3511852023-06-14 14:12:59 +08005743 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
5744 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5745 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005746}
5747
5748//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.
5749INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
5750{
developera3511852023-06-14 14:12:59 +08005751 //TODO: need to revisit below implementation
5752 char *temp;
5753 char temp_output[128] = {0};
5754 char temp_TransmitRates[64] = {0};
5755 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +08005756 int res;
developer72fb0bb2023-01-11 09:46:29 +08005757
developera3511852023-06-14 14:12:59 +08005758 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5759 if (NULL == output)
5760 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08005761
5762 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
5763 if (os_snprintf_error(sizeof(config_file), res)) {
5764 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5765 return RETURN_ERR;
5766 }
developera3511852023-06-14 14:12:59 +08005767 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08005768
developera3511852023-06-14 14:12:59 +08005769 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
5770 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
5771 } else {
5772 temp = strtok(temp_TransmitRates," ");
5773 while(temp!=NULL)
5774 {
5775 // Convert 100 kbps to Mbps
5776 temp[strlen(temp)-1]=0;
5777 if((temp[0]=='5') && (temp[1]=='\0'))
5778 {
5779 temp="5.5";
5780 }
developer32f2a182023-06-27 19:50:41 +08005781 if (strlen(temp) >= sizeof(temp_output))
5782 return RETURN_ERR;
5783 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005784 temp = strtok(NULL," ");
5785 if(temp!=NULL)
5786 {
developer32f2a182023-06-27 19:50:41 +08005787 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
5788 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005789 }
5790 }
developer32f2a182023-06-27 19:50:41 +08005791 memcpy(output, temp_output, strlen(temp_output));
5792 output[strlen(temp_output)] = '\0';
developera3511852023-06-14 14:12:59 +08005793 }
5794 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5795 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005796}
5797
5798INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
5799{
developera3511852023-06-14 14:12:59 +08005800 char *temp;
developer32f2a182023-06-27 19:50:41 +08005801 char temp1[128] = {0};
5802 char temp_output[128] = {0};
5803 char temp_TransmitRates[128] = {0};
5804 char set[128] = {0};
5805 char sub_set[128] = {0};
developera3511852023-06-14 14:12:59 +08005806 int set_count=0,subset_count=0;
5807 int set_index=0,subset_index=0;
5808 char *token;
5809 int flag=0, i=0;
5810 struct params params={'\0'};
5811 char config_file[MAX_BUF_SIZE] = {0};
5812 wifi_band band = wifi_index_to_band(radioIndex);
developer32f2a182023-06-27 19:50:41 +08005813 int res;
developer72fb0bb2023-01-11 09:46:29 +08005814
developera3511852023-06-14 14:12:59 +08005815 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5816 if(NULL == TransmitRates)
5817 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +08005818 if (strlen(TransmitRates) >= sizeof(sub_set))
5819 return RETURN_ERR;
5820
5821 memcpy(sub_set, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08005822
developera3511852023-06-14 14:12:59 +08005823 //Allow only supported Data transmit rate to be set
5824 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
5825 token = strtok(sub_set,",");
5826 while( token != NULL ) /* split the basic rate to be set, by comma */
5827 {
5828 sub_set[subset_count]=atoi(token);
5829 subset_count++;
5830 token=strtok(NULL,",");
5831 }
5832 token=strtok(set,",");
5833 while(token!=NULL) /* split the supported rate by comma */
5834 {
5835 set[set_count]=atoi(token);
5836 set_count++;
5837 token=strtok(NULL,",");
5838 }
5839 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
5840 {
5841 for(set_index=0;set_index < set_count;set_index++)
5842 {
5843 flag=0;
5844 if(sub_set[subset_index]==set[set_index])
5845 break;
5846 else
5847 flag=1; /* No match found */
5848 }
5849 if(flag==1)
5850 return RETURN_ERR; //If value not found return Error
5851 }
developer32f2a182023-06-27 19:50:41 +08005852
5853 if (strlen(TransmitRates) >= sizeof(temp_TransmitRates))
5854 return RETURN_ERR;
5855
5856 memcpy(temp_TransmitRates, TransmitRates, strlen(TransmitRates));
developer72fb0bb2023-01-11 09:46:29 +08005857
developera3511852023-06-14 14:12:59 +08005858 for(i=0;i<strlen(temp_TransmitRates);i++)
5859 {
5860 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
5861 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
5862 {
5863 continue;
5864 }
5865 else
5866 {
5867 return RETURN_ERR;
5868 }
5869 }
developera3511852023-06-14 14:12:59 +08005870 temp = strtok(temp_TransmitRates,",");
5871 while(temp!=NULL)
5872 {
developer32f2a182023-06-27 19:50:41 +08005873 if (strlen(temp) >= sizeof(temp1))
5874 return RETURN_ERR;
5875 strncpy(temp1, temp, strlen(temp));
developera3511852023-06-14 14:12:59 +08005876 if(band == band_5)
5877 {
5878 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
5879 {
5880 return RETURN_ERR;
5881 }
5882 }
developer72fb0bb2023-01-11 09:46:29 +08005883
developera3511852023-06-14 14:12:59 +08005884 if(strcmp(temp,"5.5")==0)
5885 {
developer32f2a182023-06-27 19:50:41 +08005886 memcpy(temp1, "55", 2);
developera3511852023-06-14 14:12:59 +08005887 }
5888 else
5889 {
developer32f2a182023-06-27 19:50:41 +08005890 if (strlen(temp1) >= (sizeof(temp1) - 1))
5891 return RETURN_ERR;
5892 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +08005893 }
developer32f2a182023-06-27 19:50:41 +08005894 if (strlen(temp1) >= (sizeof(temp_output) - strlen(temp_output)))
5895 return RETURN_ERR;
5896 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005897 temp = strtok(NULL,",");
5898 if(temp!=NULL)
5899 {
developer32f2a182023-06-27 19:50:41 +08005900 if (strlen(temp_output) >= (sizeof(temp_output) - 1))
5901 return RETURN_ERR;
5902 strncat(temp_output," ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +08005903 }
5904 }
developer32f2a182023-06-27 19:50:41 +08005905 memcpy(TransmitRates, temp_output, strlen(temp_output));
5906 TransmitRates[strlen(temp_output)] = '\0';
5907
developera3511852023-06-14 14:12:59 +08005908 params.name= "basic_rates";
5909 params.value =TransmitRates;
developer72fb0bb2023-01-11 09:46:29 +08005910
developera3511852023-06-14 14:12:59 +08005911 wifi_dbg_printf("\n%s:",__func__);
5912 wifi_dbg_printf("\nparams.value=%s\n",params.value);
5913 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
developer32f2a182023-06-27 19:50:41 +08005914 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,radioIndex);
5915 if (os_snprintf_error(sizeof(config_file), res)) {
5916 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5917 return RETURN_ERR;
5918 }
5919
developera3511852023-06-14 14:12:59 +08005920 wifi_hostapdWrite(config_file,&params,1);
5921 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5922 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005923}
5924
developer72fb0bb2023-01-11 09:46:29 +08005925INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
5926{
developera3511852023-06-14 14:12:59 +08005927 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5928 output_struct->radio_BytesSent = 0;
5929 output_struct->radio_BytesReceived = 0;
5930 output_struct->radio_PacketsSent = 0;
5931 output_struct->radio_PacketsReceived = 0;
5932 output_struct->radio_ErrorsSent = 0;
5933 output_struct->radio_ErrorsReceived = 0;
5934 output_struct->radio_DiscardPacketsSent = 0;
5935 output_struct->radio_DiscardPacketsReceived = 0;
5936 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5937 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005938}
5939
5940
5941INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
5942{
developera3511852023-06-14 14:12:59 +08005943 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5944 CHAR buf[MAX_CMD_SIZE] = {0};
5945 CHAR Value[MAX_BUF_SIZE] = {0};
5946 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08005947 int res;
developer37646972023-06-29 10:58:43 +08005948 unsigned long ret;
developer72fb0bb2023-01-11 09:46:29 +08005949
developera3511852023-06-14 14:12:59 +08005950 if (ifname == NULL || strlen(ifname) <= 1)
5951 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005952
developere40952c2023-06-15 18:46:43 +08005953 res = snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
5954 if (os_snprintf_error(sizeof(buf), res)) {
5955 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5956 return RETURN_ERR;
5957 }
5958
developera3511852023-06-14 14:12:59 +08005959 system(buf);
developer72fb0bb2023-01-11 09:46:29 +08005960
developera3511852023-06-14 14:12:59 +08005961 fp = fopen("/tmp/Radio_Stats.txt", "r");
5962 if(fp == NULL)
5963 {
5964 printf("/tmp/Radio_Stats.txt not exists \n");
5965 return RETURN_ERR;
5966 }
developerd14dff12023-06-28 22:47:44 +08005967 if (fclose(fp) != 0) {
5968 wifi_debug(DEBUG_ERROR, "fclose fail\n");
5969 return RETURN_ERR;
5970 }
developer72fb0bb2023-01-11 09:46:29 +08005971
developer75bd10c2023-06-27 11:34:08 +08005972 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5973 if (os_snprintf_error(sizeof(buf), res)) {
5974 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5975 return RETURN_ERR;
5976 }
developera3511852023-06-14 14:12:59 +08005977 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08005978 ret = strtoul(Value, NULL, 10);
5979 if ((Value[0] != '\0') && (ret == 0)) {
5980 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
5981 return RETURN_ERR;
5982 }
5983 pStats->radio_PacketsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08005984
developer86035662023-06-28 19:21:12 +08005985 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5986 if (os_snprintf_error(sizeof(buf), res)) {
5987 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5988 return RETURN_ERR;
5989 }
developera3511852023-06-14 14:12:59 +08005990 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08005991 ret = strtoul(Value, NULL, 10);
5992 if ((Value[0] != '\0') && (ret == 0)) {
5993 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
5994 return RETURN_ERR;
5995 }
5996 pStats->radio_PacketsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08005997
developer86035662023-06-28 19:21:12 +08005998 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5999 if (os_snprintf_error(sizeof(buf), res)) {
6000 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6001 return RETURN_ERR;
6002 }
developera3511852023-06-14 14:12:59 +08006003 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08006004 ret = strtoul(Value, NULL, 10);
6005 if ((Value[0] != '\0') && (ret == 0)) {
6006 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6007 return RETURN_ERR;
6008 }
6009 pStats->radio_BytesReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006010
developer86035662023-06-28 19:21:12 +08006011 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6012 if (os_snprintf_error(sizeof(buf), res)) {
6013 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6014 return RETURN_ERR;
6015 }
developera3511852023-06-14 14:12:59 +08006016 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08006017 ret = strtoul(Value, NULL, 10);
6018 if ((Value[0] != '\0') && (ret == 0)) {
6019 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6020 return RETURN_ERR;
6021 }
6022 pStats->radio_BytesSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006023
developer86035662023-06-28 19:21:12 +08006024 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6025 if (os_snprintf_error(sizeof(buf), res)) {
6026 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6027 return RETURN_ERR;
6028 }
developera3511852023-06-14 14:12:59 +08006029 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08006030 ret = strtoul(Value, NULL, 10);
6031 if ((Value[0] != '\0') && (ret == 0)) {
6032 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6033 return RETURN_ERR;
6034 }
6035 pStats->radio_ErrorsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006036
developer86035662023-06-28 19:21:12 +08006037 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6038 if (os_snprintf_error(sizeof(buf), res)) {
6039 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6040 return RETURN_ERR;
6041 }
developera3511852023-06-14 14:12:59 +08006042 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08006043 ret = strtoul(Value, NULL, 10);
6044 if ((Value[0] != '\0') && (ret == 0)) {
6045 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6046 return RETURN_ERR;
6047 }
6048 pStats->radio_ErrorsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006049
developer86035662023-06-28 19:21:12 +08006050 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
6051 if (os_snprintf_error(sizeof(buf), res)) {
6052 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6053 return RETURN_ERR;
6054 }
developera3511852023-06-14 14:12:59 +08006055 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08006056 ret = strtoul(Value, NULL, 10);
6057 if ((Value[0] != '\0') && (ret == 0)) {
6058 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6059 return RETURN_ERR;
6060 }
6061 pStats->radio_DiscardPacketsReceived = ret;
developer72fb0bb2023-01-11 09:46:29 +08006062
developer86035662023-06-28 19:21:12 +08006063 res = snprintf(buf, sizeof(buf), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
6064 if (os_snprintf_error(sizeof(buf), res)) {
6065 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6066 return RETURN_ERR;
6067 }
developera3511852023-06-14 14:12:59 +08006068 File_Reading(buf, Value);
developer37646972023-06-29 10:58:43 +08006069 ret = strtoul(Value, NULL, 10);
6070 if ((Value[0] != '\0') && (ret == 0)) {
6071 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6072 return RETURN_ERR;
6073 }
6074 pStats->radio_DiscardPacketsSent = ret;
developer72fb0bb2023-01-11 09:46:29 +08006075
developera3511852023-06-14 14:12:59 +08006076 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6077 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006078}
6079
6080INT GetIfacestatus(CHAR *interface_name, CHAR *status)
6081{
developer7e4a2a62023-04-06 19:56:03 +08006082 CHAR buf[MAX_CMD_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006083 int res;
developer72fb0bb2023-01-11 09:46:29 +08006084
developer7e4a2a62023-04-06 19:56:03 +08006085 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6086
6087 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
developer75bd10c2023-06-27 11:34:08 +08006088 res = snprintf(buf, sizeof(buf), "%s%s%s%s%s", "ifconfig -a ",
6089 interface_name, " | grep ", interface_name, " | wc -l");
6090
6091 if (os_snprintf_error(sizeof(buf), res)) {
6092 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6093 return RETURN_ERR;
6094 }
developer7e4a2a62023-04-06 19:56:03 +08006095 File_Reading(buf, status);
6096 }
6097
6098 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
6099 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006100}
6101
6102//Get detail radio traffic static info
6103INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
6104{
developera3511852023-06-14 14:12:59 +08006105 CHAR interface_name[64] = {0};
6106 BOOL iface_status = FALSE;
6107 wifi_radioTrafficStats2_t radioTrafficStats = {0};
developer72fb0bb2023-01-11 09:46:29 +08006108
developera3511852023-06-14 14:12:59 +08006109 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
6110 if (NULL == output_struct)
6111 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006112
developera3511852023-06-14 14:12:59 +08006113 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6114 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006115
developera3511852023-06-14 14:12:59 +08006116 wifi_getApEnable(radioIndex, &iface_status);
developer72fb0bb2023-01-11 09:46:29 +08006117
developera3511852023-06-14 14:12:59 +08006118 if (iface_status == TRUE)
6119 wifi_halGetIfStats(interface_name, &radioTrafficStats);
6120 else
6121 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
developer72fb0bb2023-01-11 09:46:29 +08006122
developera3511852023-06-14 14:12:59 +08006123 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
6124 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
6125 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
6126 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
6127 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
6128 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
6129 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
6130 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +08006131
developera3511852023-06-14 14:12:59 +08006132 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
6133 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].
6134 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
6135 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.
6136 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
6137 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
6138 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
6139 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
6140 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 +08006141
developera3511852023-06-14 14:12:59 +08006142 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
6143 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
6144 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
6145 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 +08006146
developera3511852023-06-14 14:12:59 +08006147 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006148
developera3511852023-06-14 14:12:59 +08006149 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006150}
6151
6152//Set radio traffic static Measureing rules
6153INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
6154{
developera39cfb22023-06-20 16:28:17 +08006155 char inf_name[IF_NAME_SIZE] = {0};
6156 unsigned int if_idx = 0;
6157 int ret = -1;
6158 struct unl unl_ins;
6159 struct nl_msg *msg = NULL;
6160 struct nlattr * msg_data = NULL;
6161 struct mtk_nl80211_param param;
6162
6163 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
6164 return RETURN_ERR;
6165 if_idx = if_nametoindex(inf_name);
6166 if (!if_idx) {
6167 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6168 return RETURN_ERR;
6169 }
6170 /*init mtk nl80211 vendor cmd*/
6171 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
6172 param.if_type = NL80211_ATTR_IFINDEX;
6173 param.if_idx = if_idx;
6174
6175 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6176 if (ret) {
6177 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6178 return RETURN_ERR;
6179 }
6180 /*add mtk vendor cmd data*/
6181 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD,
6182 sizeof(wifi_radioTrafficStatsMeasure_t), input_struct)) {
6183 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
6184 MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD);
6185 nlmsg_free(msg);
6186 goto err;
6187 }
6188
6189 /*send mtk nl80211 vendor msg*/
6190 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6191 if (ret) {
6192 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6193 goto err;
6194 }
6195 /*deinit mtk nl80211 vendor msg*/
6196 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08006197 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08006198err:
6199 mtk_nl80211_deint(&unl_ins);
6200 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6201 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006202}
6203
6204//To start or stop RadioTrafficStats
6205INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
6206{
developera39cfb22023-06-20 16:28:17 +08006207 char inf_name[IF_NAME_SIZE] = {0};
6208 unsigned int if_idx = 0;
6209 int ret = -1;
6210 struct unl unl_ins;
6211 struct nl_msg *msg = NULL;
6212 struct nlattr * msg_data = NULL;
6213 struct mtk_nl80211_param param;
6214
6215 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
6216 return RETURN_ERR;
6217 if_idx = if_nametoindex(inf_name);
6218 if (!if_idx) {
6219 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6220 return RETURN_ERR;
6221 }
6222 /*init mtk nl80211 vendor cmd*/
6223 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
6224 param.if_type = NL80211_ATTR_IFINDEX;
6225 param.if_idx = if_idx;
6226
6227 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6228 if (ret) {
6229 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6230 return RETURN_ERR;
6231 }
6232 /*add mtk vendor cmd data*/
6233 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL, enable)) {
6234 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
6235 MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL);
6236 nlmsg_free(msg);
6237 goto err;
6238 }
6239
6240 /*send mtk nl80211 vendor msg*/
6241 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6242 if (ret) {
6243 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6244 goto err;
6245 }
6246 /*deinit mtk nl80211 vendor msg*/
6247 mtk_nl80211_deint(&unl_ins);
developera3511852023-06-14 14:12:59 +08006248 return RETURN_OK;
developera39cfb22023-06-20 16:28:17 +08006249err:
6250 mtk_nl80211_deint(&unl_ins);
6251 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6252 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006253}
6254
6255//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
6256INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
6257{
developera3511852023-06-14 14:12:59 +08006258 if (NULL == SignalLevel)
6259 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08006260
developer9ce44382023-06-28 11:09:37 +08006261 *SignalLevel = -19;
developer72fb0bb2023-01-11 09:46:29 +08006262
developera3511852023-06-14 14:12:59 +08006263 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006264}
6265
6266//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
6267INT wifi_applyRadioSettings(INT radioIndex)
6268{
developera3511852023-06-14 14:12:59 +08006269 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006270}
6271
6272//Get the radio index assocated with this SSID entry
6273INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
6274{
developera3511852023-06-14 14:12:59 +08006275 if(NULL == radioIndex)
6276 return RETURN_ERR;
6277 int max_radio_num = 0;
6278 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08006279 if(max_radio_num == 0){
6280 return RETURN_ERR;
6281 }
developera3511852023-06-14 14:12:59 +08006282 *radioIndex = ssidIndex%max_radio_num;
6283 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006284}
6285
6286//Device.WiFi.SSID.{i}.Enable
6287//Get SSID enable configuration parameters (not the SSID enable status)
6288INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
6289{
developera3511852023-06-14 14:12:59 +08006290 if (NULL == output_bool)
6291 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006292
developera3511852023-06-14 14:12:59 +08006293 return wifi_getApEnable(ssidIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006294}
6295
6296//Device.WiFi.SSID.{i}.Enable
6297//Set SSID enable configuration parameters
6298INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
6299{
developera3511852023-06-14 14:12:59 +08006300 return wifi_setApEnable(ssidIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08006301}
6302
6303//Device.WiFi.SSID.{i}.Status
6304//Get the SSID enable status
6305INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
6306{
developer9ce44382023-06-28 11:09:37 +08006307 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +08006308 int res;
developer72fb0bb2023-01-11 09:46:29 +08006309
developera3511852023-06-14 14:12:59 +08006310 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6311 if (NULL == output_string)
6312 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08006313
developera3511852023-06-14 14:12:59 +08006314 wifi_getApEnable(ssidIndex,&output_bool);
developere40952c2023-06-15 18:46:43 +08006315 res = snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
6316 if (os_snprintf_error(32, 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 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6322 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006323}
6324
6325// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
6326INT wifi_getSSIDName(INT apIndex, CHAR *output)
6327{
developera3511852023-06-14 14:12:59 +08006328 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006329 int res;
developer72fb0bb2023-01-11 09:46:29 +08006330
developera3511852023-06-14 14:12:59 +08006331 if (NULL == output)
6332 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006333
developer75bd10c2023-06-27 11:34:08 +08006334 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6335 if (os_snprintf_error(sizeof(config_file), res)) {
6336 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6337 return RETURN_ERR;
6338 }
developera3511852023-06-14 14:12:59 +08006339 wifi_hostapdRead(config_file,"ssid",output,32);
developer72fb0bb2023-01-11 09:46:29 +08006340
developera3511852023-06-14 14:12:59 +08006341 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
6342 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006343}
6344
developer69b61b02023-03-07 17:17:44 +08006345// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08006346INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
6347{
developera3511852023-06-14 14:12:59 +08006348 struct params params;
6349 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08006350 int res;
developer72fb0bb2023-01-11 09:46:29 +08006351
developera3511852023-06-14 14:12:59 +08006352 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6353 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
6354 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006355
developera3511852023-06-14 14:12:59 +08006356 params.name = "ssid";
6357 params.value = ssid_string;
developer75bd10c2023-06-27 11:34:08 +08006358
6359 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6360 if (os_snprintf_error(sizeof(config_file), res)) {
6361 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6362 return RETURN_ERR;
6363 }
6364
developera3511852023-06-14 14:12:59 +08006365 wifi_hostapdWrite(config_file, &params, 1);
6366 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6367 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006368
developera3511852023-06-14 14:12:59 +08006369 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006370}
6371
6372//Get the BSSID
6373INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
6374{
developer7e4a2a62023-04-06 19:56:03 +08006375 char cmd[MAX_CMD_SIZE] = {0};
6376 char inf_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08006377 int res;
developer72fb0bb2023-01-11 09:46:29 +08006378
developera3511852023-06-14 14:12:59 +08006379 if (!output_string)
developerdaf24792023-06-06 11:40:04 +08006380 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006381
developer47cc27a2023-05-17 23:09:58 +08006382 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
6383 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08006384
developer5b2f10c2023-05-25 17:02:21 +08006385 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
6386 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
6387 strncpy(output_string, "\0", 1);
6388 return RETURN_ERR;
6389 }
developere40952c2023-06-15 18:46:43 +08006390 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
6391 if (os_snprintf_error(sizeof(cmd), res)) {
6392 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6393 return RETURN_ERR;
6394 }
6395
developer5b2f10c2023-05-25 17:02:21 +08006396 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08006397
developer5b2f10c2023-05-25 17:02:21 +08006398 /* if hostapd does not control interface even if this interface has been brought up,
6399 * try to get its mac address by iw command.
6400 */
6401 if(strlen(output_string) == 0) {
6402 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08006403 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
6404 if (os_snprintf_error(sizeof(cmd), res)) {
6405 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6406 return RETURN_ERR;
6407 }
6408
developer5b2f10c2023-05-25 17:02:21 +08006409 _syscmd(cmd, output_string, 64);
6410 }
developer72fb0bb2023-01-11 09:46:29 +08006411
developer5b2f10c2023-05-25 17:02:21 +08006412 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006413}
6414
6415//Get the MAC address associated with this Wifi SSID
6416INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
6417{
developera3511852023-06-14 14:12:59 +08006418 wifi_getBaseBSSID(ssidIndex,output_string);
6419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006420}
6421
6422//Get the basic SSID traffic static info
6423//Apply SSID and AP (in the case of Acess Point devices) to the hardware
6424//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
6425INT wifi_applySSIDSettings(INT ssidIndex)
6426{
developera3511852023-06-14 14:12:59 +08006427 char interface_name[16] = {0};
6428 BOOL status = false;
6429 char cmd[MAX_CMD_SIZE] = {0};
6430 char buf[MAX_CMD_SIZE] = {0};
6431 int apIndex, ret;
6432 int max_radio_num = 0;
6433 int radioIndex = 0;
developere40952c2023-06-15 18:46:43 +08006434 int res;
developer72fb0bb2023-01-11 09:46:29 +08006435
developera3511852023-06-14 14:12:59 +08006436 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08006437 if(max_radio_num == 0){
6438 return RETURN_ERR;
6439 }
developera3511852023-06-14 14:12:59 +08006440 radioIndex = ssidIndex % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +08006441
developera3511852023-06-14 14:12:59 +08006442 wifi_getApEnable(ssidIndex,&status);
6443 // Do not apply when ssid index is disabled
6444 if (status == false)
6445 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006446
developera3511852023-06-14 14:12:59 +08006447 /* Doing full remove and add for ssid Index
6448 * Not all hostapd options are supported with reload
6449 * for example macaddr_acl
6450 */
6451 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
6452 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006453
developera3511852023-06-14 14:12:59 +08006454 ret = wifi_setApEnable(ssidIndex,true);
developer72fb0bb2023-01-11 09:46:29 +08006455
developera3511852023-06-14 14:12:59 +08006456 /* Workaround for hostapd issue with multiple bss definitions
6457 * when first created interface will be removed
6458 * then all vaps other vaps on same phy are removed
6459 * after calling setApEnable to false readd all enabled vaps */
6460 for(int i=0; i < MAX_APS/max_radio_num; i++) {
6461 apIndex = max_radio_num*i+radioIndex;
6462 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6463 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006464 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
6465 if (os_snprintf_error(sizeof(cmd), res)) {
6466 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6467 return RETURN_ERR;
6468 }
6469
developera3511852023-06-14 14:12:59 +08006470 _syscmd(cmd, buf, sizeof(buf));
6471 if(*buf == '1')
6472 wifi_setApEnable(apIndex, true);
6473 }
developer72fb0bb2023-01-11 09:46:29 +08006474
developera3511852023-06-14 14:12:59 +08006475 return ret;
developer72fb0bb2023-01-11 09:46:29 +08006476}
6477
6478struct channels_noise {
developera3511852023-06-14 14:12:59 +08006479 int channel;
6480 int noise;
developer72fb0bb2023-01-11 09:46:29 +08006481};
6482
6483// Return noise array for each channel
6484int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
6485{
developera3511852023-06-14 14:12:59 +08006486 char interface_name[16] = {0};
6487 FILE *f = NULL;
6488 char cmd[128] = {0};
6489 char line[256] = {0};
developer75bd10c2023-06-27 11:34:08 +08006490 int tmp = 0, arr_index = -1, res;
developer72fb0bb2023-01-11 09:46:29 +08006491
developera3511852023-06-14 14:12:59 +08006492 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6493 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08006494
6495 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
6496 if (os_snprintf_error(sizeof(cmd), res)) {
6497 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6498 return RETURN_ERR;
6499 }
developer72fb0bb2023-01-11 09:46:29 +08006500
developera3511852023-06-14 14:12:59 +08006501 if ((f = popen(cmd, "r")) == NULL) {
6502 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6503 return RETURN_ERR;
6504 }
developer69b61b02023-03-07 17:17:44 +08006505
developera3511852023-06-14 14:12:59 +08006506 while(fgets(line, sizeof(line), f) != NULL) {
6507 if(arr_index < channels_num){
developer37646972023-06-29 10:58:43 +08006508 if (sscanf(line, "%d", &tmp) == EOF)
6509 continue;
developera3511852023-06-14 14:12:59 +08006510 if (tmp > 0) { // channel frequency, the first line must be frequency
6511 arr_index++;
6512 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
6513 } else { // noise
6514 channels_noise_arr[arr_index].noise = tmp;
6515 }
6516 }else{
6517 break;
6518 }
6519 }
6520 pclose(f);
6521 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006522}
6523
6524//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
6525//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08006526INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08006527{
developera3511852023-06-14 14:12:59 +08006528 int index = -1;
6529 wifi_neighbor_ap2_t *scan_array = NULL;
6530 char cmd[256]={0};
6531 char buf[128]={0};
6532 char file_name[32] = {0};
6533 char filter_SSID[32] = {0};
6534 char line[256] = {0};
6535 char interface_name[16] = {0};
6536 char *ret = NULL;
6537 int freq=0;
6538 FILE *f = NULL;
6539 int channels_num = 0;
6540 int vht_channel_width = 0;
6541 int get_noise_ret = RETURN_ERR;
6542 bool filter_enable = false;
6543 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
developere40952c2023-06-15 18:46:43 +08006544 int phyId = 0, res;
developer32f2a182023-06-27 19:50:41 +08006545 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08006546
developera3511852023-06-14 14:12:59 +08006547 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006548
developera3511852023-06-14 14:12:59 +08006549 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
6550 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006551
6552 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
6553 if (os_snprintf_error(sizeof(file_name), res)) {
6554 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6555 return RETURN_ERR;
6556 }
developer72fb0bb2023-01-11 09:46:29 +08006557
developera3511852023-06-14 14:12:59 +08006558 f = fopen(file_name, "r");
6559 if (f != NULL) {
developerd14dff12023-06-28 22:47:44 +08006560 if (fgets(buf, sizeof(file_name), f) == NULL)
6561 wifi_debug(DEBUG_ERROR, "fgets failed\n");
developera3511852023-06-14 14:12:59 +08006562 if ((strncmp(buf, "0", 1)) != 0) {
developerd14dff12023-06-28 22:47:44 +08006563 if (fgets(filter_SSID, sizeof(file_name), f) == NULL)
6564 wifi_debug(DEBUG_ERROR, "fgets failed\n");
developera3511852023-06-14 14:12:59 +08006565 if (strlen(filter_SSID) != 0)
6566 filter_enable = true;
6567 }
developerd14dff12023-06-28 22:47:44 +08006568 if (fclose(f) != 0) {
6569 wifi_debug(DEBUG_ERROR, "fclose fail\n");
6570 return RETURN_ERR;
6571 }
developera3511852023-06-14 14:12:59 +08006572 }
developer72fb0bb2023-01-11 09:46:29 +08006573
developera3511852023-06-14 14:12:59 +08006574 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08006575 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
6576 if (os_snprintf_error(sizeof(cmd), res)) {
6577 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6578 return RETURN_ERR;
6579 }
6580
developera3511852023-06-14 14:12:59 +08006581 _syscmd(cmd, buf, sizeof(buf));
6582 channels_num = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08006583
developer32f2a182023-06-27 19:50:41 +08006584 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 +08006585 // 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 +08006586 if (os_snprintf_error(sizeof(cmd), res)) {
6587 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6588 return RETURN_ERR;
6589 }
developer86035662023-06-28 19:21:12 +08006590 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developera3511852023-06-14 14:12:59 +08006591 if ((f = popen(cmd, "r")) == NULL) {
6592 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6593 return RETURN_ERR;
6594 }
developer9ce44382023-06-28 11:09:37 +08006595 struct channels_noise *channels_noise_arr = NULL;
6596 if(channels_num > 0 && channels_num <= 243){
6597 channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
6598 } else{
6599 return RETURN_ERR;
6600 }
6601
6602 if(channels_noise_arr != NULL){
6603 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
6604 } else{
6605 fclose(f);
6606 return RETURN_ERR;
6607 }
6608
developer69b61b02023-03-07 17:17:44 +08006609
developera3511852023-06-14 14:12:59 +08006610 ret = fgets(line, sizeof(line), f);
6611 while (ret != NULL) {
6612 if(strstr(line, "BSS") != NULL) { // new neighbor info
6613 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
6614 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
6615 // 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 +08006616
developera3511852023-06-14 14:12:59 +08006617 if (!filter_BSS) {
6618 index++;
6619 wifi_neighbor_ap2_t *tmp;
6620 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
6621 if (tmp == NULL) { // no more memory to use
6622 index--;
6623 wifi_dbg_printf("%s: realloc failed\n", __func__);
6624 break;
6625 }
6626 scan_array = tmp;
6627 }
6628 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +08006629
developera3511852023-06-14 14:12:59 +08006630 filter_BSS = false;
developer86035662023-06-28 19:21:12 +08006631 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
6632 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6633 goto err;
6634 }
developerc79e9172023-06-06 19:48:03 +08006635 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +08006636 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +08006637 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +08006638 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +08006639 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +08006640 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
6641 } else if (strstr(line, "freq") != NULL) {
developer86035662023-06-28 19:21:12 +08006642 if (sscanf(line," freq: %d", &freq) != 1) {
6643 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6644 goto err;
6645 }
developera3511852023-06-14 14:12:59 +08006646 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +08006647
developera3511852023-06-14 14:12:59 +08006648 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +08006649 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08006650 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +08006651 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08006652 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +08006653 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08006654 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
6655 }
6656 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +08006657 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08006658 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +08006659 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08006660 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +08006661 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08006662 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
6663 }
developer72fb0bb2023-01-11 09:46:29 +08006664
developera3511852023-06-14 14:12:59 +08006665 scan_array[index].ap_Noise = 0;
6666 if (get_noise_ret == RETURN_OK) {
6667 for (int i = 0; i < channels_num; i++) {
6668 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
6669 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
6670 break;
6671 }
6672 }
6673 }
6674 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +08006675 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
6676 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6677 goto err;
6678 }
developera3511852023-06-14 14:12:59 +08006679 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +08006680 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
6681 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6682 goto err;
6683 }
developera3511852023-06-14 14:12:59 +08006684 } else if (strstr(line,"SSID") != NULL) {
developer86035662023-06-28 19:21:12 +08006685 if (sscanf(line," SSID: %32s", scan_array[index].ap_SSID) != 1) {
6686 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6687 goto err;
6688 }
developera3511852023-06-14 14:12:59 +08006689 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
6690 filter_BSS = true;
6691 }
6692 } else if (strstr(line, "Supported rates") != NULL) {
6693 char SRate[80] = {0}, *tmp = NULL;
6694 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +08006695 if (strlen(line) >= sizeof(SRate))
developer86035662023-06-28 19:21:12 +08006696 goto err;
developer32f2a182023-06-27 19:50:41 +08006697 strncpy(SRate, line, strlen(line));
developera3511852023-06-14 14:12:59 +08006698 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +08006699 if (tmp == NULL)
6700 goto err;
developera3511852023-06-14 14:12:59 +08006701 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +08006702 if (tmp == NULL)
6703 goto err;
developer32f2a182023-06-27 19:50:41 +08006704 if (strlen(tmp) >= sizeof(buf))
developer86035662023-06-28 19:21:12 +08006705 goto err;
developer32f2a182023-06-27 19:50:41 +08006706 strncpy(buf, tmp, strlen(tmp));
developera3511852023-06-14 14:12:59 +08006707 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +08006708
developera3511852023-06-14 14:12:59 +08006709 tmp = strtok(buf, " \n");
6710 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +08006711 if (strlen(tmp) >= (sizeof(SRate) - strlen(SRate)))
developer86035662023-06-28 19:21:12 +08006712 goto err;
developer32f2a182023-06-27 19:50:41 +08006713 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +08006714 if (SRate[strlen(SRate) - 1] == '*') {
6715 SRate[strlen(SRate) - 1] = '\0';
6716 }
developer32f2a182023-06-27 19:50:41 +08006717 if (strlen(SRate) >= (sizeof(SRate) - 1))
developer86035662023-06-28 19:21:12 +08006718 goto err;
developer32f2a182023-06-27 19:50:41 +08006719 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +08006720
developera3511852023-06-14 14:12:59 +08006721 tmp = strtok(NULL, " \n");
6722 }
6723 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +08006724 if (sizeof(scan_array[index].ap_SupportedDataTransferRates) <= strlen(SRate))
developer86035662023-06-28 19:21:12 +08006725 goto err;
developer32f2a182023-06-27 19:50:41 +08006726 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, strlen(SRate));
developera3511852023-06-14 14:12:59 +08006727 } else if (strstr(line, "DTIM") != NULL) {
developer86035662023-06-28 19:21:12 +08006728 if (sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod)) != 1) {
6729 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6730 goto err;
6731 }
developera3511852023-06-14 14:12:59 +08006732 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006733 if (sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) <= 4)
developer86035662023-06-28 19:21:12 +08006734 goto err;
developer32f2a182023-06-27 19:50:41 +08006735 strncat(scan_array[index].ap_SupportedStandards, ",ac",
6736 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6737 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
6738 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +08006739 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006740 strncat(scan_array[index].ap_SupportedStandards, ",n", sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6741 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
6742 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +08006743 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08006744 if (fgets(line, sizeof(line), f) == NULL) {
6745 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6746 goto err;
6747 }
6748 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
6749 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6750 goto err;
6751 }
developera3511852023-06-14 14:12:59 +08006752 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +08006753 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +08006754 } else {
developere40952c2023-06-15 18:46:43 +08006755 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +08006756 }
developere40952c2023-06-15 18:46:43 +08006757 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
6758 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +08006759 free(channels_noise_arr);
6760 fclose(f);
developere40952c2023-06-15 18:46:43 +08006761 return RETURN_ERR;
6762 }
6763
developera3511852023-06-14 14:12:59 +08006764 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
6765 continue;
6766 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +08006767 if (fgets(line, sizeof(line), f) == NULL) {
6768 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6769 goto err;
6770 }
6771 if (sscanf(line," * secondary channel offset: %s", buf) != 1) {
6772 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6773 goto err;
6774 }
developera3511852023-06-14 14:12:59 +08006775 if (!strcmp(buf, "above")) {
6776 //40Mhz +
developere40952c2023-06-15 18:46:43 +08006777 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 +08006778 }
6779 else if (!strcmp(buf, "below")) {
6780 //40Mhz -
developere40952c2023-06-15 18:46:43 +08006781 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 +08006782 } else {
6783 //20Mhz
developere40952c2023-06-15 18:46:43 +08006784 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
6785 }
6786 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
6787 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +08006788 goto err;
developera3511852023-06-14 14:12:59 +08006789 }
developere40952c2023-06-15 18:46:43 +08006790
developera3511852023-06-14 14:12:59 +08006791 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
6792 continue;
6793 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006794 strncat(scan_array[index].ap_SupportedStandards, ",ax",
6795 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
6796 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
6797 scan_array[index].ap_OperatingStandards[2] = '\0';
developer86035662023-06-28 19:21:12 +08006798 if (fgets(line, sizeof(line), f) == NULL) {
6799 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6800 goto err;
6801 }
developera3511852023-06-14 14:12:59 +08006802 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +08006803 if (strstr(line, "HE40/2.4GHz") != NULL) {
6804 len = strlen("11AXHE40PLUS");
6805 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
6806 } else {
6807 len = strlen("11AXHE20");
6808 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
6809 }
6810 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +08006811 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
6812 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006813 len = strlen("11AXHE80");
6814 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
6815 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developer86035662023-06-28 19:21:12 +08006816 if (fgets(line, sizeof(line), f) == NULL) {
6817 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6818 goto err;
6819 }
developera3511852023-06-14 14:12:59 +08006820 } else
6821 continue;
developer32f2a182023-06-27 19:50:41 +08006822 if (strstr(line, "HE160/5GHz") != NULL) {
6823 len = strlen("11AXHE160");
6824 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
6825 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
6826 }
developera3511852023-06-14 14:12:59 +08006827 }
6828 continue;
6829 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006830 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
6831 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08006832 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +08006833 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
6834 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +08006835 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +08006836 if (sscanf(line, " * Group cipher: %64s", scan_array[index].ap_EncryptionMode) != 1) {
6837 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
6838 goto err;
6839 }
developera3511852023-06-14 14:12:59 +08006840 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +08006841 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
6842 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +08006843 }
6844 }
developer86035662023-06-28 19:21:12 +08006845 if (fgets(line, sizeof(line), f) == NULL) {
6846 wifi_debug(DEBUG_ERROR, "fgets fail\n");
6847 goto err;
6848 }
developera3511852023-06-14 14:12:59 +08006849 }
developer72fb0bb2023-01-11 09:46:29 +08006850
developera3511852023-06-14 14:12:59 +08006851 if (!filter_BSS) {
6852 *output_array_size = index + 1;
6853 } else {
6854 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
6855 *output_array_size = index;
6856 }
6857 *neighbor_ap_array = scan_array;
6858 pclose(f);
6859 free(channels_noise_arr);
6860 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6861 return RETURN_OK;
developer86035662023-06-28 19:21:12 +08006862err:
6863 pclose(f);
6864 free(channels_noise_arr);
6865 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6866 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006867}
6868
6869//>> Deprecated: used for old RDKB code.
6870INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
6871{
developera3511852023-06-14 14:12:59 +08006872 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006873
developera3511852023-06-14 14:12:59 +08006874 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6875 output_struct->wifi_PLCPErrorCount = 0;
6876 output_struct->wifi_FCSErrorCount = 0;
6877 output_struct->wifi_InvalidMACCount = 0;
6878 output_struct->wifi_PacketsOtherReceived = 0;
6879 output_struct->wifi_Noise = 0;
6880 status = RETURN_OK;
6881 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6882 return status;
developer72fb0bb2023-01-11 09:46:29 +08006883}
6884
6885INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
6886{
developera3511852023-06-14 14:12:59 +08006887 char interface_name[16] = {0};
6888 char cmd[128] = {0};
6889 char buf[1280] = {0};
6890 char *pos = NULL;
developere40952c2023-06-15 18:46:43 +08006891 int res;
developer72fb0bb2023-01-11 09:46:29 +08006892
developera3511852023-06-14 14:12:59 +08006893 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6894 if (NULL == output_struct)
6895 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006896
developera3511852023-06-14 14:12:59 +08006897 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6898 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006899
developera3511852023-06-14 14:12:59 +08006900 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08006901
developere40952c2023-06-15 18:46:43 +08006902 res = snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
6903 if (os_snprintf_error(sizeof(cmd), res)) {
6904 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6905 return RETURN_ERR;
6906 }
6907
developera3511852023-06-14 14:12:59 +08006908 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006909
developera3511852023-06-14 14:12:59 +08006910 pos = buf;
6911 if ((pos = strstr(pos, "RX packets:")) == NULL)
6912 return RETURN_ERR;
6913 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08006914
developera3511852023-06-14 14:12:59 +08006915 if ((pos = strstr(pos, "TX packets:")) == NULL)
6916 return RETURN_ERR;
6917 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08006918
developera3511852023-06-14 14:12:59 +08006919 if ((pos = strstr(pos, "RX bytes:")) == NULL)
6920 return RETURN_ERR;
6921 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08006922
developera3511852023-06-14 14:12:59 +08006923 if ((pos = strstr(pos, "TX bytes:")) == NULL)
6924 return RETURN_ERR;
6925 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08006926
developer37646972023-06-29 10:58:43 +08006927 res = snprintf(cmd, sizeof(cmd),
6928 "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
6929 if (os_snprintf_error(sizeof(cmd), res)) {
6930 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6931 return RETURN_ERR;
6932 }
developera3511852023-06-14 14:12:59 +08006933 _syscmd(cmd, buf, sizeof(buf));
developer37646972023-06-29 10:58:43 +08006934 if (sscanf(buf, "%lu", &output_struct->wifi_Associations) == EOF)
6935 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developer72fb0bb2023-01-11 09:46:29 +08006936
developera3511852023-06-14 14:12:59 +08006937 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6938 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006939}
6940
6941INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
6942{
developera3511852023-06-14 14:12:59 +08006943 char interface_name[IF_NAME_SIZE] = {0};
6944 char interface_status[MAX_BUF_SIZE] = {0};
6945 char Value[MAX_BUF_SIZE] = {0};
6946 char buf[MAX_CMD_SIZE] = {0};
6947 char cmd[MAX_CMD_SIZE] = {0};
6948 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08006949 int res;
developer72fb0bb2023-01-11 09:46:29 +08006950
developera3511852023-06-14 14:12:59 +08006951 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6952 if (NULL == output_struct)
6953 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006954
developera3511852023-06-14 14:12:59 +08006955 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08006956
developera3511852023-06-14 14:12:59 +08006957 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
6958 return RETURN_ERR;
6959 GetIfacestatus(interface_name, interface_status);
developer72fb0bb2023-01-11 09:46:29 +08006960
developera3511852023-06-14 14:12:59 +08006961 if(0 != strcmp(interface_status, "1"))
6962 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08006963
6964 res = snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
6965 if (os_snprintf_error(sizeof(cmd), res)) {
6966 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6967 return RETURN_ERR;
6968 }
developer72fb0bb2023-01-11 09:46:29 +08006969
developera3511852023-06-14 14:12:59 +08006970 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +08006971
developera3511852023-06-14 14:12:59 +08006972 fp = fopen("/tmp/SSID_Stats.txt", "r");
6973 if(fp == NULL)
6974 {
6975 printf("/tmp/SSID_Stats.txt not exists \n");
6976 return RETURN_ERR;
6977 }
developer37646972023-06-29 10:58:43 +08006978 if (fclose(fp) == EOF) {
6979 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
6980 return RETURN_ERR;
6981 }
developer72fb0bb2023-01-11 09:46:29 +08006982
developer37646972023-06-29 10:58:43 +08006983 res = snprintf(buf, sizeof(buf),
6984 "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6985 if (os_snprintf_error(sizeof(buf), res)) {
6986 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6987 return RETURN_ERR;
6988 }
developera3511852023-06-14 14:12:59 +08006989 File_Reading(buf, Value);
6990 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
developer37646972023-06-29 10:58:43 +08006991 if ((Value[0] != '\0') && (output_struct->wifi_ErrorsReceived == 0)) {
6992 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
6993 return RETURN_ERR;
6994 }
developer72fb0bb2023-01-11 09:46:29 +08006995
developer37646972023-06-29 10:58:43 +08006996 res = snprintf(buf, sizeof(buf),
6997 "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
6998 if (os_snprintf_error(sizeof(buf), res)) {
6999 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7000 return RETURN_ERR;
7001 }
developera3511852023-06-14 14:12:59 +08007002 File_Reading(buf, Value);
7003 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
developer37646972023-06-29 10:58:43 +08007004 if ((Value[0] != '\0') && (output_struct->wifi_ErrorsSent == 0)) {
7005 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
7006 return RETURN_ERR;
7007 }
developer72fb0bb2023-01-11 09:46:29 +08007008
developer37646972023-06-29 10:58:43 +08007009 res = snprintf(buf, sizeof(buf),
7010 "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
7011 if (os_snprintf_error(sizeof(buf), res)) {
7012 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7013 return RETURN_ERR;
7014 }
developera3511852023-06-14 14:12:59 +08007015 File_Reading(buf, Value);
7016 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
developer37646972023-06-29 10:58:43 +08007017 if ((Value[0] != '\0') && (output_struct->wifi_DiscardedPacketsReceived == 0)) {
7018 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
7019 return RETURN_ERR;
7020 }
developer72fb0bb2023-01-11 09:46:29 +08007021
developer37646972023-06-29 10:58:43 +08007022 res = snprintf(buf, sizeof(buf),
7023 "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
7024 if (os_snprintf_error(sizeof(buf), res)) {
7025 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7026 return RETURN_ERR;
7027 }
developera3511852023-06-14 14:12:59 +08007028 File_Reading(buf, Value);
7029 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
developer37646972023-06-29 10:58:43 +08007030 if ((Value[0] != '\0') && (output_struct->wifi_DiscardedPacketsSent == 0)) {
7031 wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
7032 return RETURN_ERR;
7033 }
developer72fb0bb2023-01-11 09:46:29 +08007034
developera3511852023-06-14 14:12:59 +08007035 output_struct->wifi_UnicastPacketsSent = 0;
7036 output_struct->wifi_UnicastPacketsReceived = 0;
7037 output_struct->wifi_MulticastPacketsSent = 0;
7038 output_struct->wifi_MulticastPacketsReceived = 0;
7039 output_struct->wifi_BroadcastPacketsSent = 0;
7040 output_struct->wifi_BroadcastPacketsRecevied = 0;
7041 output_struct->wifi_UnknownPacketsReceived = 0;
developer72fb0bb2023-01-11 09:46:29 +08007042
developera3511852023-06-14 14:12:59 +08007043 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7044 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007045}
7046
7047INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
7048{
developera3511852023-06-14 14:12:59 +08007049 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007050
developera3511852023-06-14 14:12:59 +08007051 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7052 //Below values should get updated from hal
7053 output_struct->wifi_RetransCount=0;
7054 output_struct->wifi_FailedRetransCount=0;
7055 output_struct->wifi_RetryCount=0;
7056 output_struct->wifi_MultipleRetryCount=0;
7057 output_struct->wifi_ACKFailureCount=0;
7058 output_struct->wifi_AggregatedPacketCount=0;
developer72fb0bb2023-01-11 09:46:29 +08007059
developera3511852023-06-14 14:12:59 +08007060 status = RETURN_OK;
7061 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007062
developera3511852023-06-14 14:12:59 +08007063 return status;
developer72fb0bb2023-01-11 09:46:29 +08007064}
7065
7066INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
7067{
developera3511852023-06-14 14:12:59 +08007068 INT status = RETURN_ERR;
7069 UINT index;
7070 wifi_neighbor_ap_t *pt=NULL;
developer72fb0bb2023-01-11 09:46:29 +08007071
developera3511852023-06-14 14:12:59 +08007072 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7073 *output_array_size=2;
7074 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
7075 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
developer86035662023-06-28 19:21:12 +08007076 if (*neighbor_ap_array == NULL) {
7077 wifi_debug(DEBUG_ERROR, "calloc fail!\n");
7078 return RETURN_ERR;
7079 }
developera3511852023-06-14 14:12:59 +08007080 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
developer32f2a182023-06-27 19:50:41 +08007081 pt->ap_Radio[0] = '\0';
7082 pt->ap_SSID[0] = '\0';
7083 pt->ap_BSSID[0] = '\0';
7084 pt->ap_Mode[0] = '\0';
developera3511852023-06-14 14:12:59 +08007085 pt->ap_Channel=1;
7086 pt->ap_SignalStrength=0;
developer32f2a182023-06-27 19:50:41 +08007087 pt->ap_SecurityModeEnabled[0] = '\0';
7088 pt->ap_EncryptionMode[0] = '\0';
7089 pt->ap_OperatingFrequencyBand[0] = '\0';
7090 pt->ap_SupportedStandards[0] = '\0';
7091 pt->ap_OperatingStandards[0] = '\0';
7092 pt->ap_OperatingChannelBandwidth[0] = '\0';
7093 pt->ap_BasicDataTransferRates[0] = '\0';
7094 pt->ap_SupportedDataTransferRates[0] = '\0';
developera3511852023-06-14 14:12:59 +08007095 pt->ap_BeaconPeriod=1;
7096 pt->ap_Noise=0;
developera3511852023-06-14 14:12:59 +08007097 pt->ap_DTIMPeriod=1;
7098 pt->ap_ChannelUtilization = 1;
7099 }
developer72fb0bb2023-01-11 09:46:29 +08007100
developera3511852023-06-14 14:12:59 +08007101 status = RETURN_OK;
7102 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007103
developera3511852023-06-14 14:12:59 +08007104 return status;
developer72fb0bb2023-01-11 09:46:29 +08007105}
7106
7107//----------------- AP HAL -------------------------------
7108
7109//>> Deprecated: used for old RDKB code.
7110INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
7111{
developera3511852023-06-14 14:12:59 +08007112 if (NULL == output_ulong || NULL == output_struct)
7113 return RETURN_ERR;
7114 *output_ulong = 0;
7115 *output_struct = NULL;
7116 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007117}
7118
7119#ifdef HAL_NETLINK_IMPL
7120static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +08007121 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7122 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7123 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
7124 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
7125 char mac_addr[20];
7126 static int count=0;
7127 int rate=0;
developer72fb0bb2023-01-11 09:46:29 +08007128
developera3511852023-06-14 14:12:59 +08007129 wifi_device_info_t *out = (wifi_device_info_t*)arg;
developer72fb0bb2023-01-11 09:46:29 +08007130
developera3511852023-06-14 14:12:59 +08007131 nla_parse(tb,
7132 NL80211_ATTR_MAX,
7133 genlmsg_attrdata(gnlh, 0),
7134 genlmsg_attrlen(gnlh, 0),
7135 NULL);
developer72fb0bb2023-01-11 09:46:29 +08007136
developera3511852023-06-14 14:12:59 +08007137 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +08007138 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +08007139 return NL_SKIP;
7140 }
developer72fb0bb2023-01-11 09:46:29 +08007141
7142
developera3511852023-06-14 14:12:59 +08007143 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +08007144 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +08007145 return NL_SKIP;
7146 }
developer72fb0bb2023-01-11 09:46:29 +08007147
developera3511852023-06-14 14:12:59 +08007148 //devIndex starts from 1
7149 if( ++count == out->wifi_devIndex )
7150 {
7151 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
7152 //Getting the mac addrress
7153 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
developer72fb0bb2023-01-11 09:46:29 +08007154
developera3511852023-06-14 14:12:59 +08007155 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +08007156 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +08007157 return NL_SKIP;
7158 }
developer72fb0bb2023-01-11 09:46:29 +08007159
developera3511852023-06-14 14:12:59 +08007160 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
7161 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
7162 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
7163 out->wifi_devTxRate = rate/10;
7164 }
7165 }
developer72fb0bb2023-01-11 09:46:29 +08007166
developera3511852023-06-14 14:12:59 +08007167 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +08007168 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +08007169 return NL_SKIP;
7170 }
developer72fb0bb2023-01-11 09:46:29 +08007171
developera3511852023-06-14 14:12:59 +08007172 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
7173 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
7174 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
7175 out->wifi_devRxRate = rate/10;
7176 }
7177 }
7178 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
7179 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
developer72fb0bb2023-01-11 09:46:29 +08007180
developera3511852023-06-14 14:12:59 +08007181 out->wifi_devAssociatedDeviceAuthentiationState = 1;
7182 count = 0; //starts the count for next cycle
7183 return NL_STOP;
7184 }
developer72fb0bb2023-01-11 09:46:29 +08007185
developera3511852023-06-14 14:12:59 +08007186 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08007187
7188}
7189#endif
7190
7191INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
7192{
developera3511852023-06-14 14:12:59 +08007193 Netlink nl = {0};
7194 char if_name[IF_NAME_SIZE] = {0};
7195 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08007196 int res;
developer72fb0bb2023-01-11 09:46:29 +08007197
developera3511852023-06-14 14:12:59 +08007198 wifi_device_info_t info = {0};
7199 info.wifi_devIndex = devIndex;
developer72fb0bb2023-01-11 09:46:29 +08007200
developera3511852023-06-14 14:12:59 +08007201 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7202 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007203
developere40952c2023-06-15 18:46:43 +08007204 res = snprintf(if_name,sizeof(if_name),"%s", interface_name);
7205 if (os_snprintf_error(sizeof(if_name), res)) {
7206 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7207 return RETURN_ERR;
7208 }
developer72fb0bb2023-01-11 09:46:29 +08007209
developera3511852023-06-14 14:12:59 +08007210 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +08007211
developera3511852023-06-14 14:12:59 +08007212 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +08007213 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +08007214 return -1;
7215 }
developer72fb0bb2023-01-11 09:46:29 +08007216
developera3511852023-06-14 14:12:59 +08007217 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +08007218
developera3511852023-06-14 14:12:59 +08007219 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +08007220 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +08007221 nlfree(&nl);
7222 return -2;
7223 }
developer72fb0bb2023-01-11 09:46:29 +08007224
developera3511852023-06-14 14:12:59 +08007225 genlmsg_put(msg,
7226 NL_AUTO_PID,
7227 NL_AUTO_SEQ,
7228 nl.id,
7229 0,
7230 NLM_F_DUMP,
7231 NL80211_CMD_GET_STATION,
7232 0);
developer72fb0bb2023-01-11 09:46:29 +08007233
developera3511852023-06-14 14:12:59 +08007234 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
7235 nl_send_auto_complete(nl.socket, msg);
7236 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
7237 nl_recvmsgs(nl.socket, nl.cb);
7238 nlmsg_free(msg);
7239 nlfree(&nl);
developer72fb0bb2023-01-11 09:46:29 +08007240
developera3511852023-06-14 14:12:59 +08007241 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
7242 output_struct->wifi_devRxRate = info.wifi_devRxRate;
7243 output_struct->wifi_devTxRate = info.wifi_devTxRate;
7244 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
7245 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
7246 return RETURN_OK;
7247}
developer72fb0bb2023-01-11 09:46:29 +08007248
developera3511852023-06-14 14:12:59 +08007249INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
7250{
7251 if (NULL == device)
7252 return RETURN_ERR;
7253 return RETURN_OK;
7254}
7255//<<
developer72fb0bb2023-01-11 09:46:29 +08007256
developer72fb0bb2023-01-11 09:46:29 +08007257
7258//--------------wifi_ap_hal-----------------------------
7259//enables CTS protection for the radio used by this AP
7260INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
7261{
developera3511852023-06-14 14:12:59 +08007262 //save config and Apply instantly
7263 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007264}
7265
7266// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
7267INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
7268{
developera3511852023-06-14 14:12:59 +08007269 char config_file[64] = {'\0'};
7270 char config_dat_file[64] = {'\0'};
7271 char buf[64] = {'\0'};
7272 struct params list = {0};
7273 struct params dat = {0};
7274 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007275 int res;
developer72fb0bb2023-01-11 09:46:29 +08007276
developera3511852023-06-14 14:12:59 +08007277 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7278 list.name = "ht_coex";
developere40952c2023-06-15 18:46:43 +08007279 res = snprintf(buf, sizeof(buf), "%d", enable);
7280 if (os_snprintf_error(sizeof(buf), res)) {
7281 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7282 return RETURN_ERR;
7283 }
7284
developera3511852023-06-14 14:12:59 +08007285 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007286
developera3511852023-06-14 14:12:59 +08007287 dat.name = "HT_BSSCoexistence";
7288 dat.value = buf;
developerd1824452023-05-18 12:30:04 +08007289
developera3511852023-06-14 14:12:59 +08007290 band = wifi_index_to_band(apIndex);
developere40952c2023-06-15 18:46:43 +08007291 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7292 if (os_snprintf_error(sizeof(config_file), res)) {
7293 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7294 return RETURN_ERR;
7295 }
7296
7297 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7298 if (os_snprintf_error(sizeof(config_dat_file), res)) {
7299 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7300 return RETURN_ERR;
7301 }
7302
developera3511852023-06-14 14:12:59 +08007303 wifi_hostapdWrite(config_file, &list, 1);
7304 wifi_datfileWrite(config_dat_file, &dat, 1);
7305 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08007306
developera3511852023-06-14 14:12:59 +08007307 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007308
developera3511852023-06-14 14:12:59 +08007309 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007310}
7311
7312//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
7313INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
7314{
developera3511852023-06-14 14:12:59 +08007315 char config_file[MAX_BUF_SIZE] = {'\0'};
7316 char buf[MAX_BUF_SIZE] = {'\0'};
7317 struct params list;
developere40952c2023-06-15 18:46:43 +08007318 int res;
developer72fb0bb2023-01-11 09:46:29 +08007319
developera3511852023-06-14 14:12:59 +08007320 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7321 if (threshold < 256 || threshold > 2346 )
7322 return RETURN_ERR;
7323 list.name = "fragm_threshold";
developere40952c2023-06-15 18:46:43 +08007324 res = snprintf(buf, sizeof(buf), "%d", threshold);
7325 if (os_snprintf_error(sizeof(buf), res)) {
7326 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7327 return RETURN_ERR;
7328 }
7329
developera3511852023-06-14 14:12:59 +08007330 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007331
developere40952c2023-06-15 18:46:43 +08007332 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7333 if (os_snprintf_error(sizeof(config_file), res)) {
7334 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7335 return RETURN_ERR;
7336 }
7337
developera3511852023-06-14 14:12:59 +08007338 wifi_hostapdWrite(config_file, &list, 1);
7339 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08007340
developera3511852023-06-14 14:12:59 +08007341 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007342
developera3511852023-06-14 14:12:59 +08007343 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007344}
7345
7346// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
7347INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
7348{
developera3511852023-06-14 14:12:59 +08007349 char config_file[64] = {'\0'};
7350 char cmd[512] = {'\0'};
7351 char buf[512] = {'\0'};
7352 char stbc_config[16] = {'\0'};
7353 wifi_band band;
7354 int iterator = 0;
7355 BOOL current_stbc = FALSE;
7356 int ant_count = 0;
7357 int ant_bitmap = 0;
7358 struct params list;
7359 char dat_file[64] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007360 int res;
developer72fb0bb2023-01-11 09:46:29 +08007361
developera3511852023-06-14 14:12:59 +08007362 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007363
developera3511852023-06-14 14:12:59 +08007364 band = wifi_index_to_band(radioIndex);
7365 if (band == band_invalid)
7366 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007367
developera3511852023-06-14 14:12:59 +08007368 if (band == band_2_4)
7369 iterator = 1;
7370 else if ((band == band_5) || (band == band_6))
7371 iterator = 2;
7372 else
7373 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007374
developera3511852023-06-14 14:12:59 +08007375 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
7376 for (; ant_bitmap > 0; ant_bitmap >>= 1)
7377 ant_count += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08007378
developera3511852023-06-14 14:12:59 +08007379 if (ant_count == 1 && STBC_Enable == TRUE) {
developer75bd10c2023-06-27 11:34:08 +08007380 wifi_debug(DEBUG_ERROR, "can not enable STBC when using only one antenna\n");
developera3511852023-06-14 14:12:59 +08007381 return RETURN_OK;
7382 }
developer72fb0bb2023-01-11 09:46:29 +08007383
developere40952c2023-06-15 18:46:43 +08007384 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
7385 if (os_snprintf_error(sizeof(config_file), res)) {
7386 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7387 return RETURN_ERR;
7388 }
developer72fb0bb2023-01-11 09:46:29 +08007389
developera3511852023-06-14 14:12:59 +08007390 // set ht and vht config
7391 for (int i = 0; i < iterator; i++) {
7392 memset(stbc_config, 0, sizeof(stbc_config));
7393 memset(cmd, 0, sizeof(cmd));
7394 memset(buf, 0, sizeof(buf));
7395 list.name = (i == 0)?"ht_capab":"vht_capab";
developere40952c2023-06-15 18:46:43 +08007396 res = snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
7397 if (os_snprintf_error(sizeof(stbc_config), res)) {
7398 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7399 return RETURN_ERR;
7400 }
7401
7402 res = snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
7403 if (os_snprintf_error(sizeof(cmd), res)) {
7404 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7405 return RETURN_ERR;
7406 }
7407
developera3511852023-06-14 14:12:59 +08007408 _syscmd(cmd, buf, sizeof(buf));
7409 if (strlen(buf) != 0)
7410 current_stbc = TRUE;
7411 if (current_stbc == STBC_Enable)
7412 continue;
developer72fb0bb2023-01-11 09:46:29 +08007413
developera3511852023-06-14 14:12:59 +08007414 if (STBC_Enable == TRUE) {
7415 // Append the STBC flags in capab config
7416 memset(cmd, 0, sizeof(cmd));
7417 if (i == 0)
developere40952c2023-06-15 18:46:43 +08007418 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
developera3511852023-06-14 14:12:59 +08007419 else
developere40952c2023-06-15 18:46:43 +08007420 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
7421 if (os_snprintf_error(sizeof(cmd), res)) {
7422 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7423 return RETURN_ERR;
7424 }
7425
developera3511852023-06-14 14:12:59 +08007426 _syscmd(cmd, buf, sizeof(buf));
7427 } else if (STBC_Enable == FALSE) {
7428 // Remove the STBC flags and remain other flags in capab
7429 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08007430 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
7431 if (os_snprintf_error(sizeof(cmd), res)) {
7432 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7433 return RETURN_ERR;
7434 }
7435
developera3511852023-06-14 14:12:59 +08007436 _syscmd(cmd, buf, sizeof(buf));
7437 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08007438 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
7439 if (os_snprintf_error(sizeof(cmd), res)) {
7440 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7441 return RETURN_ERR;
7442 }
7443
developera3511852023-06-14 14:12:59 +08007444 _syscmd(cmd, buf, sizeof(buf));
7445 }
7446 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
7447 list.value = buf;
7448 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
7449 }
developere40952c2023-06-15 18:46:43 +08007450 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7451 if (os_snprintf_error(sizeof(dat_file), res)) {
7452 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7453 return RETURN_ERR;
7454 }
7455
7456 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
7457 if (os_snprintf_error(sizeof(cmd), res)) {
7458 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7459 return RETURN_ERR;
7460 }
7461
developera1255e42023-05-13 17:45:02 +08007462 _syscmd(cmd, buf, sizeof(buf));
7463 if ((band == band_5) || (band == band_6)) {
developere40952c2023-06-15 18:46:43 +08007464 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
7465 if (os_snprintf_error(sizeof(cmd), res)) {
7466 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7467 return RETURN_ERR;
7468 }
7469
developera1255e42023-05-13 17:45:02 +08007470 _syscmd(cmd, buf, sizeof(buf));
7471 }
developera3511852023-06-14 14:12:59 +08007472 /*wifi_reloadAp(radioIndex);
developera1255e42023-05-13 17:45:02 +08007473 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08007474
developera3511852023-06-14 14:12:59 +08007475 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7476 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007477}
7478
7479// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
7480INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
7481{
developera3511852023-06-14 14:12:59 +08007482 char dat_file[128] = {0};
developer2c22d832023-05-18 17:46:26 +08007483 wifi_band band;
7484 char amdus_buff[8] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007485 int res;
developer72fb0bb2023-01-11 09:46:29 +08007486
developer2c22d832023-05-18 17:46:26 +08007487 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007488
developer2c22d832023-05-18 17:46:26 +08007489 band = wifi_index_to_band(radioIndex);
7490 if (band == band_invalid) {
7491 printf("%s:Band Error\n", __func__);
7492 return RETURN_ERR;
7493 }
developere40952c2023-06-15 18:46:43 +08007494 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7495 if (os_snprintf_error(sizeof(dat_file), res)) {
7496 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7497 return RETURN_ERR;
7498 }
7499
developer2c22d832023-05-18 17:46:26 +08007500 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
7501 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08007502 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08007503 else
7504 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08007505
developer2c22d832023-05-18 17:46:26 +08007506 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7507
7508 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007509}
7510
7511// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
7512INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
7513{
developer2c22d832023-05-18 17:46:26 +08007514 char dat_file[128] = {0};
7515 BOOL enable;
7516 wifi_band band;
7517 char amdus_buff[8] = {'\0'};
7518 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08007519 int res;
developer72fb0bb2023-01-11 09:46:29 +08007520
developer2c22d832023-05-18 17:46:26 +08007521 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007522
developer2c22d832023-05-18 17:46:26 +08007523 band = wifi_index_to_band(radioIndex);
7524 if (band == band_invalid) {
7525 printf("%s:Band Error\n", __func__);
7526 return RETURN_ERR;
7527 }
developere40952c2023-06-15 18:46:43 +08007528 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7529 if (os_snprintf_error(sizeof(dat_file), res)) {
7530 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7531 return RETURN_ERR;
7532 }
7533
developer2c22d832023-05-18 17:46:26 +08007534 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
7535 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08007536 enable = TRUE;
developer2c22d832023-05-18 17:46:26 +08007537 else
7538 enable = FALSE;
7539 if (amsduEnable == enable)
developera3511852023-06-14 14:12:59 +08007540 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007541
developer2c22d832023-05-18 17:46:26 +08007542 params.name = "HT_AMSDU";
7543 if (amsduEnable)
7544 params.value = "1";
7545 else
7546 params.value = "0";
7547 wifi_datfileWrite(dat_file, &params, 1);
7548 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08007549
developer2c22d832023-05-18 17:46:26 +08007550 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007551
developera3511852023-06-14 14:12:59 +08007552 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007553}
7554
7555//P2 // outputs the number of Tx streams
7556INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
7557{
developera3511852023-06-14 14:12:59 +08007558 char buf[8] = {0};
7559 char cmd[128] = {0};
7560 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08007561 int res;
developer72fb0bb2023-01-11 09:46:29 +08007562
developera3511852023-06-14 14:12:59 +08007563 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007564
developera3511852023-06-14 14:12:59 +08007565 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08007566 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
7567 if (os_snprintf_error(sizeof(cmd), res)) {
7568 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7569 return RETURN_ERR;
7570 }
7571
developera3511852023-06-14 14:12:59 +08007572 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007573
developera3511852023-06-14 14:12:59 +08007574 *output_int = (INT)strtol(buf, NULL, 16);
developerd14dff12023-06-28 22:47:44 +08007575 if (*output_int == 0 && buf[0] != '0') {
7576 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
7577 return RETURN_ERR;
7578 }
developer72fb0bb2023-01-11 09:46:29 +08007579
developera3511852023-06-14 14:12:59 +08007580 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007581
developera3511852023-06-14 14:12:59 +08007582 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007583}
7584
7585INT fitChainMask(INT radioIndex, int antcount)
7586{
developera3511852023-06-14 14:12:59 +08007587 char buf[128] = {0};
7588 char cmd[128] = {0};
7589 char config_file[64] = {0};
7590 wifi_band band;
7591 struct params list[2] = {0};
developere40952c2023-06-15 18:46:43 +08007592 int res;
developer72fb0bb2023-01-11 09:46:29 +08007593
developera3511852023-06-14 14:12:59 +08007594 band = wifi_index_to_band(radioIndex);
7595 if (band == band_invalid)
7596 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007597
developera3511852023-06-14 14:12:59 +08007598 list[0].name = "he_mu_beamformer";
7599 list[1].name = "he_su_beamformer";
developer72fb0bb2023-01-11 09:46:29 +08007600
developere40952c2023-06-15 18:46:43 +08007601 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
7602 if (os_snprintf_error(sizeof(config_file), res)) {
7603 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7604 return RETURN_ERR;
7605 }
7606
developera3511852023-06-14 14:12:59 +08007607 if (antcount == 1) {
7608 // remove config about multiple antennas
developere40952c2023-06-15 18:46:43 +08007609 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
7610 if (os_snprintf_error(sizeof(cmd), res)) {
7611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7612 return RETURN_ERR;
7613 }
7614
developera3511852023-06-14 14:12:59 +08007615 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007616
developere40952c2023-06-15 18:46:43 +08007617 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
7618 if (os_snprintf_error(sizeof(cmd), res)) {
7619 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7620 return RETURN_ERR;
7621 }
7622
developera3511852023-06-14 14:12:59 +08007623 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007624
developere40952c2023-06-15 18:46:43 +08007625 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
7626 if (os_snprintf_error(sizeof(cmd), res)) {
7627 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7628 return RETURN_ERR;
7629 }
7630
developera3511852023-06-14 14:12:59 +08007631 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007632
developere40952c2023-06-15 18:46:43 +08007633 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
7634 if (os_snprintf_error(sizeof(cmd), res)) {
7635 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7636 return RETURN_ERR;
7637 }
7638
developera3511852023-06-14 14:12:59 +08007639 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007640
developera3511852023-06-14 14:12:59 +08007641 list[0].value = "0";
7642 list[1].value = "0";
7643 } else {
7644 // 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.
7645 if (band == band_2_4 || band == band_5) {
developere40952c2023-06-15 18:46:43 +08007646 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
7647 if (os_snprintf_error(sizeof(cmd), res)) {
7648 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7649 return RETURN_ERR;
7650 }
7651
developera3511852023-06-14 14:12:59 +08007652 _syscmd(cmd, buf, sizeof(buf));
7653 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08007654 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
7655 if (os_snprintf_error(sizeof(cmd), res)) {
7656 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7657 return RETURN_ERR;
7658 }
7659
developera3511852023-06-14 14:12:59 +08007660 _syscmd(cmd, buf, sizeof(buf));
7661 }
7662 }
7663 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08007664 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
7665 if (os_snprintf_error(sizeof(cmd), res)) {
7666 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7667 return RETURN_ERR;
7668 }
7669
developera3511852023-06-14 14:12:59 +08007670 _syscmd(cmd, buf, sizeof(buf));
7671 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08007672 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
7673 if (os_snprintf_error(sizeof(cmd), res)) {
7674 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7675 return RETURN_ERR;
7676 }
7677
developera3511852023-06-14 14:12:59 +08007678 _syscmd(cmd, buf, sizeof(buf));
7679 }
7680 }
developer72fb0bb2023-01-11 09:46:29 +08007681
developere40952c2023-06-15 18:46:43 +08007682 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
7683 if (os_snprintf_error(sizeof(cmd), res)) {
7684 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7685 return RETURN_ERR;
7686 }
7687
developera3511852023-06-14 14:12:59 +08007688 _syscmd(cmd, buf, sizeof(buf));
7689 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007690 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
7691 if (os_snprintf_error(sizeof(cmd), res)) {
7692 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7693 return RETURN_ERR;
7694 }
7695
developera3511852023-06-14 14:12:59 +08007696 _syscmd(cmd, buf, sizeof(buf));
7697 }
developer72fb0bb2023-01-11 09:46:29 +08007698
developere40952c2023-06-15 18:46:43 +08007699 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
developera3511852023-06-14 14:12:59 +08007700 _syscmd(cmd, buf, sizeof(buf));
7701 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007702 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
7703 if (os_snprintf_error(sizeof(cmd), res)) {
7704 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7705 return RETURN_ERR;
7706 }
7707
developera3511852023-06-14 14:12:59 +08007708 _syscmd(cmd, buf, sizeof(buf));
7709 }
developer72fb0bb2023-01-11 09:46:29 +08007710
developere40952c2023-06-15 18:46:43 +08007711 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
7712 if (os_snprintf_error(sizeof(cmd), res)) {
7713 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7714 return RETURN_ERR;
7715 }
7716
developera3511852023-06-14 14:12:59 +08007717 _syscmd(cmd, buf, sizeof(buf));
7718 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08007719 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
developera3511852023-06-14 14:12:59 +08007720 } else {
developere40952c2023-06-15 18:46:43 +08007721 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
7722 }
7723 if (os_snprintf_error(sizeof(cmd), res)) {
7724 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7725 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08007726 }
developere40952c2023-06-15 18:46:43 +08007727
developera3511852023-06-14 14:12:59 +08007728 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007729
developera3511852023-06-14 14:12:59 +08007730 list[0].value = "1";
7731 list[1].value = "1";
7732 }
7733 wifi_hostapdWrite(config_file, list, 2);
developerdaf24792023-06-06 11:40:04 +08007734 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007735}
7736
7737//P2 // sets the number of Tx streams to an enviornment variable
7738INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
7739{
developera3511852023-06-14 14:12:59 +08007740 char cmd[128] = {0};
7741 char buf[128] = {0};
7742 int phyId = 0;
7743 int cur_mask = 0;
7744 int antcountmsk = 0;
developera1255e42023-05-13 17:45:02 +08007745 INT cur_nss = 0;
developer863a4a62023-06-06 16:55:59 +08007746 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +08007747 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08007748 int res;
developer72fb0bb2023-01-11 09:46:29 +08007749
developera3511852023-06-14 14:12:59 +08007750 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007751
developera3511852023-06-14 14:12:59 +08007752 if (numStreams <= 0) {
developer75bd10c2023-06-27 11:34:08 +08007753 wifi_debug(DEBUG_ERROR, "chainmask is not supported %d.\n", numStreams);
developera3511852023-06-14 14:12:59 +08007754 return RETURN_ERR;
7755 }
developer72fb0bb2023-01-11 09:46:29 +08007756
developera3511852023-06-14 14:12:59 +08007757 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
developera1255e42023-05-13 17:45:02 +08007758 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
7759 cur_nss += 1;
7760 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
developera3511852023-06-14 14:12:59 +08007761 if (cur_nss == numStreams)
7762 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007763
developera3511852023-06-14 14:12:59 +08007764 wifi_setRadioEnable(radioIndex, FALSE);
developer72fb0bb2023-01-11 09:46:29 +08007765
developera3511852023-06-14 14:12:59 +08007766 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08007767 //iw need mask value.
7768 for (;numStreams > 0; numStreams--)
7769 antcountmsk |= 0x1 << (numStreams - 1);
developere40952c2023-06-15 18:46:43 +08007770 res = snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
7771 if (os_snprintf_error(sizeof(cmd), res)) {
7772 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7773 return RETURN_ERR;
7774 }
developerb758dfd2023-06-21 17:32:07 +08007775
developera3511852023-06-14 14:12:59 +08007776 _syscmd(cmd, buf, sizeof(buf));
7777 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007778 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007779 return RETURN_ERR;
7780 }
7781 band = wifi_index_to_band(radioIndex);
developera1255e42023-05-13 17:45:02 +08007782 if (band == band_invalid) {
7783 printf("%s:Band Error\n", __func__);
7784 return RETURN_ERR;
7785 }
developere40952c2023-06-15 18:46:43 +08007786 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
7787 if (os_snprintf_error(sizeof(dat_file), res)) {
7788 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7789 return RETURN_ERR;
7790 }
developerb758dfd2023-06-21 17:32:07 +08007791
developere40952c2023-06-15 18:46:43 +08007792 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
7793 if (os_snprintf_error(sizeof(cmd), res)) {
7794 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7795 return RETURN_ERR;
7796 }
developerb758dfd2023-06-21 17:32:07 +08007797
developera1255e42023-05-13 17:45:02 +08007798 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08007799 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007800 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007801 return RETURN_ERR;
7802 }
developere40952c2023-06-15 18:46:43 +08007803 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
7804 if (os_snprintf_error(sizeof(cmd), res)) {
7805 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7806 return RETURN_ERR;
7807 }
developerb758dfd2023-06-21 17:32:07 +08007808
developera1255e42023-05-13 17:45:02 +08007809 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08007810 if (strlen(buf) > 0) {
developer75bd10c2023-06-27 11:34:08 +08007811 wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
developera3511852023-06-14 14:12:59 +08007812 return RETURN_ERR;
7813 }
7814 fitChainMask(radioIndex, numStreams);
7815 wifi_setRadioEnable(radioIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +08007816
developera3511852023-06-14 14:12:59 +08007817 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7818 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007819}
7820
7821//P2 // outputs the number of Rx streams
7822INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
7823{
developera3511852023-06-14 14:12:59 +08007824 char buf[8] = {0};
7825 char cmd[128] = {0};
7826 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +08007827 int res;
developer72fb0bb2023-01-11 09:46:29 +08007828
developera3511852023-06-14 14:12:59 +08007829 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007830
developera3511852023-06-14 14:12:59 +08007831 phyId = radio_index_to_phy(radioIndex);
developer75bd10c2023-06-27 11:34:08 +08007832
7833 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
7834 if (os_snprintf_error(sizeof(cmd), res)) {
7835 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7836 return RETURN_ERR;
7837 }
developera3511852023-06-14 14:12:59 +08007838 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007839
developera3511852023-06-14 14:12:59 +08007840 *output_int = (INT)strtol(buf, NULL, 16);
developerd14dff12023-06-28 22:47:44 +08007841 if (*output_int == 0 && buf[0] != '0') {
7842 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
7843 return RETURN_ERR;
7844 }
developer72fb0bb2023-01-11 09:46:29 +08007845
developera3511852023-06-14 14:12:59 +08007846 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007847
developera3511852023-06-14 14:12:59 +08007848 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007849}
7850
7851//P2 // sets the number of Rx streams to an enviornment variable
7852INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
7853{
developera3511852023-06-14 14:12:59 +08007854 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7855 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
developer75bd10c2023-06-27 11:34:08 +08007856 wifi_debug(DEBUG_ERROR, "wifi_setRadioTxChainMask return error.\n");
developera3511852023-06-14 14:12:59 +08007857 return RETURN_ERR;
7858 }
7859 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7860 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007861}
7862
7863//Get radio RDG enable setting
7864INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
7865{
developer47cc27a2023-05-17 23:09:58 +08007866 if (NULL == output_bool)
7867 return RETURN_ERR;
7868
7869 *output_bool = TRUE;
7870 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007871}
7872
7873//Get radio RDG enable setting
7874INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
7875{
developer47cc27a2023-05-17 23:09:58 +08007876 char rdg_status[2] = {0};
7877 char dat_file[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08007878 int res;
developer47cc27a2023-05-17 23:09:58 +08007879
7880 if (NULL == output_bool)
7881 return RETURN_ERR;
7882
7883 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08007884 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7885 if (os_snprintf_error(sizeof(dat_file), res)) {
7886 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7887 return RETURN_ERR;
7888 }
developer47cc27a2023-05-17 23:09:58 +08007889
7890 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
7891 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
7892 *output_bool = TRUE;
7893 else
7894 *output_bool = FALSE;
7895
7896 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007897}
7898
7899//Set radio RDG enable setting
7900INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
7901{
developer47cc27a2023-05-17 23:09:58 +08007902 char dat_file[MAX_CMD_SIZE] = {0};
7903 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08007904 int res;
developer47cc27a2023-05-17 23:09:58 +08007905
7906 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08007907 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
7908 if (os_snprintf_error(sizeof(dat_file), res)) {
7909 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7910 return RETURN_ERR;
7911 }
developer47cc27a2023-05-17 23:09:58 +08007912
7913 params.name = "HT_RDG";
7914
developera3511852023-06-14 14:12:59 +08007915 if (enable) {
7916 params.value = "1";
7917 } else {
7918 params.value = "0";
7919 }
developer47cc27a2023-05-17 23:09:58 +08007920
7921 wifi_datfileWrite(dat_file, &params, 1);
7922
7923 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007924}
7925
developer5cd4c862023-05-26 09:34:42 +08007926
7927int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08007928{
developer5cd4c862023-05-26 09:34:42 +08007929 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7930 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
7931 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7932 unsigned char status;
7933 unsigned char *out_status = data;
7934 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08007935
developer5cd4c862023-05-26 09:34:42 +08007936 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7937 genlmsg_attrlen(gnlh, 0), NULL);
7938 if (err < 0){
7939 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7940 return err;
7941 }
developer8e6583c2023-05-23 13:36:06 +08007942
developer5cd4c862023-05-26 09:34:42 +08007943 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7944 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
7945 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7946 if (err < 0){
7947 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
7948 return err;
7949 }
developer8e6583c2023-05-23 13:36:06 +08007950
developer5cd4c862023-05-26 09:34:42 +08007951 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
7952 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
7953 if (status == 0) {
7954 wifi_debug(DEBUG_NOTICE, "disabled\n");
7955 } else {
7956 wifi_debug(DEBUG_NOTICE, "enabled\n");
7957 }
7958 *out_status = status;
7959 }
7960 }
developer8e6583c2023-05-23 13:36:06 +08007961
developer5cd4c862023-05-26 09:34:42 +08007962 return 0;
7963}
developer8e6583c2023-05-23 13:36:06 +08007964
developer5cd4c862023-05-26 09:34:42 +08007965int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
7966{
7967 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7968 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
7969 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7970 unsigned char status;
7971 unsigned char *out_status = data;
7972 int err = 0;
7973
7974 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7975 genlmsg_attrlen(gnlh, 0), NULL);
7976 if (err < 0) {
7977 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7978 return err;
7979 }
7980
7981 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7982 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
7983 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7984 if (err < 0) {
7985 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
7986 return err;
7987 }
7988
7989 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
7990 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
7991 if (status == 0) {
7992 wifi_debug(DEBUG_NOTICE, "disabled\n");
7993 } else {
7994 wifi_debug(DEBUG_NOTICE, "enabled\n");
7995 }
7996 *out_status = status;
7997 }
7998 }
7999
8000 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08008001}
8002
developer5cd4c862023-05-26 09:34:42 +08008003INT mtk_wifi_get_ba_decl_auto_status(
8004 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
8005{
8006 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08008007 unsigned int if_idx = 0;
8008 int ret = -1;
8009 struct unl unl_ins;
8010 struct nl_msg *msg = NULL;
8011 struct nlattr * msg_data = NULL;
8012 struct mtk_nl80211_param param;
8013
8014 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8015 return RETURN_ERR;
8016 if_idx = if_nametoindex(inf_name);
8017 if (!if_idx) {
8018 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8019 return RETURN_ERR;
8020 }
8021 /*init mtk nl80211 vendor cmd*/
8022 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
8023 param.if_type = NL80211_ATTR_IFINDEX;
8024 param.if_idx = if_idx;
8025
8026 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8027 if (ret) {
8028 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8029 return RETURN_ERR;
8030 }
8031 /*add mtk vendor cmd data*/
8032 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
8033 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8034 nlmsg_free(msg);
8035 goto err;
8036 }
8037
8038 /*send mtk nl80211 vendor msg*/
8039 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
8040 if (ret) {
8041 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8042 goto err;
8043 }
8044 /*deinit mtk nl80211 vendor msg*/
8045 mtk_nl80211_deint(&unl_ins);
8046 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
8047 return RETURN_OK;
8048err:
8049 mtk_nl80211_deint(&unl_ins);
8050 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8051 return RETURN_ERR;
8052}
developere0ff7232023-06-08 16:33:14 +08008053
8054INT mtk_wifi_set_auto_ba_en(
8055 INT apIndex, INT vendor_data_attr, BOOL enable)
8056{
8057 char inf_name[IF_NAME_SIZE] = {0};
8058 unsigned int if_idx = 0;
8059 int ret = -1;
8060 struct unl unl_ins;
8061 struct nl_msg *msg = NULL;
8062 struct nlattr * msg_data = NULL;
8063 struct mtk_nl80211_param param;
8064
8065 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8066 return RETURN_ERR;
8067 if_idx = if_nametoindex(inf_name);
8068 if (!if_idx) {
8069 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8070 return RETURN_ERR;
8071 }
8072 /*init mtk nl80211 vendor cmd*/
8073 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
8074 param.if_type = NL80211_ATTR_IFINDEX;
8075 param.if_idx = if_idx;
8076
8077 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8078 if (ret) {
8079 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8080 return RETURN_ERR;
8081 }
8082 /*add mtk vendor cmd data*/
8083 if (nla_put_u8(msg, vendor_data_attr, enable)) {
8084 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8085 nlmsg_free(msg);
8086 goto err;
8087 }
8088
8089 /*send mtk nl80211 vendor msg*/
8090 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8091 if (ret) {
8092 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8093 goto err;
8094 }
8095 /*deinit mtk nl80211 vendor msg*/
8096 mtk_nl80211_deint(&unl_ins);
8097 return RETURN_OK;
8098err:
8099 mtk_nl80211_deint(&unl_ins);
8100 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8101 return RETURN_ERR;
8102}
8103
developer5cd4c862023-05-26 09:34:42 +08008104//Get radio ADDBA enable setting
8105INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
8106{
8107 if (output_bool == NULL) {
8108 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8109 return RETURN_ERR;
8110 }
8111 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
8112 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
8113 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
8114 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
8115 return RETURN_ERR;
8116 }
8117 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
8118 return RETURN_OK;
8119}
8120
developer72fb0bb2023-01-11 09:46:29 +08008121//Set radio ADDBA enable setting
8122INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
8123{
developera3511852023-06-14 14:12:59 +08008124 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008125}
8126
8127//Get radio auto block ack enable setting
8128INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
8129{
developer5cd4c862023-05-26 09:34:42 +08008130 if (output_bool == NULL) {
8131 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8132 return RETURN_ERR;
8133 }
developer8e6583c2023-05-23 13:36:06 +08008134
developera3511852023-06-14 14:12:59 +08008135 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
developer5cd4c862023-05-26 09:34:42 +08008136 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
8137 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
8138 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
8139 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
8140 return RETURN_ERR;
8141 }
8142 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
8143 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008144}
8145
8146//Set radio auto block ack enable setting
8147INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
8148{
developera3511852023-06-14 14:12:59 +08008149 if (mtk_wifi_set_auto_ba_en
developere0ff7232023-06-08 16:33:14 +08008150 (radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
8151 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
8152 return RETURN_ERR;
8153 }
8154 wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08008155 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008156}
8157
8158//Get radio 11n pure mode enable support
8159INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
8160{
developera3511852023-06-14 14:12:59 +08008161 if (NULL == output_bool)
8162 return RETURN_ERR;
8163 *output_bool = TRUE;
8164 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008165}
8166
8167//Get radio 11n pure mode enable setting
8168INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
8169{
developera3511852023-06-14 14:12:59 +08008170 if (NULL == output_bool)
8171 return RETURN_ERR;
8172 *output_bool = TRUE;
8173 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008174}
8175
8176//Set radio 11n pure mode enable setting
developer86035662023-06-28 19:21:12 +08008177INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
developer72fb0bb2023-01-11 09:46:29 +08008178{
developer82533be2023-06-28 17:21:01 +08008179 char interface_name[16] = {0};
8180 int if_idx, ret = 0;
8181 struct nl_msg *msg = NULL;
8182 struct nlattr * msg_data = NULL;
8183 struct mtk_nl80211_param param;
8184 struct unl unl_ins;
8185
8186 if (radioIndex > MAX_APS) {
8187 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", radioIndex);
8188 return RETURN_ERR;
8189 }
8190 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8191 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
8192 return RETURN_ERR;
developerd14dff12023-06-28 22:47:44 +08008193
developer82533be2023-06-28 17:21:01 +08008194 if_idx = if_nametoindex(interface_name);
8195 /*init mtk nl80211 vendor cmd*/
8196 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
8197 param.if_type = NL80211_ATTR_IFINDEX;
8198 param.if_idx = if_idx;
8199 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8200 if (ret) {
8201 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8202 return RETURN_ERR;
8203 }
8204 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_HT_OP_MODE, enable)) {
8205 printf("Nla put attribute error\n");
8206 nlmsg_free(msg);
8207 goto err;
8208 }
8209 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8210 if (ret) {
8211 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8212 goto err;
8213 }
8214 mtk_nl80211_deint(&unl_ins);
8215 //wifi_debug(DEBUG_NOTICE, "set Gf cmd success.\n");
8216 printf("set gf=%d cmd success.\n", enable);
8217 return RETURN_OK;
8218err:
8219 mtk_nl80211_deint(&unl_ins);
8220 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08008221 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008222}
8223
developer5cd4c862023-05-26 09:34:42 +08008224int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08008225{
developer5cd4c862023-05-26 09:34:42 +08008226 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8227 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
8228 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8229 unsigned char status = 0, *out_status = data;
8230 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08008231
developer5cd4c862023-05-26 09:34:42 +08008232 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8233 genlmsg_attrlen(gnlh, 0), NULL);
8234 if (err < 0) {
8235 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
8236 return err;
8237 }
developer72fb0bb2023-01-11 09:46:29 +08008238
developer5cd4c862023-05-26 09:34:42 +08008239 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8240 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
8241 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8242 if (err < 0){
8243 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
8244 return err;
8245 }
developer72fb0bb2023-01-11 09:46:29 +08008246
developer5cd4c862023-05-26 09:34:42 +08008247 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
8248 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
8249 if (status == 0) {
8250 wifi_debug(DEBUG_NOTICE, "disabled\n");
8251 } else {
8252 wifi_debug(DEBUG_NOTICE, "enabled\n");
8253 }
8254 *out_status = status;
8255 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
8256 }
8257 }
8258
8259 return 0;
8260}
8261
8262INT mtk_wifi_set_igmp_en_status(
8263 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
8264 unsigned char in_en_stat, BOOL *output_bool)
8265{
8266 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08008267 unsigned int if_idx = 0;
8268 int ret = -1;
8269 struct unl unl_ins;
8270 struct nl_msg *msg = NULL;
8271 struct nlattr * msg_data = NULL;
8272 struct mtk_nl80211_param param;
8273
8274 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8275 return RETURN_ERR;
8276 if_idx = if_nametoindex(inf_name);
8277 if (!if_idx) {
8278 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
8279 return RETURN_ERR;
8280 }
8281 /*init mtk nl80211 vendor cmd*/
8282 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
8283 param.if_type = NL80211_ATTR_IFINDEX;
8284 param.if_idx = if_idx;
8285
8286 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8287 if (ret) {
8288 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8289 return RETURN_ERR;
8290 }
8291 /*add mtk vendor cmd data*/
8292 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
8293 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
8294 nlmsg_free(msg);
8295 goto err;
8296 }
8297
8298 /*send mtk nl80211 vendor msg*/
8299 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
8300 if (ret) {
8301 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8302 goto err;
8303 }
8304 /*deinit mtk nl80211 vendor msg*/
8305 mtk_nl80211_deint(&unl_ins);
8306 if (output_bool) {
8307 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
8308 } else {
8309 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
8310 }
8311 return RETURN_OK;
8312err:
8313 mtk_nl80211_deint(&unl_ins);
8314 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
8315 return RETURN_ERR;
8316}
8317
8318
8319//Get radio IGMP snooping enable setting
8320INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
8321{
8322 if (output_bool == NULL) {
8323 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
8324 return RETURN_ERR;
8325 }
developera3511852023-06-14 14:12:59 +08008326 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08008327 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
8328 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
8329 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
8330 return RETURN_ERR;
8331 }
8332 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developera3511852023-06-14 14:12:59 +08008333 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008334}
8335
8336//Set radio IGMP snooping enable setting
8337INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
8338{
developera3511852023-06-14 14:12:59 +08008339 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08008340 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
8341 NULL, enable, NULL) != RETURN_OK) {
8342 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
8343 return RETURN_ERR;
8344 }
8345 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08008346 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008347}
8348
8349//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08008350INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08008351{
developera3511852023-06-14 14:12:59 +08008352 if (NULL == output_int)
8353 return RETURN_ERR;
8354 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08008355
developera3511852023-06-14 14:12:59 +08008356 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008357}
8358
8359
8360//---------------------------------------------------------------------------------------------------
8361//
8362// Additional Wifi AP level APIs used for Access Point devices
8363//
8364//---------------------------------------------------------------------------------------------------
8365
8366// creates a new ap and pushes these parameters to the hardware
8367INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
8368{
developera3511852023-06-14 14:12:59 +08008369 // Deprecated when use hal version 3, use wifi_createVap() instead.
8370 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008371}
8372
8373// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
8374INT wifi_deleteAp(INT apIndex)
8375{
developer7e4a2a62023-04-06 19:56:03 +08008376 char interface_name[16] = {0};
8377 char buf[MAX_BUF_SIZE];
8378 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08008379 int res;
developer72fb0bb2023-01-11 09:46:29 +08008380
developer7e4a2a62023-04-06 19:56:03 +08008381 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8382 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08008383
developere40952c2023-06-15 18:46:43 +08008384 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8385 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
8386 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8387 return RETURN_ERR;
8388 }
developer7e4a2a62023-04-06 19:56:03 +08008389 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008390
developer7e4a2a62023-04-06 19:56:03 +08008391 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008392
developer7e4a2a62023-04-06 19:56:03 +08008393 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008394}
8395
8396// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
8397INT wifi_getApName(INT apIndex, CHAR *output_string)
8398{
developer7e4a2a62023-04-06 19:56:03 +08008399 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008400 int radio_idx = 0;
8401 int bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08008402 int res;
developer72fb0bb2023-01-11 09:46:29 +08008403
developer7e4a2a62023-04-06 19:56:03 +08008404 if(!output_string)
8405 return RETURN_ERR;
8406
8407 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8408 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
8409
developere40952c2023-06-15 18:46:43 +08008410 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 +08008411 } else
developere40952c2023-06-15 18:46:43 +08008412 res = snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
8413
8414 if (os_snprintf_error(IF_NAME_SIZE, res)) {
8415 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8416 return RETURN_ERR;
8417 }
developer7e4a2a62023-04-06 19:56:03 +08008418
8419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008420}
8421
8422// Outputs the index number in that corresponds to the SSID string
8423INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
8424{
developer7e4a2a62023-04-06 19:56:03 +08008425 char cmd [128] = {0};
8426 char buf[32] = {0};
8427 char ap_idx = 0;
8428 char *apIndex_str = NULL;
8429 char radio_idx = 0;
8430 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08008431 int res;
developer72fb0bb2023-01-11 09:46:29 +08008432
developere40952c2023-06-15 18:46:43 +08008433 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 +08008434 inputSsidString);
developere40952c2023-06-15 18:46:43 +08008435
8436 if (os_snprintf_error(sizeof(cmd), res)) {
8437 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8438 return RETURN_ERR;
8439 }
8440
developer7e4a2a62023-04-06 19:56:03 +08008441 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008442
developer7e4a2a62023-04-06 19:56:03 +08008443 if (strlen(buf)) {
8444 apIndex_str = strtok(buf, "\n");
developerd14dff12023-06-28 22:47:44 +08008445 if (apIndex_str == NULL) {
8446 wifi_debug(DEBUG_ERROR, "strtok fail\n");
8447 return RETURN_ERR;
8448 }
developer7e4a2a62023-04-06 19:56:03 +08008449 *output_int = strtoul(apIndex_str, NULL, 10);
developerd14dff12023-06-28 22:47:44 +08008450 if (*output_int == 0 && apIndex_str[0] != '0') {
8451 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
8452 return RETURN_ERR;
8453 }
developer7e4a2a62023-04-06 19:56:03 +08008454 return RETURN_OK;
8455 }
developer72fb0bb2023-01-11 09:46:29 +08008456
developer7e4a2a62023-04-06 19:56:03 +08008457 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
8458 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
8459 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
8460 radio_idx = 2;
8461 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
8462 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
8463 radio_idx = 1;
8464 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
8465 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
8466 radio_idx = 0;
8467 } else {
8468 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
8469 __func__, inputSsidString, ap_idx);
developera3511852023-06-14 14:12:59 +08008470 *output_int = -1;
8471 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08008472 }
8473
8474 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
8475
8476 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
8477 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
8478 __func__, inputSsidString, ap_idx);
8479 *output_int = ap_idx;
8480 return RETURN_OK;
8481 }
8482
8483 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008484}
8485
8486INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
8487{
developera3511852023-06-14 14:12:59 +08008488 return wifi_getIndexFromName(inputSsidString, output_int);
developer72fb0bb2023-01-11 09:46:29 +08008489}
8490
8491// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
8492INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
8493{
developera3511852023-06-14 14:12:59 +08008494 char buf[MAX_BUF_SIZE] = {0};
8495 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08008496 int res;
developer72fb0bb2023-01-11 09:46:29 +08008497
developera3511852023-06-14 14:12:59 +08008498 if(NULL == output_string)
8499 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008500
developer32f2a182023-06-27 19:50:41 +08008501 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
8502 if (os_snprintf_error(sizeof(config_file), res)) {
8503 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8504 return RETURN_ERR;
8505 }
developera3511852023-06-14 14:12:59 +08008506 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
8507 if((strcmp(buf,"3")==0))
developere40952c2023-06-15 18:46:43 +08008508 res = snprintf(output_string, 32, "WPAand11i");
developera3511852023-06-14 14:12:59 +08008509 else if((strcmp(buf,"2")==0))
developere40952c2023-06-15 18:46:43 +08008510 res = snprintf(output_string, 32, "11i");
developera3511852023-06-14 14:12:59 +08008511 else if((strcmp(buf,"1")==0))
developere40952c2023-06-15 18:46:43 +08008512 res = snprintf(output_string, 32, "WPA");
developera3511852023-06-14 14:12:59 +08008513 else
developere40952c2023-06-15 18:46:43 +08008514 res = snprintf(output_string, 32, "None");
8515 if (os_snprintf_error(32, res)) {
8516 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8517 return RETURN_ERR;
8518 }
developer72fb0bb2023-01-11 09:46:29 +08008519
developera3511852023-06-14 14:12:59 +08008520 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008521}
8522
8523// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
8524INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
8525{
developera3511852023-06-14 14:12:59 +08008526 char config_file[MAX_BUF_SIZE] = {0};
8527 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008528 int res;
developer72fb0bb2023-01-11 09:46:29 +08008529
developera3511852023-06-14 14:12:59 +08008530 if (NULL == beaconTypeString)
8531 return RETURN_ERR;
8532 list.name = "wpa";
8533 list.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08008534
developera3511852023-06-14 14:12:59 +08008535 if((strcmp(beaconTypeString,"WPAand11i")==0))
8536 list.value="3";
8537 else if((strcmp(beaconTypeString,"11i")==0))
8538 list.value="2";
8539 else if((strcmp(beaconTypeString,"WPA")==0))
8540 list.value="1";
developer72fb0bb2023-01-11 09:46:29 +08008541
developer75bd10c2023-06-27 11:34:08 +08008542 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8543 if (os_snprintf_error(sizeof(config_file), res)) {
8544 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8545 return RETURN_ERR;
8546 }
developera3511852023-06-14 14:12:59 +08008547 wifi_hostapdWrite(config_file, &list, 1);
8548 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8549 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8550 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008551}
8552
8553// sets the beacon interval on the hardware for this AP
8554INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
8555{
developera3511852023-06-14 14:12:59 +08008556 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8557 struct params params={'\0'};
8558 char buf[MAX_BUF_SIZE] = {'\0'};
8559 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08008560 int res;
developer72fb0bb2023-01-11 09:46:29 +08008561
developera3511852023-06-14 14:12:59 +08008562 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08008563 res = snprintf(buf, sizeof(buf), "%u", beaconInterval);
8564 if (os_snprintf_error(sizeof(buf), res)) {
8565 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8566 return RETURN_ERR;
8567 }
developera3511852023-06-14 14:12:59 +08008568 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08008569
developer75bd10c2023-06-27 11:34:08 +08008570 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8571 if (os_snprintf_error(sizeof(config_file), res)) {
8572 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8573 return RETURN_ERR;
8574 }
developera3511852023-06-14 14:12:59 +08008575 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08008576
developera3511852023-06-14 14:12:59 +08008577 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8578 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8579 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008580}
8581
8582INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
8583{
developera3511852023-06-14 14:12:59 +08008584 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
8585 return RETURN_ERR;
8586 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008587}
8588
8589// Get the packet size threshold supported.
8590INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
8591{
developera3511852023-06-14 14:12:59 +08008592 //save config and apply instantly
8593 if (NULL == output_bool)
8594 return RETURN_ERR;
8595 *output_bool = TRUE;
8596 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008597}
8598
8599// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
8600INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
8601{
developera3511852023-06-14 14:12:59 +08008602 char buf[16] = {0};
8603 char config_file[128] = {0};
8604 struct params param = {0};
developere40952c2023-06-15 18:46:43 +08008605 int res;
developer72fb0bb2023-01-11 09:46:29 +08008606
developera3511852023-06-14 14:12:59 +08008607 if (threshold > 65535) {
developer75bd10c2023-06-27 11:34:08 +08008608 wifi_debug(DEBUG_ERROR, "rts threshold %u is too big.\n", threshold);
developera3511852023-06-14 14:12:59 +08008609 return RETURN_ERR;
8610 }
developer72fb0bb2023-01-11 09:46:29 +08008611
developere40952c2023-06-15 18:46:43 +08008612 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8613 if (os_snprintf_error(sizeof(config_file), res)) {
8614 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8615 return RETURN_ERR;
8616 }
8617
8618 res = snprintf(buf, sizeof(buf), "%u", threshold);
8619 if (os_snprintf_error(sizeof(buf), res)) {
8620 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8621 return RETURN_ERR;
8622 }
developera3511852023-06-14 14:12:59 +08008623 param.name = "rts_threshold";
8624 param.value = buf;
8625 wifi_hostapdWrite(config_file, &param, 1);
8626 wifi_hostapdProcessUpdate(apIndex, &param, 1);
8627 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008628
developera3511852023-06-14 14:12:59 +08008629 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008630}
8631
8632// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8633INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
8634{
developere40952c2023-06-15 18:46:43 +08008635 int res;
8636
developera3511852023-06-14 14:12:59 +08008637 if (NULL == output_string)
8638 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008639 res = snprintf(output_string, 32, "TKIPandAESEncryption");
8640 if (os_snprintf_error(32, res)) {
8641 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8642 return RETURN_ERR;
8643 }
developera3511852023-06-14 14:12:59 +08008644 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008645
8646}
8647
8648// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8649INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
8650{
developera3511852023-06-14 14:12:59 +08008651 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8652 char *param_name = NULL;
8653 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
developerc79e9172023-06-06 19:48:03 +08008654 unsigned int len;
developere40952c2023-06-15 18:46:43 +08008655 int res;
developer72fb0bb2023-01-11 09:46:29 +08008656
developera3511852023-06-14 14:12:59 +08008657 if(NULL == output_string)
8658 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008659
developer75bd10c2023-06-27 11:34:08 +08008660 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8661 if (os_snprintf_error(sizeof(config_file), res)) {
8662 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8663 return RETURN_ERR;
8664 }
8665
developera3511852023-06-14 14:12:59 +08008666 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008667
developera3511852023-06-14 14:12:59 +08008668 if(strcmp(buf,"0")==0)
8669 {
8670 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
developere40952c2023-06-15 18:46:43 +08008671 res = snprintf(output_string, 32, "None");
8672 if (os_snprintf_error(32, res)) {
8673 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8674 return RETURN_ERR;
8675 }
developera3511852023-06-14 14:12:59 +08008676 return RETURN_OK;
8677 }
8678 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
8679 param_name = "rsn_pairwise";
8680 else if((strcmp(buf,"1")==0))
8681 param_name = "wpa_pairwise";
8682 else
8683 return RETURN_ERR;
8684 memset(output_string,'\0',32);
8685 wifi_hostapdRead(config_file,param_name,output_string,32);
8686 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
8687 param_name = "wpa_pairwise";
8688 memset(output_string, '\0', 32);
8689 wifi_hostapdRead(config_file, param_name, output_string, 32);
8690 }
8691 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
developer72fb0bb2023-01-11 09:46:29 +08008692
developera3511852023-06-14 14:12:59 +08008693 if(strcmp(output_string,"TKIP CCMP") == 0) {
developerc79e9172023-06-06 19:48:03 +08008694 len = strlen("TKIPandAESEncryption");
8695 memcpy(output_string,"TKIPandAESEncryption", len);
8696 output_string[len] = '\0';
8697 } else if(strcmp(output_string,"TKIP") == 0) {
8698 len = strlen("TKIPEncryption");
8699 memcpy(output_string,"TKIPEncryption", len);
8700 output_string[len] = '\0';
8701 } else if(strcmp(output_string,"CCMP") == 0) {
8702 len = strlen("AESEncryption");
8703 memcpy(output_string,"AESEncryption", len);
8704 output_string[len] = '\0';
8705 }
developer72fb0bb2023-01-11 09:46:29 +08008706
developera3511852023-06-14 14:12:59 +08008707 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8708 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008709}
8710
8711// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
8712INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
8713{
developera3511852023-06-14 14:12:59 +08008714 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8715 struct params params={'\0'};
8716 char output_string[32];
8717 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008718 int res;
developer72fb0bb2023-01-11 09:46:29 +08008719
developera3511852023-06-14 14:12:59 +08008720 memset(output_string,'\0',32);
8721 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08008722
developera3511852023-06-14 14:12:59 +08008723 if(strcmp(encMode, "TKIPEncryption") == 0)
8724 params.value = "TKIP";
8725 else if(strcmp(encMode,"AESEncryption") == 0)
8726 params.value = "CCMP";
8727 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
8728 params.value = "TKIP CCMP";
developer72fb0bb2023-01-11 09:46:29 +08008729
developera3511852023-06-14 14:12:59 +08008730 if((strcmp(output_string,"WPAand11i")==0))
8731 {
8732 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008733 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8734 if (os_snprintf_error(sizeof(config_file), res)) {
8735 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8736 return RETURN_ERR;
8737 }
developera3511852023-06-14 14:12:59 +08008738 wifi_hostapdWrite(config_file, &params, 1);
8739 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08008740
developera3511852023-06-14 14:12:59 +08008741 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008742 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8743 if (os_snprintf_error(sizeof(config_file), res)) {
8744 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8745 return RETURN_ERR;
8746 }
developera3511852023-06-14 14:12:59 +08008747 wifi_hostapdWrite(config_file, &params, 1);
8748 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08008749
developera3511852023-06-14 14:12:59 +08008750 return RETURN_OK;
8751 }
8752 else if((strcmp(output_string,"11i")==0))
8753 {
8754 params.name = "rsn_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008755 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8756 if (os_snprintf_error(sizeof(config_file), res)) {
8757 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8758 return RETURN_ERR;
8759 }
developera3511852023-06-14 14:12:59 +08008760 wifi_hostapdWrite(config_file, &params, 1);
8761 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8762 return RETURN_OK;
8763 }
8764 else if((strcmp(output_string,"WPA")==0))
8765 {
8766 params.name = "wpa_pairwise";
developer75bd10c2023-06-27 11:34:08 +08008767 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8768 if (os_snprintf_error(sizeof(config_file), res)) {
8769 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8770 return RETURN_ERR;
8771 }
developera3511852023-06-14 14:12:59 +08008772 wifi_hostapdWrite(config_file, &params, 1);
8773 wifi_hostapdProcessUpdate(apIndex, &params, 1);
8774 return RETURN_OK;
8775 }
developer72fb0bb2023-01-11 09:46:29 +08008776
developera3511852023-06-14 14:12:59 +08008777 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8778 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008779}
8780
8781// deletes internal security varable settings for this ap
8782INT wifi_removeApSecVaribles(INT apIndex)
8783{
developer0155a502023-06-19 20:33:57 +08008784 char config_file[MAX_BUF_SIZE] = {0};
8785 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008786 int res;
developer0155a502023-06-19 20:33:57 +08008787
8788 list.name = "wpa";
8789 list.value = "0";
8790
developer75bd10c2023-06-27 11:34:08 +08008791 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8792 if (os_snprintf_error(sizeof(config_file), res)) {
8793 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8794 return RETURN_ERR;
8795 }
developer0155a502023-06-19 20:33:57 +08008796 wifi_hostapdWrite(config_file, &list, 1);
8797
8798 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008799}
8800
8801// changes the hardware settings to disable encryption on this ap
8802INT wifi_disableApEncryption(INT apIndex)
8803{
developer0155a502023-06-19 20:33:57 +08008804 char config_file[MAX_BUF_SIZE] = {0};
8805 struct params list;
developer75bd10c2023-06-27 11:34:08 +08008806 int res;
developer0155a502023-06-19 20:33:57 +08008807
8808 list.name = "wpa";
8809 list.value = "0";
8810
developer75bd10c2023-06-27 11:34:08 +08008811 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8812 if (os_snprintf_error(sizeof(config_file), res)) {
8813 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8814 return RETURN_ERR;
8815 }
developer0155a502023-06-19 20:33:57 +08008816 wifi_hostapdWrite(config_file, &list, 1);
8817 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8818 wifi_reloadAp(apIndex);
8819
8820 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008821}
8822
8823// set the authorization mode on this ap
8824// mode mapping as: 1: open, 2: shared, 4:auto
8825INT wifi_setApAuthMode(INT apIndex, INT mode)
8826{
developera3511852023-06-14 14:12:59 +08008827 struct params params={0};
8828 char config_file[64] = {0};
developer75bd10c2023-06-27 11:34:08 +08008829 int res;
developer72fb0bb2023-01-11 09:46:29 +08008830
developera3511852023-06-14 14:12:59 +08008831 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008832
developera3511852023-06-14 14:12:59 +08008833 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
8834 params.name = "auth_algs";
developer72fb0bb2023-01-11 09:46:29 +08008835
developere5750452023-05-15 16:46:42 +08008836 if ((mode & 1 && mode & 2) || mode & 4)
developera3511852023-06-14 14:12:59 +08008837 params.value = "3";
8838 else if (mode & 2)
8839 params.value = "2";
8840 else if (mode & 1)
8841 params.value = "1";
8842 else
8843 params.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08008844
developer75bd10c2023-06-27 11:34:08 +08008845 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8846 if (os_snprintf_error(sizeof(config_file), res)) {
8847 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8848 return RETURN_ERR;
8849 }
developera3511852023-06-14 14:12:59 +08008850 wifi_hostapdWrite(config_file, &params, 1);
8851 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008852 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +08008853 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008854
developera3511852023-06-14 14:12:59 +08008855 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008856}
8857
8858// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
8859INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
8860{
developera3511852023-06-14 14:12:59 +08008861 //save to wifi config, and wait for wifi restart to apply
8862 struct params params={'\0'};
8863 char config_file[MAX_BUF_SIZE] = {0};
8864 int ret;
developer72fb0bb2023-01-11 09:46:29 +08008865
developera3511852023-06-14 14:12:59 +08008866 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8867 if(authMode == NULL)
8868 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008869
developera3511852023-06-14 14:12:59 +08008870 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
8871 params.name = "wpa_key_mgmt";
developer72fb0bb2023-01-11 09:46:29 +08008872
developera3511852023-06-14 14:12:59 +08008873 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
8874 params.value = "WPA-PSK";
8875 else if(strcmp(authMode,"EAPAuthentication") == 0)
8876 params.value = "WPA-EAP";
8877 else if (strcmp(authMode, "SAEAuthentication") == 0)
8878 params.value = "SAE";
8879 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
8880 params.value = "WPA-EAP-SUITE-B-192";
8881 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
8882 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
8883 else if (strcmp(authMode, "Enhanced_Open") == 0)
8884 params.value = "OWE";
8885 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
8886 return RETURN_OK; //This is taken careof in beaconType
developer72fb0bb2023-01-11 09:46:29 +08008887
developer32f2a182023-06-27 19:50:41 +08008888 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
8889 if (os_snprintf_error(sizeof(config_file), ret)) {
8890 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8891 return RETURN_ERR;
8892 }
developera3511852023-06-14 14:12:59 +08008893 ret=wifi_hostapdWrite(config_file,&params,1);
8894 if(!ret)
8895 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
8896 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008897
developera3511852023-06-14 14:12:59 +08008898 return ret;
developer72fb0bb2023-01-11 09:46:29 +08008899}
8900
8901// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
8902INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
8903{
developera3511852023-06-14 14:12:59 +08008904 //save to wifi config, and wait for wifi restart to apply
8905 char BeaconType[50] = {0};
8906 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +08008907 int res;
developer32f2a182023-06-27 19:50:41 +08008908 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +08008909
developera3511852023-06-14 14:12:59 +08008910 *authMode = 0;
8911 wifi_getApBeaconType(apIndex,BeaconType);
8912 printf("%s____%s \n",__FUNCTION__,BeaconType);
developer72fb0bb2023-01-11 09:46:29 +08008913
developer32f2a182023-06-27 19:50:41 +08008914 if(strcmp(BeaconType,"None") == 0) {
8915 memcpy(authMode, "None", 4);
8916 authMode[4] = '\0';
8917 } else {
8918 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
developer75bd10c2023-06-27 11:34:08 +08008919 if (os_snprintf_error(sizeof(config_file), res)) {
8920 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8921 return RETURN_ERR;
8922 }
developera3511852023-06-14 14:12:59 +08008923 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
8924 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
developer32f2a182023-06-27 19:50:41 +08008925 if(strcmp(authMode,"WPA-PSK") == 0) {
8926 len = strlen("SharedAuthentication");
8927 memcpy(authMode, "SharedAuthentication", len);
8928 authMode[len] = '\0';
8929 } else if(strcmp(authMode,"WPA-EAP") == 0) {
8930 len = strlen("EAPAuthentication");
8931 memcpy(authMode, "EAPAuthentication", len);
8932 authMode[len] = '\0';
8933 }
developera3511852023-06-14 14:12:59 +08008934 }
developer72fb0bb2023-01-11 09:46:29 +08008935
developera3511852023-06-14 14:12:59 +08008936 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008937}
8938
8939// Outputs the number of stations associated per AP
8940INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
8941{
developera3511852023-06-14 14:12:59 +08008942 char interface_name[16] = {0};
8943 char cmd[128]={0};
8944 char buf[128]={0};
8945 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +08008946 int res;
developer72fb0bb2023-01-11 09:46:29 +08008947
developera3511852023-06-14 14:12:59 +08008948 if(apIndex > MAX_APS)
8949 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008950
developera3511852023-06-14 14:12:59 +08008951 wifi_getApEnable(apIndex,&status);
8952 if (!status)
8953 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008954
developera3511852023-06-14 14:12:59 +08008955 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
8956 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8957 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +08008958 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta | wc -l", interface_name);
8959 if (os_snprintf_error(sizeof(cmd), res)) {
8960 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8961 return RETURN_ERR;
8962 }
developera3511852023-06-14 14:12:59 +08008963 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +08008964 if (sscanf(buf,"%lu", output_ulong) != 1) {
8965 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
8966 return RETURN_ERR;
8967 }
developer72fb0bb2023-01-11 09:46:29 +08008968
developera3511852023-06-14 14:12:59 +08008969 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008970}
8971
8972// manually removes any active wi-fi association with the device specified on this ap
8973INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
8974{
developera3511852023-06-14 14:12:59 +08008975 char inf_name[16] = {0};
8976 char cmd[MAX_CMD_SIZE] = {0};
8977 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08008978 int res;
developer72fb0bb2023-01-11 09:46:29 +08008979
developera3511852023-06-14 14:12:59 +08008980 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8981 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008982
8983 res = snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
8984 if (os_snprintf_error(sizeof(cmd), res)) {
8985 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8986 return RETURN_ERR;
8987 }
developer7e4a2a62023-04-06 19:56:03 +08008988
developera3511852023-06-14 14:12:59 +08008989 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008990
developera3511852023-06-14 14:12:59 +08008991 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008992}
8993
8994// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
8995INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
8996{
developer7e4a2a62023-04-06 19:56:03 +08008997 int max_radio_num = 0;
8998
8999 if(NULL == output_int)
9000 return RETURN_ERR;
9001
9002 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +08009003 if(max_radio_num == 0){
9004 return RETURN_ERR;
9005 }
developer7e4a2a62023-04-06 19:56:03 +08009006 *output_int = apIndex % max_radio_num;
9007
9008 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009009}
9010
9011// sets the radio index for the specific ap
9012INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
9013{
developera3511852023-06-14 14:12:59 +08009014 //set to config only and wait for wifi reset to apply settings
9015 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009016}
9017
developer0155a502023-06-19 20:33:57 +08009018int mtk_get_ap_metrics(struct nl_msg *msg, void *cb)
9019{
9020 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9021 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX + 1];
9022 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9023 wdev_ap_metric ap_metric;
9024 wdev_ap_metric *p_ap_metric = &ap_metric;
9025 int err = 0;
9026 struct mtk_nl80211_cb_data *cb_data = cb;
9027
9028 if (!msg || !cb_data) {
9029 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
9030 return NL_SKIP;
9031 }
9032
9033 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9034 genlmsg_attrlen(gnlh, 0), NULL);
9035 if (err < 0) {
9036 wifi_debug(DEBUG_ERROR, "nla_parse ap_metrics nl80211 msg fails,error.\n");
9037 return err;
9038 }
9039
9040 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9041 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX,
9042 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9043 if (err < 0) {
9044 wifi_debug(DEBUG_ERROR, "GET_STATISTIC_MAX fails,error.\n");
9045 return err;
9046 }
9047
9048 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]) {
9049 p_ap_metric = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]);
9050 if (p_ap_metric) {
9051 memcpy(cb_data->out_buf , &p_ap_metric->cu, sizeof(unsigned char));
9052 }
9053 }
9054 }
9055
9056 return NL_OK;
9057}
9058
developer121a8e72023-05-22 09:19:39 +08009059
9060#define MAX_ACL_DUMP_LEN 4096
9061int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
9062{
9063 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9064 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
9065 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9066 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08009067 int err = 0;
developer121a8e72023-05-22 09:19:39 +08009068 unsigned short acl_result_len = 0;
9069 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08009070 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08009071 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08009072 return NL_SKIP;
9073 }
developer121a8e72023-05-22 09:19:39 +08009074 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9075 genlmsg_attrlen(gnlh, 0), NULL);
9076 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08009077 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08009078 return NL_SKIP;
9079 }
developer121a8e72023-05-22 09:19:39 +08009080 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9081 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
9082 tb[NL80211_ATTR_VENDOR_DATA], NULL);
9083 if (err < 0)
9084 return NL_SKIP;
9085 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
9086 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
9087 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
9088 if (acl_result_len > MAX_ACL_DUMP_LEN) {
9089 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
9090 return NL_SKIP;
9091 } else if (*(show_str + acl_result_len - 1) != '\0') {
9092 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
9093 *(show_str + acl_result_len - 1) = '\0';
9094 }
9095 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08009096
9097 if (cb_data->out_len >= acl_result_len) {
9098 memset(cb_data->out_buf, 0, cb_data->out_len);
9099 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
9100 memmove(cb_data->out_buf, show_str, acl_result_len);
9101 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
9102 } else {
9103 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08009104 }
developer121a8e72023-05-22 09:19:39 +08009105 } else
9106 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
9107 } else
9108 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
9109 return NL_OK;
9110}
developer72fb0bb2023-01-11 09:46:29 +08009111// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08009112INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08009113{
developer7e4a2a62023-04-06 19:56:03 +08009114 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08009115 unsigned int if_idx = 0;
9116 int ret = -1;
9117 struct unl unl_ins;
9118 struct nl_msg *msg = NULL;
9119 struct nlattr * msg_data = NULL;
9120 struct mtk_nl80211_param param;
9121 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08009122 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9123 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08009124 if_idx = if_nametoindex(inf_name);
9125 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08009126 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08009127 return RETURN_ERR;
9128 }
9129 /*init mtk nl80211 vendor cmd*/
9130 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9131 param.if_type = NL80211_ATTR_IFINDEX;
9132 param.if_idx = if_idx;
9133
9134 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9135 if (ret) {
9136 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9137 return RETURN_ERR;
9138 }
developer121a8e72023-05-22 09:19:39 +08009139 /*add mtk vendor cmd data*/
9140 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08009141 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08009142 nlmsg_free(msg);
9143 goto err;
9144 }
developer72fb0bb2023-01-11 09:46:29 +08009145
developer121a8e72023-05-22 09:19:39 +08009146 /*send mtk nl80211 vendor msg*/
9147 cb_data.out_buf = macArray;
9148 cb_data.out_len = buf_size;
9149
9150 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
9151 if (ret) {
9152 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9153 goto err;
9154 }
9155 /*deinit mtk nl80211 vendor msg*/
9156 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08009157 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developera3511852023-06-14 14:12:59 +08009158 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08009159err:
9160 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08009161 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08009162 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009163}
9164
developer2edaf012023-05-24 14:24:53 +08009165INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
9166{
9167 char *mac_arry_buf = NULL;
9168
9169 mac_arry_buf = malloc(buf_size);
9170 if (!mac_arry_buf) {
9171 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
9172 return RETURN_ERR;
9173 }
9174 memset(mac_arry_buf, 0, buf_size);
9175 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
9176 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
9177 free(mac_arry_buf);
9178 mac_arry_buf = NULL;
9179 return RETURN_ERR;
9180 }
9181 /*
9182 mtk format to wifi hal format:
9183 "policy=1
9184 00:11:22:33:44:55
9185 00:11:22:33:44:66
9186 "
9187 -->
9188 "00:11:22:33:44:55
9189 00:11:22:33:44:66
9190 "
9191 */
9192 memset(macArray, 0, buf_size);
9193 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
9194 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
9195 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
9196 }
9197 free(mac_arry_buf);
9198 mac_arry_buf = NULL;
9199 return RETURN_OK;
9200}
9201
developer72fb0bb2023-01-11 09:46:29 +08009202INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
9203{
developer72fb0bb2023-01-11 09:46:29 +08009204
developer7e4a2a62023-04-06 19:56:03 +08009205 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08009206
developera3511852023-06-14 14:12:59 +08009207 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009208}
9209
9210
9211// Get the list of stations associated per AP
9212INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
9213{
developer7e4a2a62023-04-06 19:56:03 +08009214 char interface_name[IF_NAME_SIZE] = {0};
9215 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08009216 int res;
developer72fb0bb2023-01-11 09:46:29 +08009217
developer7e4a2a62023-04-06 19:56:03 +08009218 if(apIndex > 3) //Currently supporting apIndex upto 3
developera3511852023-06-14 14:12:59 +08009219 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009220
developer7e4a2a62023-04-06 19:56:03 +08009221 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08009222 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08009223
developere40952c2023-06-15 18:46:43 +08009224 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
9225 if (os_snprintf_error(sizeof(cmd), res)) {
9226 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9227 return RETURN_ERR;
9228 }
developer7e4a2a62023-04-06 19:56:03 +08009229 _syscmd(cmd, macArray, buf_size);
9230 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009231}
9232
developer8dd72532023-05-17 19:58:35 +08009233int hex2num(char c)
9234{
9235 if (c >= '0' && c <= '9')
9236 return c - '0';
9237 if (c >= 'a' && c <= 'f')
9238 return c - 'a' + 10;
9239 if (c >= 'A' && c <= 'F')
9240 return c - 'A' + 10;
9241 return -1;
9242}
9243
9244/**
9245 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
9246 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
9247 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
9248 * Returns: Characters used (> 0) on success, -1 on failure
9249 */
9250int hwaddr_aton2(const char *txt, unsigned char *addr)
9251{
9252 int i;
9253 const char *pos = txt;
9254
9255 for (i = 0; i < 6; i++) {
9256 int a, b;
9257
9258 while (*pos == ':' || *pos == '.' || *pos == '-')
9259 pos++;
9260
9261 a = hex2num(*pos++);
9262 if (a < 0)
9263 return -1;
9264 b = hex2num(*pos++);
9265 if (b < 0)
9266 return -1;
9267 *addr++ = (a << 4) | b;
9268 }
9269
9270 return pos - txt;
9271}
9272
developer72fb0bb2023-01-11 09:46:29 +08009273// adds the mac address to the filter list
9274//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
9275INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
9276{
developer7e4a2a62023-04-06 19:56:03 +08009277 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08009278 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08009279 struct nl_msg *msg = NULL;
9280 struct nlattr * msg_data = NULL;
9281 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08009282 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
9283 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08009284 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9285 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08009286 if (!DeviceMacAddress)
9287 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08009288 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08009289 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08009290 return RETURN_ERR;
9291 }
developer8dd72532023-05-17 19:58:35 +08009292 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08009293 if (!if_idx) {
9294 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9295 return RETURN_ERR;
9296 }
developer49b17232023-05-19 16:35:19 +08009297 /*init mtk nl80211 vendor cmd*/
9298 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9299 param.if_type = NL80211_ATTR_IFINDEX;
9300 param.if_idx = if_idx;
9301 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9302 if (ret) {
9303 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08009304 return RETURN_ERR;
9305 }
developer49b17232023-05-19 16:35:19 +08009306 /*add mtk vendor cmd data*/
9307 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08009308 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08009309 nlmsg_free(msg);
9310 goto err;
9311 }
developer49b17232023-05-19 16:35:19 +08009312 /*send mtk nl80211 vendor msg*/
9313 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9314 if (ret) {
9315 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08009316 goto err;
9317 }
developer49b17232023-05-19 16:35:19 +08009318 /*deinit mtk nl80211 vendor msg*/
9319 mtk_nl80211_deint(&unl_ins);
9320 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08009321 return RETURN_OK;
9322err:
developer49b17232023-05-19 16:35:19 +08009323 mtk_nl80211_deint(&unl_ins);
9324 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08009325 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009326}
9327
9328// deletes the mac address from the filter list
9329//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
9330INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
9331{
developer2edaf012023-05-24 14:24:53 +08009332 struct unl unl_ins;
9333 int if_idx = 0, ret = 0;
9334 struct nl_msg *msg = NULL;
9335 struct nlattr * msg_data = NULL;
9336 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08009337 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08009338 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009339
developer7e4a2a62023-04-06 19:56:03 +08009340 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9341 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009342
developer7e4a2a62023-04-06 19:56:03 +08009343 if (!DeviceMacAddress)
9344 return RETURN_ERR;
9345
developer2edaf012023-05-24 14:24:53 +08009346 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
9347 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
9348 return RETURN_ERR;
9349 }
developer72fb0bb2023-01-11 09:46:29 +08009350
developer2edaf012023-05-24 14:24:53 +08009351 if_idx = if_nametoindex(inf_name);
9352 if (!if_idx) {
9353 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9354 return RETURN_ERR;
9355 }
9356 /*init mtk nl80211 vendor cmd*/
9357 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9358 param.if_type = NL80211_ATTR_IFINDEX;
9359 param.if_idx = if_idx;
9360 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9361 if (ret) {
9362 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9363 return RETURN_ERR;
9364 }
9365 /*add mtk vendor cmd data*/
9366 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
9367 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9368 nlmsg_free(msg);
9369 goto err;
9370 }
9371 /*send mtk nl80211 vendor msg*/
9372 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9373 if (ret) {
9374 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9375 goto err;
9376 }
9377 /*deinit mtk nl80211 vendor msg*/
9378 mtk_nl80211_deint(&unl_ins);
9379 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
9380 return RETURN_OK;
9381err:
9382 mtk_nl80211_deint(&unl_ins);
9383 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9384 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009385}
9386
9387// outputs the number of devices in the filter list
9388INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
9389{
developer2edaf012023-05-24 14:24:53 +08009390 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
9391 UINT buf_size = 1024;
9392 UINT sta_num = 0;
9393 unsigned char mac[ETH_ALEN] = {0};
developera3511852023-06-14 14:12:59 +08009394 if(output_uint == NULL)
developerdaf24792023-06-06 11:40:04 +08009395 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009396
developer2edaf012023-05-24 14:24:53 +08009397 mac_arry = (char *)malloc(buf_size);
9398 if (mac_arry == NULL) {
9399 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08009400 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08009401 }
developerdaf24792023-06-06 11:40:04 +08009402 memset(mac_arry, 0, buf_size);
developer2edaf012023-05-24 14:24:53 +08009403 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
9404 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
9405 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
developer9ce44382023-06-28 11:09:37 +08009406 free(mac_arry);
developer2edaf012023-05-24 14:24:53 +08009407 return RETURN_ERR;
9408 }
9409 /*count the acl str nums:*/
9410 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08009411
developer2edaf012023-05-24 14:24:53 +08009412 /*mac addr string format:
9413 exp1: 00:11:22:33:44:55\0
9414 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
9415 */
9416 ptr = mac_arry;
9417 while (sscanf(ptr, "%17s", mac_str) == 1) {
9418 if (hwaddr_aton2(mac_str, mac) >= 0)
9419 sta_num++;
9420 ptr = strstr(ptr, mac_str) + strlen(mac_str);
9421 }
9422 *output_uint = sta_num;
9423 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
9424 free(mac_arry);
9425 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08009426 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009427}
9428
9429INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
9430{
developera3511852023-06-14 14:12:59 +08009431 char buf[128]={'\0'};
developer75bd10c2023-06-27 11:34:08 +08009432 int res;
developer72fb0bb2023-01-11 09:46:29 +08009433
developera3511852023-06-14 14:12:59 +08009434 if(strcmp(action,"DENY")==0)
9435 {
developer32f2a182023-06-27 19:50:41 +08009436 res = snprintf(buf, sizeof(buf),
9437 "iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",
9438 apIndex, interface, client_mac);
developer75bd10c2023-06-27 11:34:08 +08009439 if (os_snprintf_error(sizeof(buf), res)) {
9440 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9441 return RETURN_ERR;
9442 }
developera3511852023-06-14 14:12:59 +08009443 system(buf);
9444 return RETURN_OK;
9445 }
developer72fb0bb2023-01-11 09:46:29 +08009446
developera3511852023-06-14 14:12:59 +08009447 if(strcmp(action,"ALLOW")==0)
9448 {
developer32f2a182023-06-27 19:50:41 +08009449 res = snprintf(buf, sizeof(buf),
9450 "iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",
9451 apIndex, interface, client_mac);
developer75bd10c2023-06-27 11:34:08 +08009452 if (os_snprintf_error(sizeof(buf), res)) {
9453 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9454 return RETURN_ERR;
9455 }
developera3511852023-06-14 14:12:59 +08009456 system(buf);
9457 return RETURN_OK;
9458 }
developer72fb0bb2023-01-11 09:46:29 +08009459
developera3511852023-06-14 14:12:59 +08009460 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009461
9462}
9463
9464// enable kick for devices on acl black list
9465INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
9466{
developera3511852023-06-14 14:12:59 +08009467 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
9468 char assocArray[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009469
developera3511852023-06-14 14:12:59 +08009470 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
9471 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
developer72fb0bb2023-01-11 09:46:29 +08009472
developera3511852023-06-14 14:12:59 +08009473 /* if there are no devices connected there is nothing to do */
9474 if (strlen(assocArray) < 17)
9475 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009476
developera3511852023-06-14 14:12:59 +08009477 if (enable == TRUE) {
9478 /* kick off the MAC which is in ACL array (deny list) */
9479 acl = strtok(aclArray, "\n");
9480 while (acl != NULL) {
9481 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
9482 wifi_kickApAssociatedDevice(apIndex, acl);
developer72fb0bb2023-01-11 09:46:29 +08009483
developera3511852023-06-14 14:12:59 +08009484 acl = strtok(NULL, "\n");
9485 }
developer72fb0bb2023-01-11 09:46:29 +08009486 wifi_setApMacAddressControlMode(apIndex, 2);
developera3511852023-06-14 14:12:59 +08009487 } else
developer72fb0bb2023-01-11 09:46:29 +08009488 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08009489
developera3511852023-06-14 14:12:59 +08009490 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009491}
9492
9493INT wifi_setPreferPrivateConnection(BOOL enable)
9494{
developera3511852023-06-14 14:12:59 +08009495 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009496}
9497
9498// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
9499INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
9500{
developer2edaf012023-05-24 14:24:53 +08009501 int if_idx = 0, ret = 0;
9502 struct unl unl_ins;
9503 struct nl_msg *msg = NULL;
9504 struct nlattr * msg_data = NULL;
9505 struct mtk_nl80211_param param;
9506 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08009507 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009508
developer7e4a2a62023-04-06 19:56:03 +08009509 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
9510 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08009511 if_idx = if_nametoindex(inf_name);
9512 if (!if_idx) {
9513 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
9514 return RETURN_ERR;
9515 }
9516 /*init mtk nl80211 vendor cmd*/
9517 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
9518 param.if_type = NL80211_ATTR_IFINDEX;
9519 param.if_idx = if_idx;
9520 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9521 if (ret) {
9522 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9523 return RETURN_ERR;
9524 }
9525 /*add mtk vendor cmd data*/
9526 if (filterMode == 0) {
9527 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
9528 } else if (filterMode == 1) {
9529 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
9530 } else if (filterMode == 2) {
9531 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
9532 } else {
9533 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
9534 nlmsg_free(msg);
9535 goto err;
9536 }
9537 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
9538 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
9539 nlmsg_free(msg);
9540 goto err;
9541 }
9542 /*send mtk nl80211 vendor msg*/
9543 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9544 if (ret) {
9545 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
9546 goto err;
9547 }
9548 /*deinit mtk nl80211 vendor msg*/
9549 mtk_nl80211_deint(&unl_ins);
9550 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08009551 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08009552err:
9553 mtk_nl80211_deint(&unl_ins);
9554 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9555 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009556}
9557
9558// 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.
9559INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
9560{
developera3511852023-06-14 14:12:59 +08009561 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009562}
9563
9564// gets the vlan ID for this ap from an internal enviornment variable
9565INT wifi_getApVlanID(INT apIndex, INT *output_int)
9566{
developera3511852023-06-14 14:12:59 +08009567 if(apIndex==0)
9568 {
9569 *output_int=100;
9570 return RETURN_OK;
9571 }
developer72fb0bb2023-01-11 09:46:29 +08009572
developera3511852023-06-14 14:12:59 +08009573 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009574}
9575
9576// sets the vlan ID for this ap to an internal enviornment variable
9577INT wifi_setApVlanID(INT apIndex, INT vlanId)
9578{
developera3511852023-06-14 14:12:59 +08009579 //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 +08009580 char interface_name[16] = {0};
9581 int if_idx, ret = 0;
9582 struct nl_msg *msg = NULL;
9583 struct nlattr * msg_data = NULL;
9584 struct mtk_nl80211_param param;
9585 struct unl unl_ins;
9586
9587 if (apIndex > MAX_APS) {
9588 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9589 return RETURN_ERR;
9590 }
9591 if (vlanId > 4095 || vlanId < 1) {
9592 wifi_debug(DEBUG_ERROR, "Invalid vlanId %d\n", vlanId);
9593 return RETURN_ERR;
9594 }
9595 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9596 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9597 return RETURN_ERR;
9598 /*step 1. mwctl dev %s set vlan_tag 0*/
9599 if_idx = if_nametoindex(interface_name);
9600 /*init mtk nl80211 vendor cmd*/
9601 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
9602 param.if_type = NL80211_ATTR_IFINDEX;
9603 param.if_idx = if_idx;
9604 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9605 if (ret) {
9606 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9607 return RETURN_ERR;
9608 }
9609 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, vlanId)) {
9610 printf("Nla put attribute error\n");
9611 nlmsg_free(msg);
9612 goto err;
9613 }
9614 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9615 if (ret) {
9616 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9617 goto err;
9618 }
9619 mtk_nl80211_deint(&unl_ins);
9620 //wifi_debug(DEBUG_NOTICE, "set vlanId cmd success.\n", vlanId);
9621 printf("set vlanId=%d cmd success.\n", vlanId);
9622 return RETURN_OK;
9623err:
9624 mtk_nl80211_deint(&unl_ins);
9625 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developera3511852023-06-14 14:12:59 +08009626 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009627}
9628
developercc5cbfb2023-06-13 18:29:52 +08009629char br_name[IFNAMSIZ] = "brlan0";
9630
developer72fb0bb2023-01-11 09:46:29 +08009631// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
9632INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
9633{
developercc5cbfb2023-06-13 18:29:52 +08009634 int sock = socket(AF_INET, SOCK_DGRAM, 0);
9635 struct ifreq ifr;
9636 struct sockaddr_in *sin;
9637
9638 memcpy(bridgeName, br_name, strlen(br_name));
9639
9640 if (sock == -1) {
9641 wifi_debug(DEBUG_ERROR, "socket failed");
9642 return RETURN_ERR;
9643 }
9644
developerd14dff12023-06-28 22:47:44 +08009645 strncpy(ifr.ifr_name, br_name, strlen(br_name));
developercc5cbfb2023-06-13 18:29:52 +08009646 ifr.ifr_addr.sa_family = AF_INET;
9647 if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
9648 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFADDR) failed, %s, bridge_name=%s\n",
9649 strerror(errno), br_name);
developer9ce44382023-06-28 11:09:37 +08009650 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009651 return RETURN_ERR;
9652 }
9653
9654 sin = (struct sockaddr_in *)&ifr.ifr_addr;
9655 wifi_debug(DEBUG_ERROR, "Bridge device %s has IP address: %s\n", br_name, inet_ntoa(sin->sin_addr));
9656 memcpy(IP, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
9657
9658 if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0) {
9659 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFNETMASK) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009660 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009661 return RETURN_ERR;
9662 }
9663
9664 wifi_debug(DEBUG_ERROR, "Bridge device %s has subnet mask: %s\n", br_name, inet_ntoa(sin->sin_addr));
9665 memcpy(subnet, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
9666 close(sock);
developer72fb0bb2023-01-11 09:46:29 +08009667
developera3511852023-06-14 14:12:59 +08009668 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009669}
9670
9671//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
9672INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
9673{
developera3511852023-06-14 14:12:59 +08009674 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
developercc5cbfb2023-06-13 18:29:52 +08009675 struct ifreq ifr;
9676 struct sockaddr_in sin;
9677 int sock = socket(AF_INET, SOCK_DGRAM, 0);
9678
9679 if (strlen(bridgeName) >= IFNAMSIZ) {
9680 wifi_debug(DEBUG_ERROR, "invalide bridgeName length=%ld\n", strlen(bridgeName));
developer9ce44382023-06-28 11:09:37 +08009681 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009682 return RETURN_ERR;
9683 }
9684
9685 if (strlen(br_name) >= IFNAMSIZ) {
9686 wifi_debug(DEBUG_ERROR, "invalide br_name length=%ld in strorage\n", strlen(br_name));
developer9ce44382023-06-28 11:09:37 +08009687 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009688 return RETURN_ERR;
9689 }
9690
9691 if (sock == -1) {
developera3511852023-06-14 14:12:59 +08009692 wifi_debug(DEBUG_ERROR, "socket failed");
developercc5cbfb2023-06-13 18:29:52 +08009693 return RETURN_ERR;
9694 }
9695
9696 memset(&ifr, 0, sizeof(ifr));
9697 strncpy(ifr.ifr_name, br_name, strlen(br_name));
9698 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
9699 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009700 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009701 return RETURN_ERR;
9702 }
9703
9704 ifr.ifr_flags = (short)(ifr.ifr_flags & ~IFF_UP);
9705 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
9706 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009707 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009708 return RETURN_ERR;
9709 }
9710
9711 memset(&ifr, 0, sizeof(ifr));
9712 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
developerd14dff12023-06-28 22:47:44 +08009713 strncpy(ifr.ifr_newname, bridgeName, strlen(bridgeName));
developercc5cbfb2023-06-13 18:29:52 +08009714 if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
9715 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNAME) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009716 close(sock);
developera3511852023-06-14 14:12:59 +08009717 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009718 }
9719
9720 memset(br_name, 0, sizeof(br_name));
9721 memcpy(br_name, bridgeName, strlen(bridgeName));
9722
9723 memset(&ifr, 0, sizeof(ifr));
9724 strncpy(ifr.ifr_name, bridgeName, IFNAMSIZ);
9725 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
9726 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009727 close(sock);
developera3511852023-06-14 14:12:59 +08009728 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009729 }
9730 ifr.ifr_flags = (short)(ifr.ifr_flags | IFF_UP);
9731 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
9732 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009733 close(sock);
developera3511852023-06-14 14:12:59 +08009734 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08009735 }
9736
9737 memset(&ifr, 0, sizeof(ifr));
9738 memcpy(ifr.ifr_name, bridgeName, strlen(bridgeName));
9739
9740 memset(&sin, 0, sizeof(struct sockaddr_in));
9741 sin.sin_family = AF_INET;
9742 if (inet_aton(IP, &(sin.sin_addr)) == 0) {
9743 wifi_debug(DEBUG_ERROR, "inet_aton failed");
developer9ce44382023-06-28 11:09:37 +08009744 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009745 return RETURN_ERR;
9746 }
9747 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in));
9748 if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
9749 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFADDR) failed, %s", strerror(errno));
developer9ce44382023-06-28 11:09:37 +08009750 close(sock);
developercc5cbfb2023-06-13 18:29:52 +08009751 return RETURN_ERR;
9752 }
9753
9754 if (inet_aton(subnet, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr) == 0) {
9755 wifi_debug(DEBUG_ERROR, "inet_aton failed");
9756 return RETURN_ERR;
9757 }
9758 if (ioctl(sock, SIOCSIFNETMASK, &ifr) < -1) {
9759 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNETMASK) failed, %s", strerror(errno));
9760 return RETURN_ERR;
9761 }
9762
9763 close(sock);
developera3511852023-06-14 14:12:59 +08009764 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009765}
9766
9767// reset the vlan configuration for this ap
9768INT wifi_resetApVlanCfg(INT apIndex)
9769{
developera1255e42023-05-13 17:45:02 +08009770 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08009771 int if_idx, ret = 0;
9772 struct nl_msg *msg = NULL;
9773 struct nlattr * msg_data = NULL;
9774 struct mtk_nl80211_param param;
9775 struct unl unl_ins;
9776 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08009777
developer2202b332023-05-24 16:23:22 +08009778 if (apIndex > MAX_APS) {
9779 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
9780 return RETURN_ERR;
9781 }
developer72fb0bb2023-01-11 09:46:29 +08009782
developer2202b332023-05-24 16:23:22 +08009783 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9784 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9785 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009786
developer2202b332023-05-24 16:23:22 +08009787 /*step 1. mwctl dev %s set vlan_tag 0*/
9788 if_idx = if_nametoindex(interface_name);
9789 /*init mtk nl80211 vendor cmd*/
9790 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
9791 param.if_type = NL80211_ATTR_IFINDEX;
9792 param.if_idx = if_idx;
9793 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08009794
developer2202b332023-05-24 16:23:22 +08009795 if (ret) {
9796 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9797 return RETURN_ERR;
9798 }
developer72fb0bb2023-01-11 09:46:29 +08009799
developer2202b332023-05-24 16:23:22 +08009800 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
9801 printf("Nla put attribute error\n");
9802 nlmsg_free(msg);
9803 goto err;
9804 }
developer72fb0bb2023-01-11 09:46:29 +08009805
developer2202b332023-05-24 16:23:22 +08009806 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9807 if (ret) {
9808 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9809 goto err;
9810 }
9811 mtk_nl80211_deint(&unl_ins);
9812 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08009813
developer2202b332023-05-24 16:23:22 +08009814 /*step 2. mwctl dev %s set vlan_priority 0*/
9815 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9816 if (ret) {
9817 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9818 return RETURN_ERR;
9819 }
developer72fb0bb2023-01-11 09:46:29 +08009820
developer2202b332023-05-24 16:23:22 +08009821 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
9822 printf("Nla put attribute error\n");
9823 nlmsg_free(msg);
9824 goto err;
9825 }
developer72fb0bb2023-01-11 09:46:29 +08009826
developer2202b332023-05-24 16:23:22 +08009827 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9828 if (ret) {
9829 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9830 goto err;
9831 }
9832 mtk_nl80211_deint(&unl_ins);
9833 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
9834
9835 /*step 3. mwctl dev %s set vlan_id 0*/
9836 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9837 if (ret) {
9838 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08009839 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08009840 }
developer72fb0bb2023-01-11 09:46:29 +08009841
developer2202b332023-05-24 16:23:22 +08009842 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
9843 printf("Nla put attribute error\n");
9844 nlmsg_free(msg);
9845 goto err;
9846 }
9847
9848 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9849 if (ret) {
9850 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9851 goto err;
9852 }
9853 mtk_nl80211_deint(&unl_ins);
9854 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
9855
9856 /*step 4. mwctl dev %s set vlan_en 0*/
9857 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9858 if (ret) {
9859 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9860 return RETURN_ERR;
9861 }
9862
9863 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
9864 printf("Nla put attribute error\n");
9865 nlmsg_free(msg);
9866 goto err;
9867 }
9868
9869 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9870 if (ret) {
9871 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9872 goto err;
9873 }
9874 mtk_nl80211_deint(&unl_ins);
9875 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
9876
9877 /*step 5. mwctl dev %s set vlan_policy 0:4*/
9878 vlan_param.direction = 0;
9879 vlan_param.policy = 4;
9880 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9881 if (ret) {
9882 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9883 return RETURN_ERR;
9884 }
9885 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
9886 printf("Nla put attribute error\n");
9887 nlmsg_free(msg);
9888 goto err;
9889 }
9890
9891 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9892 if (ret) {
9893 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9894 goto err;
9895 }
9896 mtk_nl80211_deint(&unl_ins);
9897 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
9898
9899 /*step 6. mwctl dev %s set vlan_policy 1:0*/
9900 vlan_param.direction = 1;
9901 vlan_param.policy = 0;
9902 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
9903 if (ret) {
9904 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
9905 return RETURN_ERR;
9906 }
9907
9908 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
9909 printf("Nla put attribute error\n");
9910 nlmsg_free(msg);
9911 goto err;
9912 }
9913
9914 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
9915 if (ret) {
9916 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
9917 goto err;
9918 }
9919 /*deinit mtk nl80211 vendor msg*/
9920 mtk_nl80211_deint(&unl_ins);
9921 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
9922
9923 /*TODO need to modify VLAN config in dat file*/
9924 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9925
9926 return RETURN_OK;
9927err:
9928 mtk_nl80211_deint(&unl_ins);
9929 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
9930 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009931}
9932
9933// 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.
9934INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
9935{
developera3511852023-06-14 14:12:59 +08009936 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009937}
9938
9939// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
9940INT wifi_startHostApd()
9941{
developera3511852023-06-14 14:12:59 +08009942 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9943 system("systemctl start hostapd.service");
9944 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9945 return RETURN_OK;
9946 //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 +08009947}
9948
9949// stops hostapd
developer69b61b02023-03-07 17:17:44 +08009950INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08009951{
developera3511852023-06-14 14:12:59 +08009952 char cmd[128] = {0};
9953 char buf[128] = {0};
developer75bd10c2023-06-27 11:34:08 +08009954 int res;
developer72fb0bb2023-01-11 09:46:29 +08009955
developer75bd10c2023-06-27 11:34:08 +08009956 res = snprintf(cmd, sizeof(cmd), "systemctl stop hostapd");
9957 if (os_snprintf_error(sizeof(cmd), res)) {
9958 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9959 return RETURN_ERR;
9960 }
developera3511852023-06-14 14:12:59 +08009961 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009962
developera3511852023-06-14 14:12:59 +08009963 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009964}
9965
9966// restart hostapd dummy function
9967INT wifi_restartHostApd()
9968{
developera3511852023-06-14 14:12:59 +08009969 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9970 system("systemctl restart hostapd-global");
9971 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009972
developera3511852023-06-14 14:12:59 +08009973 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009974}
9975
9976// sets the AP enable status variable for the specified ap.
9977INT wifi_setApEnable(INT apIndex, BOOL enable)
9978{
developer7e4a2a62023-04-06 19:56:03 +08009979 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +08009980 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +08009981 char cmd[MAX_CMD_SIZE] = {0};
9982 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08009983 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08009984 int max_radio_num = 0;
9985 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08009986 int res;
developer72fb0bb2023-01-11 09:46:29 +08009987
developer7e4a2a62023-04-06 19:56:03 +08009988 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08009989
developer7e4a2a62023-04-06 19:56:03 +08009990 wifi_getMaxRadioNumber(&max_radio_num);
9991 if (enable == status)
9992 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009993
developer7e4a2a62023-04-06 19:56:03 +08009994 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9995 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009996
developer7e4a2a62023-04-06 19:56:03 +08009997 if (enable == TRUE) {
9998 int radioIndex = apIndex % max_radio_num;
9999 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +080010000 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
10001 if (os_snprintf_error(sizeof(cmd), res)) {
10002 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10003 return RETURN_ERR;
10004 }
developerf3c7d292023-05-29 17:57:16 +080010005 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +080010006
developere40952c2023-06-15 18:46:43 +080010007 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
10008 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
10009 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10010 return RETURN_ERR;
10011 }
10012 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
10013 if (os_snprintf_error(sizeof(cmd), res)) {
10014 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10015 return RETURN_ERR;
10016 }
developer7e4a2a62023-04-06 19:56:03 +080010017 _syscmd(cmd, buf, sizeof(buf));
10018 } else {
developere40952c2023-06-15 18:46:43 +080010019 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
10020 if (os_snprintf_error(sizeof(cmd), res)) {
10021 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10022 return RETURN_ERR;
10023 }
developer7e4a2a62023-04-06 19:56:03 +080010024 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +080010025 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
10026 if (os_snprintf_error(sizeof(cmd), res)) {
10027 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10028 return RETURN_ERR;
10029 }
developerf3c7d292023-05-29 17:57:16 +080010030 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +080010031 }
developere40952c2023-06-15 18:46:43 +080010032 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer7e4a2a62023-04-06 19:56:03 +080010033 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +080010034 if (os_snprintf_error(sizeof(cmd), res)) {
10035 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10036 return RETURN_ERR;
10037 }
developer7e4a2a62023-04-06 19:56:03 +080010038 _syscmd(cmd, buf, sizeof(buf));
10039 //Wait for wifi up/down to apply
10040 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010041}
10042
10043// Outputs the setting of the internal variable that is set by wifi_setApEnable().
10044INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
10045{
developer7e4a2a62023-04-06 19:56:03 +080010046 char interface_name[IF_NAME_SIZE] = {0};
10047 char cmd[MAX_CMD_SIZE] = {0};
developerc1aa6532023-06-09 09:37:01 +080010048 char buf[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080010049 int res;
developer72fb0bb2023-01-11 09:46:29 +080010050
developer7e4a2a62023-04-06 19:56:03 +080010051 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
10052 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010053
developer7e4a2a62023-04-06 19:56:03 +080010054 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +080010055
developer7e4a2a62023-04-06 19:56:03 +080010056 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
10057 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
10058 *output_bool = FALSE;
10059 return RETURN_OK;
10060 }
developerc1aa6532023-06-09 09:37:01 +080010061
developer75bd10c2023-06-27 11:34:08 +080010062 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
10063 if (os_snprintf_error(sizeof(cmd), res)) {
10064 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10065 return RETURN_ERR;
10066 }
developerc1aa6532023-06-09 09:37:01 +080010067 _syscmd(cmd, buf, sizeof(buf));
10068
10069 if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 ||
10070 strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) {
10071 *output_bool = TRUE;
10072 }
developer7e4a2a62023-04-06 19:56:03 +080010073 }
developer72fb0bb2023-01-11 09:46:29 +080010074
developer7e4a2a62023-04-06 19:56:03 +080010075 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010076}
10077
developer69b61b02023-03-07 17:17:44 +080010078// Outputs the AP "Enabled" "Disabled" status from driver
10079INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +080010080{
developer9ce44382023-06-28 11:09:37 +080010081 BOOL output_bool = 0;
developere40952c2023-06-15 18:46:43 +080010082 int res;
developer72fb0bb2023-01-11 09:46:29 +080010083
developer7e4a2a62023-04-06 19:56:03 +080010084 if (!output_string) {
10085 printf("%s: null pointer!", __func__);
10086 return RETURN_ERR;
10087 }
developer72fb0bb2023-01-11 09:46:29 +080010088
developer7e4a2a62023-04-06 19:56:03 +080010089 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +080010090
developer7e4a2a62023-04-06 19:56:03 +080010091 if(output_bool == 1)
developere40952c2023-06-15 18:46:43 +080010092 res = snprintf(output_string, 32, "Up");
developer7e4a2a62023-04-06 19:56:03 +080010093 else
developere40952c2023-06-15 18:46:43 +080010094 res = snprintf(output_string, 32, "Disable");
10095 if (os_snprintf_error(32, res)) {
10096 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10097 return RETURN_ERR;
10098 }
developer7e4a2a62023-04-06 19:56:03 +080010099
10100 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010101}
10102
10103//Indicates whether or not beacons include the SSID name.
10104// outputs a 1 if SSID on the AP is enabled, else outputs 0
10105INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
10106{
developera3511852023-06-14 14:12:59 +080010107 //get the running status
10108 char config_file[MAX_BUF_SIZE] = {0};
10109 char buf[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080010110 int res;
developer72fb0bb2023-01-11 09:46:29 +080010111
developera3511852023-06-14 14:12:59 +080010112 if (!output)
10113 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010114
developer32f2a182023-06-27 19:50:41 +080010115 res = snprintf(config_file, sizeof(config_file),
10116 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010117 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, "ignore_broadcast_ssid", buf, sizeof(buf));
10122 // default is enable
10123 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
10124 *output = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080010125
developera3511852023-06-14 14:12:59 +080010126 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010127}
10128
10129// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
10130INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
10131{
developera3511852023-06-14 14:12:59 +080010132 //store the config, apply instantly
10133 char config_file[MAX_BUF_SIZE] = {0};
10134 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010135 int res;
developer72fb0bb2023-01-11 09:46:29 +080010136
developera3511852023-06-14 14:12:59 +080010137 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10138 list.name = "ignore_broadcast_ssid";
10139 list.value = enable?"0":"1";
developer72fb0bb2023-01-11 09:46:29 +080010140
developer32f2a182023-06-27 19:50:41 +080010141 res = snprintf(config_file, sizeof(config_file),
10142 "%s%d.conf", CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010143 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 //TODO: call hostapd_cli for dynamic_config_control
10150 wifi_reloadAp(apIndex);
10151 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010152
developera3511852023-06-14 14:12:59 +080010153 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010154}
10155
10156//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
10157INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
10158{
developer47cc27a2023-05-17 23:09:58 +080010159 /* get the running status */
10160 if(!output_uint)
developera3511852023-06-14 14:12:59 +080010161 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +080010162
10163 *output_uint = 15;
10164 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010165}
10166
developer47cc27a2023-05-17 23:09:58 +080010167/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +080010168INT wifi_setApRetryLimit(INT apIndex, UINT number)
10169{
developer47cc27a2023-05-17 23:09:58 +080010170 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010171}
10172
developer95c045d2023-05-24 19:26:28 +080010173int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
10174{
10175 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10176 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
10177 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developer2f79c922023-06-02 17:33:42 +080010178 unsigned char *status = (unsigned char *)data;
developer95c045d2023-05-24 19:26:28 +080010179 int err = 0;
developer95c045d2023-05-24 19:26:28 +080010180
10181 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10182 genlmsg_attrlen(gnlh, 0), NULL);
10183 if (err < 0)
10184 return err;
10185
10186 if (tb[NL80211_ATTR_VENDOR_DATA]) {
10187 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
10188 tb[NL80211_ATTR_VENDOR_DATA], NULL);
10189 if (err < 0)
10190 return err;
10191
10192 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
developer95c045d2023-05-24 19:26:28 +080010193 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
10194 }
10195 }
10196
10197 return 0;
10198}
10199
developer72fb0bb2023-01-11 09:46:29 +080010200//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
10201INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
10202{
developer95c045d2023-05-24 19:26:28 +080010203 int if_idx, ret = 0;
developera3511852023-06-14 14:12:59 +080010204 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080010205 unsigned char status = 0;
10206 struct nl_msg *msg = NULL;
10207 struct nlattr * msg_data = NULL;
10208 struct mtk_nl80211_param param;
10209 struct unl unl_ins;
developer8e6583c2023-05-23 13:36:06 +080010210
developera3511852023-06-14 14:12:59 +080010211 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10212 if(!output)
developerdaf24792023-06-06 11:40:04 +080010213 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080010214
developer95c045d2023-05-24 19:26:28 +080010215 if (apIndex > MAX_APS) {
10216 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
10217 return RETURN_ERR;
10218 }
10219
developera3511852023-06-14 14:12:59 +080010220 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developerdaf24792023-06-06 11:40:04 +080010221 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +080010222
10223 if_idx = if_nametoindex(interface_name);
10224 /*init mtk nl80211 vendor cmd*/
10225 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
10226 param.if_type = NL80211_ATTR_IFINDEX;
10227 param.if_idx = if_idx;
10228 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10229
10230 if (ret) {
10231 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10232 return RETURN_ERR;
10233 }
10234
10235 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
10236 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
10237 nlmsg_free(msg);
10238 goto err;
10239 }
10240
10241 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
10242 (void *)&status);
10243 if (ret) {
10244 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
10245 goto err;
10246 }
10247 mtk_nl80211_deint(&unl_ins);
10248
10249 *output = status == 0 ? FALSE : TRUE;
10250 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +080010251
developera3511852023-06-14 14:12:59 +080010252 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10253 return RETURN_OK;
10254err:
developer95c045d2023-05-24 19:26:28 +080010255 mtk_nl80211_deint(&unl_ins);
10256 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
10257 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010258}
10259
10260//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
10261INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
10262{
developera3511852023-06-14 14:12:59 +080010263 //get the running status from driver
10264 char cmd[128] = {0};
10265 char buf[128] = {0};
10266 int max_radio_num = 0, radioIndex = 0;
10267 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080010268 int res;
developer72fb0bb2023-01-11 09:46:29 +080010269
developera3511852023-06-14 14:12:59 +080010270 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010271
developera3511852023-06-14 14:12:59 +080010272 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080010273 if(max_radio_num == 0){
10274 return RETURN_ERR;
10275 }
developera3511852023-06-14 14:12:59 +080010276 radioIndex = apIndex % max_radio_num;
10277 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +080010278 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
10279 if (os_snprintf_error(sizeof(cmd), res)) {
10280 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10281 return RETURN_ERR;
10282 }
developera3511852023-06-14 14:12:59 +080010283 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010284
developera3511852023-06-14 14:12:59 +080010285 if (strlen(buf) > 0)
10286 *output = true;
developer72fb0bb2023-01-11 09:46:29 +080010287
developera3511852023-06-14 14:12:59 +080010288 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010289
developera3511852023-06-14 14:12:59 +080010290 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010291}
10292
10293//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
10294INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
10295{
developera3511852023-06-14 14:12:59 +080010296 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +080010297}
10298
10299// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
10300INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
10301{
developer95c045d2023-05-24 19:26:28 +080010302 int if_idx, ret = 0;
10303 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +080010304 struct nl_msg *msg = NULL;
10305 struct nlattr * msg_data = NULL;
10306 struct mtk_nl80211_param param;
10307 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +080010308
developer95c045d2023-05-24 19:26:28 +080010309 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010310
developer95c045d2023-05-24 19:26:28 +080010311 if (apIndex > MAX_APS) {
10312 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
10313 return RETURN_ERR;
10314 }
developer72fb0bb2023-01-11 09:46:29 +080010315
developer95c045d2023-05-24 19:26:28 +080010316 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10317 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +080010318
developer95c045d2023-05-24 19:26:28 +080010319 if_idx = if_nametoindex(interface_name);
10320 /*init mtk nl80211 vendor cmd*/
10321 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
10322 param.if_type = NL80211_ATTR_IFINDEX;
10323 param.if_idx = if_idx;
10324 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
10325
10326 if (ret) {
10327 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
10328 return RETURN_ERR;
10329 }
10330
10331 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
10332 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
10333 nlmsg_free(msg);
10334 goto err;
10335 }
10336
10337 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
10338 if (ret) {
10339 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
10340 goto err;
10341 }
10342 mtk_nl80211_deint(&unl_ins);
10343
10344 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10345 return RETURN_OK;
10346err:
10347 mtk_nl80211_deint(&unl_ins);
10348 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
10349 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010350}
10351
developer95c045d2023-05-24 19:26:28 +080010352
developer72fb0bb2023-01-11 09:46:29 +080010353//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.
10354INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
10355{
developer75bd10c2023-06-27 11:34:08 +080010356 int res;
10357
developera3511852023-06-14 14:12:59 +080010358 //get the running status from driver
10359 if(!output)
10360 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010361
developera3511852023-06-14 14:12:59 +080010362 char config_file[128] = {0};
10363 char buf[16] = {0};
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, "uapsd_advertisement_enabled", buf, sizeof(buf));
10371 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
10372 *output = TRUE;
10373 else
10374 *output = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010375
developera3511852023-06-14 14:12:59 +080010376 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010377}
10378
10379// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
10380INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
10381{
developera3511852023-06-14 14:12:59 +080010382 //save config and apply instantly.
10383 char config_file[MAX_BUF_SIZE] = {0};
10384 struct params list;
developer75bd10c2023-06-27 11:34:08 +080010385 int res;
developer72fb0bb2023-01-11 09:46:29 +080010386
developera3511852023-06-14 14:12:59 +080010387 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10388 list.name = "uapsd_advertisement_enabled";
10389 list.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080010390
developer75bd10c2023-06-27 11:34:08 +080010391 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10392 if (os_snprintf_error(sizeof(config_file), res)) {
10393 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10394 return RETURN_ERR;
10395 }
developera3511852023-06-14 14:12:59 +080010396 wifi_hostapdWrite(config_file, &list, 1);
10397 wifi_hostapdProcessUpdate(apIndex, &list, 1);
10398 wifi_quick_reload_ap(apIndex);
10399 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010400
developera3511852023-06-14 14:12:59 +080010401 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010402}
10403
10404// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
10405INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
10406{
developera3511852023-06-14 14:12:59 +080010407 char interface_name[16] = {0};
10408 // assume class 0->BE, 1->BK, 2->VI, 3->VO
10409 char cmd[MAX_CMD_SIZE] = {0};
10410 char buf[128] = {0};
10411 char ack_filepath[128] = {0};
10412 uint16_t bitmap = 0;
10413 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
10414 FILE *f = NULL;
developere40952c2023-06-15 18:46:43 +080010415 int res;
developer72fb0bb2023-01-11 09:46:29 +080010416
developera3511852023-06-14 14:12:59 +080010417 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010418
developera3511852023-06-14 14:12:59 +080010419 // Get current setting
developere40952c2023-06-15 18:46:43 +080010420 res = snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
10421 if (os_snprintf_error(sizeof(ack_filepath), res)) {
10422 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10423 return RETURN_ERR;
10424 }
10425 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
10426 if (os_snprintf_error(sizeof(cmd), res)) {
10427 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10428 return RETURN_ERR;
10429 }
developera3511852023-06-14 14:12:59 +080010430 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +080010431 if (strlen(buf) > 0) {
developera3511852023-06-14 14:12:59 +080010432 bitmap = strtoul(buf, NULL, 10);
developerd14dff12023-06-28 22:47:44 +080010433 if (bitmap == 0 && buf[0] != '0') {
10434 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
10435 return RETURN_ERR;
10436 }
10437 }
developer72fb0bb2023-01-11 09:46:29 +080010438
developera3511852023-06-14 14:12:59 +080010439 if (ackPolicy == TRUE) { // True, unset this class
10440 bitmap &= ~class_map[class];
10441 } else { // False, set this class
10442 bitmap |= class_map[class];
10443 }
developer72fb0bb2023-01-11 09:46:29 +080010444
developera3511852023-06-14 14:12:59 +080010445 f = fopen(ack_filepath, "w");
10446 if (f == NULL) {
developer37646972023-06-29 10:58:43 +080010447 if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
10448 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
developera3511852023-06-14 14:12:59 +080010449 return RETURN_ERR;
10450 }
developer37646972023-06-29 10:58:43 +080010451 if (fprintf(f, "%hu", bitmap) < 0)
10452 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
10453
10454 if (fclose(f) == EOF) {
10455 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
10456 return RETURN_ERR;
10457 }
developer72fb0bb2023-01-11 09:46:29 +080010458
developera3511852023-06-14 14:12:59 +080010459 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10460 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010461 res = snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
10462 if (os_snprintf_error(sizeof(cmd), res)) {
10463 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10464 return RETURN_ERR;
10465 }
developera3511852023-06-14 14:12:59 +080010466 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010467
developera3511852023-06-14 14:12:59 +080010468 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10469 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010470}
10471
10472//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.
10473INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
10474{
developer75bd10c2023-06-27 11:34:08 +080010475 int res;
10476
developera3511852023-06-14 14:12:59 +080010477 //get the running status from driver
10478 if(!output_uint)
10479 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010480
developera3511852023-06-14 14:12:59 +080010481 char output[16]={'\0'};
10482 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010483
developer75bd10c2023-06-27 11:34:08 +080010484 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10485 if (os_snprintf_error(sizeof(config_file), res)) {
10486 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10487 return RETURN_ERR;
10488 }
developera3511852023-06-14 14:12:59 +080010489 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
10490 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
10491 else {
10492 int device_num = atoi(output);
10493 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
10494 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
10495 return RETURN_ERR;
10496 }
10497 else {
10498 *output_uint = device_num;
10499 }
10500 }
developer72fb0bb2023-01-11 09:46:29 +080010501
developera3511852023-06-14 14:12:59 +080010502 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010503}
10504
10505INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
10506{
developera3511852023-06-14 14:12:59 +080010507 //store to wifi config, apply instantly
10508 char str[MAX_BUF_SIZE]={'\0'};
10509 struct params params;
10510 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080010511 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080010512
developera3511852023-06-14 14:12:59 +080010513 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10514 if (number > MAX_ASSOCIATED_STA_NUM) {
10515 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
10516 return RETURN_ERR;
10517 }
developer75bd10c2023-06-27 11:34:08 +080010518 res = snprintf(str, sizeof(str), "%d", number);
10519 if (os_snprintf_error(sizeof(str), res)) {
10520 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10521 return RETURN_ERR;
10522 }
developera3511852023-06-14 14:12:59 +080010523 params.name = "max_num_sta";
10524 params.value = str;
developer72fb0bb2023-01-11 09:46:29 +080010525
developer32f2a182023-06-27 19:50:41 +080010526 res = snprintf(config_file,
10527 sizeof(config_file), "%s%d.conf",CONFIG_PREFIX, apIndex);
developer75bd10c2023-06-27 11:34:08 +080010528 if (os_snprintf_error(sizeof(config_file), res)) {
10529 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10530 return RETURN_ERR;
10531 }
developer32f2a182023-06-27 19:50:41 +080010532 ret = wifi_hostapdWrite(config_file, &params, 1);
developera3511852023-06-14 14:12:59 +080010533 if (ret) {
10534 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
10535 ,__func__, ret);
10536 }
developer72fb0bb2023-01-11 09:46:29 +080010537
developera3511852023-06-14 14:12:59 +080010538 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
10539 if (ret) {
10540 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
10541 ,__func__, ret);
10542 }
10543 wifi_reloadAp(apIndex);
10544 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010545
developera3511852023-06-14 14:12:59 +080010546 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010547}
10548
10549//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.
10550INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
10551{
developera3511852023-06-14 14:12:59 +080010552 //get the current threshold
10553 if(!output_uint)
10554 return RETURN_ERR;
10555 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
10556 if (*output_uint == 0)
10557 *output_uint = 50;
10558 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010559}
10560
10561INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
10562{
developera3511852023-06-14 14:12:59 +080010563 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
10564 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
10565 return RETURN_OK;
10566 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010567}
10568
10569//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.
10570INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
10571{
developera3511852023-06-14 14:12:59 +080010572 if(!output_uint)
10573 return RETURN_ERR;
10574 *output_uint = 3;
10575 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010576}
10577
10578//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
10579INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
10580{
developera3511852023-06-14 14:12:59 +080010581 if(!output_uint)
10582 return RETURN_ERR;
10583 *output_uint = 3;
10584 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010585}
10586
10587//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.
10588INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
10589{
developera3511852023-06-14 14:12:59 +080010590 if(!output_in_seconds)
10591 return RETURN_ERR;
10592 *output_in_seconds = 0;
10593 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010594}
10595
10596//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
10597INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
10598{
developere40952c2023-06-15 18:46:43 +080010599 int res;
10600
developera3511852023-06-14 14:12:59 +080010601 if(!output || apIndex>=MAX_APS)
10602 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010603 //res = snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
10604 res = snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
10605 if (os_snprintf_error(128, res)) {
10606 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10607 return RETURN_ERR;
10608 }
developera3511852023-06-14 14:12:59 +080010609 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080010610}
developer72fb0bb2023-01-11 09:46:29 +080010611
10612//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
10613INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
10614{
developera3511852023-06-14 14:12:59 +080010615 char config_file[128] = {0};
10616 char wpa[16] = {0};
10617 char key_mgmt[64] = {0};
developer9ce44382023-06-28 11:09:37 +080010618 int res = -1;
developere40952c2023-06-15 18:46:43 +080010619
developera3511852023-06-14 14:12:59 +080010620 if (!output)
10621 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010622
developer75bd10c2023-06-27 11:34:08 +080010623 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10624 if (os_snprintf_error(sizeof(config_file), res)) {
10625 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10626 return RETURN_ERR;
10627 }
developera3511852023-06-14 14:12:59 +080010628 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
developer72fb0bb2023-01-11 09:46:29 +080010629
developer32f2a182023-06-27 19:50:41 +080010630 memcpy(output, "None", 4);//Copying "None" to output string for default case
10631 output[4] = '\0';
developera3511852023-06-14 14:12:59 +080010632 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
10633 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
10634 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080010635 res = snprintf(output, 32, "WPA-Personal");
developera3511852023-06-14 14:12:59 +080010636 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080010637 res = snprintf(output, 32, "WPA2-Personal");
developera3511852023-06-14 14:12:59 +080010638 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080010639 res = snprintf(output, 32, "WPA-WPA2-Personal");
developer72fb0bb2023-01-11 09:46:29 +080010640
developera3511852023-06-14 14:12:59 +080010641 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
developere40952c2023-06-15 18:46:43 +080010642 res = snprintf(output, 32, "WPA3-Enterprise");
developera3511852023-06-14 14:12:59 +080010643 } else if (strstr(key_mgmt, "WPA-EAP")) {
10644 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +080010645 res = snprintf(output, 32, "WPA-Enterprise");
developera3511852023-06-14 14:12:59 +080010646 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +080010647 res = snprintf(output, 32, "WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080010648 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +080010649 res = snprintf(output, 32, "WPA-WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +080010650 } else if (strstr(key_mgmt, "SAE")) {
10651 if (strstr(key_mgmt, "WPA-PSK") == NULL)
developere40952c2023-06-15 18:46:43 +080010652 res = snprintf(output, 32, "WPA3-Personal");
developera3511852023-06-14 14:12:59 +080010653 else
developere40952c2023-06-15 18:46:43 +080010654 res = snprintf(output, 32, "WPA3-Personal-Transition");
10655 }
10656 if (os_snprintf_error(32, res)) {
10657 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10658 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080010659 }
developer72fb0bb2023-01-11 09:46:29 +080010660
developera3511852023-06-14 14:12:59 +080010661 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
10662 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010663}
developer69b61b02023-03-07 17:17:44 +080010664
developer72fb0bb2023-01-11 09:46:29 +080010665INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
10666{
developer32f2a182023-06-27 19:50:41 +080010667 char securityType[32] = {0};
10668 char authMode[32] = {0};
10669 unsigned long len_sec, len_auth;
developera3511852023-06-14 14:12:59 +080010670 //store settings and wait for wifi up to apply
10671 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10672 if(!encMode)
10673 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010674
developera3511852023-06-14 14:12:59 +080010675 if (strcmp(encMode, "None")==0)
10676 {
developer32f2a182023-06-27 19:50:41 +080010677 len_sec = strlen("None");
10678 len_auth = strlen("None");
10679 memcpy(securityType, "None", len_sec);
10680 memcpy(authMode, "None", len_auth);
10681 } else if (strcmp(encMode, "WPA-WPA2-Personal")==0) {
10682 len_sec = strlen("WPAand11i");
10683 memcpy(securityType, "WPAand11i", len_sec);
10684 len_auth = strlen("PSKAuthentication");
10685 memcpy(authMode, "PSKAuthentication", len_auth);
10686 } else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) {
10687 len_sec = strlen("WPAand11i");
10688 memcpy(securityType, "WPAand11i", len_sec);
10689 len_auth = strlen("EAPAuthentication");
10690 memcpy(authMode, "EAPAuthentication", len_auth);
10691 } else if (strcmp(encMode, "WPA-Personal")==0) {
10692 len_sec = strlen("WPA");
10693 memcpy(securityType, "WPA", len_sec);
10694 len_auth = strlen("PSKAuthentication");
10695 memcpy(authMode, "PSKAuthentication", len_auth);
10696 } else if (strcmp(encMode, "WPA-Enterprise")==0) {
10697 len_sec = strlen("WPA");
10698 memcpy(securityType, "WPA", len_sec);
10699 len_auth = strlen("EAPAuthentication");
10700 memcpy(authMode, "EAPAuthentication", len_auth);
10701 } else if (strcmp(encMode, "WPA2-Personal")==0) {
10702 len_sec = strlen("11i");
10703 memcpy(securityType, "11i", len_sec);
10704 len_auth = strlen("PSKAuthentication");
10705 memcpy(authMode, "PSKAuthentication", len_auth);
10706 } else if (strcmp(encMode, "WPA2-Enterprise")==0) {
10707 len_sec = strlen("11i");
10708 memcpy(securityType, "11i", len_sec);
10709 len_auth = strlen("EAPAuthentication");
10710 memcpy(authMode, "EAPAuthentication", len_auth);
10711 } else if (strcmp(encMode, "WPA3-Personal") == 0) {
10712 len_sec = strlen("11i");
10713 memcpy(securityType, "11i", len_sec);
10714 len_auth = strlen("SAEAuthentication");
10715 memcpy(authMode, "SAEAuthentication", len_auth);
10716 } else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) {
10717 len_sec = strlen("11i");
10718 memcpy(securityType, "11i", len_sec);
10719 len_auth = strlen("PSK-SAEAuthentication");
10720 memcpy(authMode, "PSK-SAEAuthentication", len_auth);
10721 } else if (strcmp(encMode, "WPA3-Enterprise") == 0) {
10722 len_sec = strlen("11i");
10723 memcpy(securityType, "11i", len_sec);
10724 len_auth = strlen("EAP_192-bit_Authentication");
10725 memcpy(authMode, "EAP_192-bit_Authentication", len_auth);
10726 } else if (strcmp(encMode, "OWE") == 0) {
10727 len_sec = strlen("11i");
10728 memcpy(securityType, "11i", len_sec);
10729 len_auth = strlen("Enhanced_Open");
10730 memcpy(authMode, "Enhanced_Open", len_auth);
10731 } else {
10732 len_sec = strlen("None");
10733 memcpy(securityType, "None", len_sec);
10734 len_auth = strlen("None");
10735 memcpy(authMode, "None", len_auth);
developera3511852023-06-14 14:12:59 +080010736 }
developer32f2a182023-06-27 19:50:41 +080010737 securityType[len_sec] = '\0';
10738 authMode[len_auth] = '\0';
developera3511852023-06-14 14:12:59 +080010739 wifi_setApBeaconType(apIndex, securityType);
10740 wifi_setApBasicAuthenticationMode(apIndex, authMode);
10741 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010742
developera3511852023-06-14 14:12:59 +080010743 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080010744}
developer72fb0bb2023-01-11 09:46:29 +080010745
10746
10747//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
10748// output_string must be pre-allocated as 64 character string by caller
10749// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
10750INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
10751{
developera3511852023-06-14 14:12:59 +080010752 char buf[16] = {0};
10753 char config_file[MAX_BUF_SIZE] = {0};
10754 int res;
developer72fb0bb2023-01-11 09:46:29 +080010755
developera3511852023-06-14 14:12:59 +080010756 if(output_string==NULL)
10757 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010758
developera3511852023-06-14 14:12:59 +080010759 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10760 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010761 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10762 return RETURN_ERR;
10763 }
developera3511852023-06-14 14:12:59 +080010764 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010765
developera3511852023-06-14 14:12:59 +080010766 if(strcmp(buf,"0")==0)
10767 {
10768 printf("wpa_mode is %s ......... \n",buf);
10769 return RETURN_ERR;
10770 }
developer72fb0bb2023-01-11 09:46:29 +080010771
developera3511852023-06-14 14:12:59 +080010772 wifi_dbg_printf("\nFunc=%s\n",__func__);
10773 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
10774 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010775 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10776 return RETURN_ERR;
10777 }
developere5750452023-05-15 16:46:42 +080010778 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developera3511852023-06-14 14:12:59 +080010779 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080010780
developera3511852023-06-14 14:12:59 +080010781 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010782}
10783
10784// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
10785// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
10786INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
10787{
developera3511852023-06-14 14:12:59 +080010788 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
10789 struct params params={'\0'};
developer32f2a182023-06-27 19:50:41 +080010790 int ret;
developera3511852023-06-14 14:12:59 +080010791 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010792
developera3511852023-06-14 14:12:59 +080010793 if(NULL == preSharedKey)
10794 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010795
developera3511852023-06-14 14:12:59 +080010796 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +080010797
developera3511852023-06-14 14:12:59 +080010798 if(strlen(preSharedKey) != 64)
10799 {
10800 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
10801 return RETURN_ERR;
10802 }
10803 params.value = preSharedKey;
developer32f2a182023-06-27 19:50:41 +080010804 ret = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10805 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080010806 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10807 return RETURN_ERR;
10808 }
developera3511852023-06-14 14:12:59 +080010809 ret = wifi_hostapdWrite(config_file, &params, 1);
10810 if(!ret) {
10811 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
10812 wifi_reloadAp(apIndex);
10813 }
10814 return ret;
10815 //TODO: call hostapd_cli for dynamic_config_control
developer72fb0bb2023-01-11 09:46:29 +080010816}
10817
10818//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
10819// outputs the passphrase, maximum 63 characters
10820INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
10821{
developera3511852023-06-14 14:12:59 +080010822 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
developer75bd10c2023-06-27 11:34:08 +080010823 int res;
developer72fb0bb2023-01-11 09:46:29 +080010824
developera3511852023-06-14 14:12:59 +080010825 wifi_dbg_printf("\nFunc=%s\n",__func__);
10826 if (NULL == output_string)
10827 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010828
developer75bd10c2023-06-27 11:34:08 +080010829 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10830 if (os_snprintf_error(sizeof(config_file), res)) {
10831 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10832 return RETURN_ERR;
10833 }
10834
developera3511852023-06-14 14:12:59 +080010835 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
10836 if(strcmp(buf,"0")==0)
10837 {
10838 printf("wpa_mode is %s ......... \n",buf);
10839 return RETURN_ERR;
10840 }
developer72fb0bb2023-01-11 09:46:29 +080010841
developera3511852023-06-14 14:12:59 +080010842 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
10843 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +080010844
developera3511852023-06-14 14:12:59 +080010845 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010846}
10847
10848// sets the passphrase enviornment variable, max 63 characters
10849INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
10850{
developera3511852023-06-14 14:12:59 +080010851 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
10852 struct params params={'\0'};
10853 char config_file[MAX_BUF_SIZE] = {0};
10854 int ret;
developer72fb0bb2023-01-11 09:46:29 +080010855
developera3511852023-06-14 14:12:59 +080010856 if(NULL == passPhrase)
10857 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010858
developera3511852023-06-14 14:12:59 +080010859 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
10860 {
10861 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
10862 return RETURN_ERR;
10863 }
10864 params.name = "wpa_passphrase";
10865 params.value = passPhrase;
developer32f2a182023-06-27 19:50:41 +080010866 ret = snprintf(config_file, sizeof(config_file),
10867 "%s%d.conf", CONFIG_PREFIX, apIndex);
10868 if (os_snprintf_error(sizeof(config_file), ret)) {
developer75bd10c2023-06-27 11:34:08 +080010869 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10870 return RETURN_ERR;
10871 }
developera3511852023-06-14 14:12:59 +080010872 ret=wifi_hostapdWrite(config_file,&params,1);
10873 if(!ret) {
10874 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +080010875 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +080010876 }
developer72fb0bb2023-01-11 09:46:29 +080010877
developera3511852023-06-14 14:12:59 +080010878 return ret;
developer72fb0bb2023-01-11 09:46:29 +080010879}
10880
10881//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.
10882INT wifi_setApSecurityReset(INT apIndex)
10883{
developera3511852023-06-14 14:12:59 +080010884 char original_config_file[64] = {0};
10885 char current_config_file[64] = {0};
10886 char buf[64] = {0};
10887 char cmd[64] = {0};
10888 char wpa[4] = {0};
10889 char wpa_psk[64] = {0};
10890 char wpa_passphrase[64] = {0};
10891 char wpa_psk_file[128] = {0};
10892 char wpa_key_mgmt[64] = {0};
10893 char wpa_pairwise[32] = {0};
10894 wifi_band band;
10895 struct params list[6];
developere40952c2023-06-15 18:46:43 +080010896 int res;
developer72fb0bb2023-01-11 09:46:29 +080010897
developera3511852023-06-14 14:12:59 +080010898 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010899
developera3511852023-06-14 14:12:59 +080010900 band = wifi_index_to_band(apIndex);
developer37646972023-06-29 10:58:43 +080010901 if (band == band_2_4) {
10902 res = snprintf(original_config_file, sizeof(original_config_file),
10903 "/etc/hostapd-2G.conf");
10904 if (os_snprintf_error(sizeof(original_config_file), res)) {
10905 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10906 return RETURN_ERR;
10907 }
10908 } else if (band == band_5) {
10909 res = snprintf(original_config_file, sizeof(original_config_file),
10910 "/etc/hostapd-5G.conf");
10911 if (os_snprintf_error(sizeof(original_config_file), res)) {
10912 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10913 return RETURN_ERR;
10914 }
10915 } else if (band == band_6) {
10916 res = snprintf(original_config_file, sizeof(original_config_file),
10917 "/etc/hostapd-6G.conf");
10918 if (os_snprintf_error(sizeof(original_config_file), res)) {
10919 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10920 return RETURN_ERR;
10921 }
10922 } else
developera3511852023-06-14 14:12:59 +080010923 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010924
developera3511852023-06-14 14:12:59 +080010925 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
10926 list[0].name = "wpa";
10927 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +080010928
developera3511852023-06-14 14:12:59 +080010929 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
10930 list[1].name = "wpa_psk";
10931 list[1].value = wpa_psk;
developer72fb0bb2023-01-11 09:46:29 +080010932
developera3511852023-06-14 14:12:59 +080010933 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
10934 list[2].name = "wpa_passphrase";
10935 list[2].value = wpa_passphrase;
developer72fb0bb2023-01-11 09:46:29 +080010936
developera3511852023-06-14 14:12:59 +080010937 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
developer72fb0bb2023-01-11 09:46:29 +080010938
developera3511852023-06-14 14:12:59 +080010939 if (strlen(wpa_psk_file) == 0)
developer32f2a182023-06-27 19:50:41 +080010940 memcpy(wpa_psk_file, PSK_FILE, strlen(PSK_FILE));
developer72fb0bb2023-01-11 09:46:29 +080010941
developera3511852023-06-14 14:12:59 +080010942 if (access(wpa_psk_file, F_OK) != 0) {
developerd14dff12023-06-28 22:47:44 +080010943 res = snprintf(cmd, sizeof(cmd), "touch %s", wpa_psk_file);
developere40952c2023-06-15 18:46:43 +080010944 if (os_snprintf_error(sizeof(cmd), res)) {
10945 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10946 return RETURN_ERR;
10947 }
developera3511852023-06-14 14:12:59 +080010948 _syscmd(cmd, buf, sizeof(buf));
10949 }
10950 list[3].name = "wpa_psk_file";
10951 list[3].value = wpa_psk_file;
developer72fb0bb2023-01-11 09:46:29 +080010952
developera3511852023-06-14 14:12:59 +080010953 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
10954 list[4].name = "wpa_key_mgmt";
10955 list[4].value = wpa_key_mgmt;
developer72fb0bb2023-01-11 09:46:29 +080010956
developera3511852023-06-14 14:12:59 +080010957 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
10958 list[5].name = "wpa_pairwise";
10959 list[5].value = wpa_pairwise;
developer72fb0bb2023-01-11 09:46:29 +080010960
developer32f2a182023-06-27 19:50:41 +080010961 res = snprintf(current_config_file, sizeof(current_config_file),
10962 "%s%d.conf", CONFIG_PREFIX, apIndex);
10963 if (os_snprintf_error(sizeof(current_config_file), res)) {
10964 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10965 return RETURN_ERR;
10966 }
developera3511852023-06-14 14:12:59 +080010967 wifi_hostapdWrite(current_config_file, list, 6);
developer72fb0bb2023-01-11 09:46:29 +080010968
developera3511852023-06-14 14:12:59 +080010969 wifi_setApEnable(apIndex, FALSE);
10970 wifi_setApEnable(apIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +080010971
developera3511852023-06-14 14:12:59 +080010972 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10973 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010974}
10975
10976//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).
10977INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
10978{
developera3511852023-06-14 14:12:59 +080010979 char config_file[64] = {0};
10980 char buf[64] = {0};
10981 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +080010982 int res;
developer72fb0bb2023-01-11 09:46:29 +080010983
developera3511852023-06-14 14:12:59 +080010984 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010985
developera3511852023-06-14 14:12:59 +080010986 if(!IP_output || !Port_output || !RadiusSecret_output)
10987 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010988
developera3511852023-06-14 14:12:59 +080010989 // Read the first matched config
developere40952c2023-06-15 18:46:43 +080010990 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10991 if (os_snprintf_error(sizeof(config_file), res)) {
10992 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10993 return RETURN_ERR;
10994 }
developer32f2a182023-06-27 19:50:41 +080010995 res = snprintf(cmd, sizeof(cmd),
10996 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
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 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011003
developera3511852023-06-14 14:12:59 +080011004 memset(buf, 0, sizeof(buf));
developer75bd10c2023-06-27 11:34:08 +080011005 res = snprintf(cmd, sizeof(cmd), "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
11006 if (os_snprintf_error(sizeof(cmd), res)) {
11007 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11008 return RETURN_ERR;
11009 }
developera3511852023-06-14 14:12:59 +080011010 _syscmd(cmd, buf, sizeof(buf));
11011 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011012
developera3511852023-06-14 14:12:59 +080011013 memset(buf, 0, sizeof(buf));
developer75bd10c2023-06-27 11:34:08 +080011014 res = snprintf(cmd, sizeof(cmd), "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
11015 if (os_snprintf_error(sizeof(cmd), res)) {
11016 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11017 return RETURN_ERR;
11018 }
developera3511852023-06-14 14:12:59 +080011019 _syscmd(cmd, buf, sizeof(buf));
11020 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011021
developera3511852023-06-14 14:12:59 +080011022 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11023 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011024}
11025
11026INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
11027{
developera3511852023-06-14 14:12:59 +080011028 char config_file[64] = {0};
11029 char port_str[8] = {0};
11030 char cmd[256] = {0};
11031 char buf[128] = {0};
11032 int res;
developer72fb0bb2023-01-11 09:46:29 +080011033
developera3511852023-06-14 14:12:59 +080011034 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011035
developere5750452023-05-15 16:46:42 +080011036 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080011037 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011038
developera3511852023-06-14 14:12:59 +080011039 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
11040 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011041
developera3511852023-06-14 14:12:59 +080011042 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11043 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080011044 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11045 return RETURN_ERR;
11046 }
developer72fb0bb2023-01-11 09:46:29 +080011047
developera3511852023-06-14 14:12:59 +080011048 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
11049 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011050 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11051 return RETURN_ERR;
11052 }
developera3511852023-06-14 14:12:59 +080011053 _syscmd(cmd, buf, sizeof(buf));
11054 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080011055
developere40952c2023-06-15 18:46:43 +080011056 res = snprintf(port_str, sizeof(port_str), "%d", port);
developer37646972023-06-29 10:58:43 +080011057 if (os_snprintf_error(sizeof(port_str), res)) {
11058 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11059 return RETURN_ERR;
11060 }
developera3511852023-06-14 14:12:59 +080011061 if (strlen(buf) == 0) {
11062 // Append
11063 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
11064 "auth_server_addr=%s\\n"
11065 "auth_server_port=%s\\n"
11066 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
11067 if (os_snprintf_error(sizeof(cmd), res)) {
11068 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11069 return RETURN_ERR;
11070 }
11071 } else {
11072 // Delete the three lines setting after the "# radius 1" comment
11073 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
11074 if (os_snprintf_error(sizeof(cmd), res)) {
11075 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11076 return RETURN_ERR;
11077 }
11078 _syscmd(cmd, buf, sizeof(buf));
11079 memset(cmd, 0, sizeof(cmd));
11080 // Use "# radius 1" comment to find the location to insert the radius setting
11081 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
11082 "# radius 1\\n"
11083 "auth_server_addr=%s\\n"
11084 "auth_server_port=%s\\n"
11085 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
11086 if (os_snprintf_error(sizeof(cmd), res)) {
11087 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11088 return RETURN_ERR;
11089 }
11090 }
11091 if(_syscmd(cmd, buf, sizeof(buf))) {
11092 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
11093 return RETURN_ERR;
11094 }
developer72fb0bb2023-01-11 09:46:29 +080011095
developera3511852023-06-14 14:12:59 +080011096 wifi_reloadAp(apIndex);
11097 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11098 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011099}
11100
11101INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
11102{
developera3511852023-06-14 14:12:59 +080011103 char config_file[64] = {0};
11104 char buf[64] = {0};
11105 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +080011106 int res;
developer72fb0bb2023-01-11 09:46:29 +080011107
developera3511852023-06-14 14:12:59 +080011108 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011109
developera3511852023-06-14 14:12:59 +080011110 if(!IP_output || !Port_output || !RadiusSecret_output)
11111 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011112
developera3511852023-06-14 14:12:59 +080011113 // Read the second matched config
developere40952c2023-06-15 18:46:43 +080011114 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11115 if (os_snprintf_error(sizeof(config_file), res)) {
11116 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11117 return RETURN_ERR;
11118 }
11119
developer32f2a182023-06-27 19:50:41 +080011120 res = snprintf(cmd, sizeof(cmd),
11121 "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
11122 config_file);
developer75bd10c2023-06-27 11:34:08 +080011123 if (os_snprintf_error(sizeof(cmd), res)) {
11124 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11125 return RETURN_ERR;
11126 }
developera3511852023-06-14 14:12:59 +080011127 _syscmd(cmd, buf, sizeof(buf));
11128 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011129
developera3511852023-06-14 14:12:59 +080011130 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080011131 res = snprintf(cmd, sizeof(cmd),
11132 "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
11133 config_file);
developer75bd10c2023-06-27 11:34:08 +080011134 if (os_snprintf_error(sizeof(cmd), res)) {
11135 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11136 return RETURN_ERR;
11137 }
developera3511852023-06-14 14:12:59 +080011138 _syscmd(cmd, buf, sizeof(buf));
11139 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011140
developera3511852023-06-14 14:12:59 +080011141 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080011142 res = snprintf(cmd, sizeof(cmd),
11143 "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
11144 config_file);
developer75bd10c2023-06-27 11:34:08 +080011145 if (os_snprintf_error(sizeof(cmd), res)) {
11146 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11147 return RETURN_ERR;
11148 }
11149
developera3511852023-06-14 14:12:59 +080011150 _syscmd(cmd, buf, sizeof(buf));
11151 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +080011152
developera3511852023-06-14 14:12:59 +080011153 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11154 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011155}
11156
11157INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
11158{
developera3511852023-06-14 14:12:59 +080011159 char config_file[64] = {0};
11160 char port_str[8] = {0};
11161 char cmd[256] = {0};
11162 char buf[128] = {0};
11163 int res;
developer72fb0bb2023-01-11 09:46:29 +080011164
developera3511852023-06-14 14:12:59 +080011165 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011166
developere5750452023-05-15 16:46:42 +080011167 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +080011168 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011169
developera3511852023-06-14 14:12:59 +080011170 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
11171 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +080011172
developera3511852023-06-14 14:12:59 +080011173 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11174 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080011175 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11176 return RETURN_ERR;
11177 }
developer72fb0bb2023-01-11 09:46:29 +080011178
developera3511852023-06-14 14:12:59 +080011179 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
11180 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011181 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11182 return RETURN_ERR;
11183 }
developera3511852023-06-14 14:12:59 +080011184 _syscmd(cmd, buf, sizeof(buf));
11185 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +080011186
developera3511852023-06-14 14:12:59 +080011187 res = snprintf(port_str, sizeof(port_str), "%d", port);
11188 if (os_snprintf_error(sizeof(port_str), res)) {
developer46506162023-06-12 10:09:39 +080011189 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11190 return RETURN_ERR;
11191 }
developera3511852023-06-14 14:12:59 +080011192 if (strlen(buf) == 0) {
11193 // Append
11194 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
11195 "auth_server_addr=%s\\n"
11196 "auth_server_port=%s\\n"
11197 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
11198 if (os_snprintf_error(sizeof(cmd), res)) {
11199 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11200 return RETURN_ERR;
11201 }
11202 } else {
11203 // Delete the three lines setting after the "# radius 2" comment
11204 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
11205 if (os_snprintf_error(sizeof(cmd), res)) {
11206 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11207 return RETURN_ERR;
11208 }
11209 _syscmd(cmd, buf, sizeof(buf));
11210 memset(cmd, 0, sizeof(cmd));
11211 // Use "# radius 2" comment to find the location to insert the radius setting
11212 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
11213 "# radius 2\\n"
11214 "auth_server_addr=%s\\n"
11215 "auth_server_port=%s\\n"
11216 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
11217 if (os_snprintf_error(sizeof(cmd), res)) {
11218 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11219 return RETURN_ERR;
11220 }
11221 }
11222 if(_syscmd(cmd, buf, sizeof(buf))) {
11223 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
11224 return RETURN_ERR;
11225 }
developer72fb0bb2023-01-11 09:46:29 +080011226
developera3511852023-06-14 14:12:59 +080011227 wifi_reloadAp(apIndex);
11228 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11229 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011230}
11231
11232//RadiusSettings
11233INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
11234{
developera3511852023-06-14 14:12:59 +080011235 if(!output)
11236 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011237
developera3511852023-06-14 14:12:59 +080011238 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
11239 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
11240 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
11241 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
11242 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
11243 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.
11244 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
11245 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
11246 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 +080011247 //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 +080011248
developera3511852023-06-14 14:12:59 +080011249 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011250}
11251
11252INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
11253{
developera3511852023-06-14 14:12:59 +080011254 //store the paramters, and apply instantly
11255 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011256}
11257
11258//Device.WiFi.AccessPoint.{i}.WPS.Enable
11259//Enables or disables WPS functionality for this access point.
11260// outputs the WPS enable state of this ap in output_bool
11261INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
11262{
developera3511852023-06-14 14:12:59 +080011263 char interface_name[16] = {0};
11264 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080011265 int res;
11266
developera3511852023-06-14 14:12:59 +080011267 if(!output_bool)
11268 return RETURN_ERR;
11269 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11270 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080011271 res = snprintf(cmd, sizeof(cmd),
11272 "hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2",
11273 interface_name);
developer75bd10c2023-06-27 11:34:08 +080011274 if (os_snprintf_error(sizeof(cmd), res)) {
11275 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11276 return RETURN_ERR;
11277 }
developera3511852023-06-14 14:12:59 +080011278 _syscmd(cmd, buf, sizeof(buf));
11279 if(strstr(buf, "configured"))
11280 *output_bool=TRUE;
11281 else
11282 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +080011283
developera3511852023-06-14 14:12:59 +080011284 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +080011285}
developer72fb0bb2023-01-11 09:46:29 +080011286
11287//Device.WiFi.AccessPoint.{i}.WPS.Enable
11288// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
11289INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
11290{
developera3511852023-06-14 14:12:59 +080011291 char config_file[MAX_BUF_SIZE] = {0};
11292 char buf[128] = {0};
11293 struct params params;
developere40952c2023-06-15 18:46:43 +080011294 int res;
developer72fb0bb2023-01-11 09:46:29 +080011295
developera3511852023-06-14 14:12:59 +080011296 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11297 //store the paramters, and wait for wifi up to apply
11298 params.name = "wps_state";
11299 if (enable == TRUE) {
11300 wifi_getApBeaconType(apIndex, buf);
11301 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
11302 params.value = "1";
11303 else // If ap set encryption
11304 params.value = "2";
11305 } else {
11306 params.value = "0";
11307 }
developer72fb0bb2023-01-11 09:46:29 +080011308
developere40952c2023-06-15 18:46:43 +080011309 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11310 if (os_snprintf_error(sizeof(config_file), res)) {
11311 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11312 return RETURN_ERR;
11313 }
developera3511852023-06-14 14:12:59 +080011314 wifi_hostapdWrite(config_file, &params, 1);
11315 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11316 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080011317
developera3511852023-06-14 14:12:59 +080011318 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11319 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011320}
11321
11322//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
11323INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
11324{
developere40952c2023-06-15 18:46:43 +080011325 int res;
developera3511852023-06-14 14:12:59 +080011326 if(!output)
11327 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011328 res = snprintf(output, 128, "PushButton,PIN");
11329 if (os_snprintf_error(128, res)) {
11330 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11331 return RETURN_ERR;
11332 }
11333
developera3511852023-06-14 14:12:59 +080011334 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011335}
11336
11337//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
11338//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.
11339// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
11340INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
11341{
developere40952c2023-06-15 18:46:43 +080011342 int res;
developera3511852023-06-14 14:12:59 +080011343 if(!output)
11344 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011345 res = snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
11346 if (os_snprintf_error(64, res)) {
11347 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11348 return RETURN_ERR;
11349 }
developer72fb0bb2023-01-11 09:46:29 +080011350
developera3511852023-06-14 14:12:59 +080011351 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011352}
11353
11354//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
11355// 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
11356INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
11357{
developera3511852023-06-14 14:12:59 +080011358 //apply instantly. No setting need to be stored.
11359 char methods[MAX_BUF_SIZE], *token, *next_token;
11360 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
11361 struct params params;
developere40952c2023-06-15 18:46:43 +080011362 int res;
developer72fb0bb2023-01-11 09:46:29 +080011363
developera3511852023-06-14 14:12:59 +080011364 if(!methodString)
11365 return RETURN_ERR;
11366 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11367 //store the paramters, and wait for wifi up to apply
developer72fb0bb2023-01-11 09:46:29 +080011368
developere40952c2023-06-15 18:46:43 +080011369 res = snprintf(methods, sizeof(methods), "%s", methodString);
11370 if (os_snprintf_error(sizeof(methods), res)) {
11371 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11372 return RETURN_ERR;
11373 }
developera3511852023-06-14 14:12:59 +080011374 for(token=methods; *token; token=next_token) {
11375 strtok_r(token, ",", &next_token);
11376 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
developere40952c2023-06-15 18:46:43 +080011377 res = snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
developera3511852023-06-14 14:12:59 +080011378 else if(*token=='E')
11379 {
11380 if(!strcmp(methods, "Ethernet"))
developere40952c2023-06-15 18:46:43 +080011381 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
developera3511852023-06-14 14:12:59 +080011382 else if(!strcmp(methods, "ExternalNFCToken"))
developere40952c2023-06-15 18:46:43 +080011383 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
developera3511852023-06-14 14:12:59 +080011384 else
11385 printf("%s: Unknown WpsConfigMethod\n", __func__);
11386 }
11387 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
developere40952c2023-06-15 18:46:43 +080011388 res = snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
developera3511852023-06-14 14:12:59 +080011389 else if(*token=='N' && !strcmp(token, "NFCInterface"))
developere40952c2023-06-15 18:46:43 +080011390 res = snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
developera3511852023-06-14 14:12:59 +080011391 else if(*token=='P' )
11392 {
11393 if(!strcmp(token, "PushButton"))
developere40952c2023-06-15 18:46:43 +080011394 res = snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developera3511852023-06-14 14:12:59 +080011395 else if(!strcmp(token, "PIN"))
developere40952c2023-06-15 18:46:43 +080011396 res = snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
developera3511852023-06-14 14:12:59 +080011397 else
11398 printf("%s: Unknown WpsConfigMethod\n", __func__);
11399 }
11400 else
11401 printf("%s: Unknown WpsConfigMethod\n", __func__);
developere40952c2023-06-15 18:46:43 +080011402
developer37646972023-06-29 10:58:43 +080011403 if (os_snprintf_error(sizeof(config_methods), res)) {
11404 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11405 return RETURN_ERR;
11406 }
11407 }
developera3511852023-06-14 14:12:59 +080011408 params.name = "config_methods";
11409 params.value = config_methods;
developere40952c2023-06-15 18:46:43 +080011410 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11411 if (os_snprintf_error(sizeof(config_file), res)) {
11412 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11413 return RETURN_ERR;
11414 }
developera3511852023-06-14 14:12:59 +080011415 wifi_hostapdWrite(config_file, &params, 1);
11416 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11417 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011418
developera3511852023-06-14 14:12:59 +080011419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011420}
11421
11422// outputs the pin value, ulong_pin must be allocated by the caller
11423INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
11424{
developera3511852023-06-14 14:12:59 +080011425 char buf[MAX_BUF_SIZE] = {0};
11426 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011427 int res;
developer72fb0bb2023-01-11 09:46:29 +080011428
developera3511852023-06-14 14:12:59 +080011429 if(!output_ulong)
11430 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011431 res = snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
11432 if (os_snprintf_error(sizeof(cmd), res)) {
11433 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11434 return RETURN_ERR;
11435 }
developera3511852023-06-14 14:12:59 +080011436 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +080011437 if(strlen(buf) > 0) {
developera3511852023-06-14 14:12:59 +080011438 *output_ulong=strtoul(buf, NULL, 10);
developerd14dff12023-06-28 22:47:44 +080011439 if (*output_ulong == 0 && buf[0] != '0') {
11440 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
11441 return RETURN_ERR;
11442 }
11443 }
developer72fb0bb2023-01-11 09:46:29 +080011444
developera3511852023-06-14 14:12:59 +080011445 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011446}
11447
11448// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
11449INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
11450{
developera3511852023-06-14 14:12:59 +080011451 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
11452 char ap_pin[16] = {0};
11453 char config_file[MAX_BUF_SIZE] = {0};
11454 struct params params;
developere40952c2023-06-15 18:46:43 +080011455 int res;
developer72fb0bb2023-01-11 09:46:29 +080011456
developera3511852023-06-14 14:12:59 +080011457 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080011458 res = snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
11459 if (os_snprintf_error(sizeof(ap_pin), res)) {
11460 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11461 return RETURN_ERR;
11462 }
developera3511852023-06-14 14:12:59 +080011463 params.name = "ap_pin";
11464 params.value = ap_pin;
developere40952c2023-06-15 18:46:43 +080011465 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
11466 if (os_snprintf_error(sizeof(config_file), res)) {
11467 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11468 return RETURN_ERR;
11469 }
developera3511852023-06-14 14:12:59 +080011470 wifi_hostapdWrite(config_file, &params, 1);
11471 wifi_hostapdProcessUpdate(apIndex, &params, 1);
11472 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011473
developera3511852023-06-14 14:12:59 +080011474 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011475}
11476
11477// Output string is either Not configured or Configured, max 32 characters
11478INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
11479{
developera3511852023-06-14 14:12:59 +080011480 char interface_name[16] = {0};
11481 char cmd[MAX_CMD_SIZE];
11482 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080011483 int res;
developer72fb0bb2023-01-11 09:46:29 +080011484
developera3511852023-06-14 14:12:59 +080011485 if(!output_string)
11486 return RETURN_ERR;
11487 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080011488 res = snprintf(output_string, 32, "Not configured");
11489 if (os_snprintf_error(32, res)) {
11490 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11491 return RETURN_ERR;
11492 }
developera3511852023-06-14 14:12:59 +080011493 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11494 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011495 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
11496 if (os_snprintf_error(sizeof(cmd), res)) {
11497 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11498 return RETURN_ERR;
11499 }
developera3511852023-06-14 14:12:59 +080011500 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011501
developera3511852023-06-14 14:12:59 +080011502 if(!strncmp(buf, "configured", 10))
developere40952c2023-06-15 18:46:43 +080011503 res = snprintf(output_string, 32, "Configured");
developera3511852023-06-14 14:12:59 +080011504 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011505
developera3511852023-06-14 14:12:59 +080011506 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011507}
11508
11509// sets the WPS pin for this AP
11510INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
11511{
developera3511852023-06-14 14:12:59 +080011512 char interface_name[16] = {0};
11513 char cmd[MAX_CMD_SIZE];
11514 char buf[MAX_BUF_SIZE]={0};
developer9ce44382023-06-28 11:09:37 +080011515 BOOL enable = 0;
developere40952c2023-06-15 18:46:43 +080011516 int res;
developer72fb0bb2023-01-11 09:46:29 +080011517
developera3511852023-06-14 14:12:59 +080011518 wifi_getApEnable(apIndex, &enable);
11519 if (!enable)
11520 return RETURN_ERR;
11521 wifi_getApWpsEnable(apIndex, &enable);
11522 if (!enable)
11523 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011524
developera3511852023-06-14 14:12:59 +080011525 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11526 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011527 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
11528 if (os_snprintf_error(sizeof(cmd), res)) {
11529 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11530 return RETURN_ERR;
11531 }
developera3511852023-06-14 14:12:59 +080011532 _syscmd(cmd, buf, sizeof(buf));
11533 if((strstr(buf, "OK"))!=NULL)
11534 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011535
developera3511852023-06-14 14:12:59 +080011536 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011537}
11538
11539// This function is called when the WPS push button has been pressed for this AP
11540INT wifi_setApWpsButtonPush(INT apIndex)
11541{
developera3511852023-06-14 14:12:59 +080011542 char cmd[MAX_CMD_SIZE];
11543 char buf[MAX_BUF_SIZE]={0};
11544 char interface_name[16] = {0};
11545 BOOL enable=FALSE;
developere40952c2023-06-15 18:46:43 +080011546 int res;
developer72fb0bb2023-01-11 09:46:29 +080011547
developera3511852023-06-14 14:12:59 +080011548 wifi_getApEnable(apIndex, &enable);
11549 if (!enable)
11550 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011551
developera3511852023-06-14 14:12:59 +080011552 wifi_getApWpsEnable(apIndex, &enable);
11553 if (!enable)
11554 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011555
developera3511852023-06-14 14:12:59 +080011556 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11557 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011558
developere40952c2023-06-15 18:46:43 +080011559 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
11560 if (os_snprintf_error(sizeof(cmd), res)) {
11561 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11562 return RETURN_ERR;
11563 }
developera3511852023-06-14 14:12:59 +080011564 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011565
developera3511852023-06-14 14:12:59 +080011566 if((strstr(buf, "OK"))!=NULL)
11567 return RETURN_OK;
11568 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011569}
11570
11571// cancels WPS mode for this AP
11572INT wifi_cancelApWPS(INT apIndex)
11573{
developera3511852023-06-14 14:12:59 +080011574 char interface_name[16] = {0};
11575 char cmd[MAX_CMD_SIZE];
11576 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +080011577 int res;
developer72fb0bb2023-01-11 09:46:29 +080011578
developera3511852023-06-14 14:12:59 +080011579 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11580 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080011581 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
11582 if (os_snprintf_error(sizeof(cmd), res)) {
11583 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11584 return RETURN_ERR;
11585 }
developera3511852023-06-14 14:12:59 +080011586 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011587
developera3511852023-06-14 14:12:59 +080011588 if((strstr(buf, "OK"))!=NULL)
11589 return RETURN_OK;
11590 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011591}
11592
11593//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
11594//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
11595INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
11596{
developera3511852023-06-14 14:12:59 +080011597 char interface_name[16] = {0};
11598 FILE *f = NULL;
11599 int read_flag=0, auth_temp=0, mac_temp=0;
11600 char cmd[256] = {0}, buf[2048] = {0};
11601 char *param = NULL, *value = NULL, *line=NULL;
11602 size_t len = 0;
11603 wifi_associated_dev_t *dev=NULL;
11604 int res;
developer72fb0bb2023-01-11 09:46:29 +080011605
developera3511852023-06-14 14:12:59 +080011606 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11607 *associated_dev_array = NULL;
11608 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11609 return RETURN_ERR;
11610 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
11611 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011612 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11613 return RETURN_ERR;
11614 }
developera3511852023-06-14 14:12:59 +080011615 _syscmd(cmd,buf,sizeof(buf));
11616 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080011617
developera3511852023-06-14 14:12:59 +080011618 if (*output_array_size <= 0)
11619 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011620
developera3511852023-06-14 14:12:59 +080011621 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
11622 *associated_dev_array = dev;
11623 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
11624 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080011625 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11626 return RETURN_ERR;
11627 }
developera3511852023-06-14 14:12:59 +080011628 _syscmd(cmd,buf,sizeof(buf));
11629 f = fopen("/tmp/connected_devices.txt", "r");
11630 if (f==NULL)
11631 {
11632 *output_array_size=0;
11633 return RETURN_ERR;
11634 }
11635 while ((getline(&line, &len, f)) != -1)
11636 {
11637 param = strtok(line,"=");
11638 value = strtok(NULL,"=");
developer72fb0bb2023-01-11 09:46:29 +080011639
developera3511852023-06-14 14:12:59 +080011640 if( strcmp("flags",param) == 0 )
11641 {
11642 value[strlen(value)-1]='\0';
11643 if(strstr (value,"AUTHORIZED") != NULL )
11644 {
11645 dev[auth_temp].cli_AuthenticationState = 1;
11646 dev[auth_temp].cli_Active = 1;
11647 auth_temp++;
11648 read_flag=1;
11649 }
11650 }
11651 if(read_flag==1)
11652 {
11653 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
11654 {
11655 value[strlen(value)-1]='\0';
11656 sscanf(value, "%x:%x:%x:%x:%x:%x",
11657 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
11658 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
11659 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
11660 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
11661 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
11662 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
11663 mac_temp++;
11664 read_flag=0;
11665 }
11666 }
11667 }
11668 *output_array_size = auth_temp;
11669 auth_temp=0;
11670 mac_temp=0;
11671 free(line);
11672 fclose(f);
11673 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11674 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011675}
11676
11677#define MACADDRESS_SIZE 6
11678
11679INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
11680{
developera3511852023-06-14 14:12:59 +080011681 FILE *fp = NULL;
11682 char str[MAX_BUF_SIZE] = {0};
11683 int wificlientindex = 0 ;
11684 int count = 0;
11685 int signalstrength = 0;
11686 int arr[MACADDRESS_SIZE] = {0};
11687 unsigned char mac[MACADDRESS_SIZE] = {0};
11688 UINT wifi_count = 0;
11689 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011690 int res;
developer72fb0bb2023-01-11 09:46:29 +080011691
developera3511852023-06-14 14:12:59 +080011692 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11693 *output_array_size = 0;
11694 *associated_dev_array = NULL;
developer72fb0bb2023-01-11 09:46:29 +080011695
developer32f2a182023-06-27 19:50:41 +080011696 res = snprintf(pipeCmd, sizeof(pipeCmd),
11697 "iw dev %s station dump | grep %s | wc -l", interface_name,
11698 interface_name);
developer75bd10c2023-06-27 11:34:08 +080011699 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11700 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11701 return RETURN_ERR;
11702 }
developera3511852023-06-14 14:12:59 +080011703 fp = popen(pipeCmd, "r");
11704 if (fp == NULL)
11705 {
11706 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11707 return RETURN_ERR;
11708 }
developer72fb0bb2023-01-11 09:46:29 +080011709
developera3511852023-06-14 14:12:59 +080011710 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080011711 if (fgets(str, sizeof(str)-1, fp) == NULL) {
11712 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11713 pclose(fp);
11714 return RETURN_ERR;
11715 }
developera3511852023-06-14 14:12:59 +080011716 wifi_count = (unsigned int) atoi ( str );
11717 *output_array_size = wifi_count;
11718 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11719 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080011720
developera3511852023-06-14 14:12:59 +080011721 if(wifi_count == 0)
11722 {
11723 return RETURN_OK;
11724 }
11725 else
11726 {
11727 wifi_associated_dev3_t* temp = NULL;
developer9ce44382023-06-28 11:09:37 +080011728 if(wifi_count <= 0 || wifi_count > MAX_ASSOCIATED_STA_NUM){
11729 return RETURN_ERR;
11730 }
developera3511852023-06-14 14:12:59 +080011731 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
11732 if(temp == NULL)
11733 {
11734 printf("Error Statement. Insufficient memory \n");
11735 return RETURN_ERR;
11736 }
developer72fb0bb2023-01-11 09:46:29 +080011737
developere40952c2023-06-15 18:46:43 +080011738 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11739 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11740 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080011741 free(temp);
developere40952c2023-06-15 18:46:43 +080011742 return RETURN_ERR;
11743 }
developera3511852023-06-14 14:12:59 +080011744 system(pipeCmd);
11745 memset(pipeCmd,0,sizeof(pipeCmd));
11746 if(apIndex == 0)
developere40952c2023-06-15 18:46:43 +080011747 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 +080011748 else if(apIndex == 1)
developere40952c2023-06-15 18:46:43 +080011749 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
11750 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11751 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080011752 free(temp);
developere40952c2023-06-15 18:46:43 +080011753 return RETURN_ERR;
11754 }
developera3511852023-06-14 14:12:59 +080011755 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080011756
developera3511852023-06-14 14:12:59 +080011757 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11758 if(fp == NULL)
11759 {
11760 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11761 free(temp);
11762 return RETURN_ERR;
11763 }
11764 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080011765
developer86035662023-06-28 19:21:12 +080011766 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11767 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11768 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11769 return RETURN_ERR;
11770 }
11771
developera3511852023-06-14 14:12:59 +080011772 fp = popen(pipeCmd, "r");
11773 if(fp)
11774 {
11775 for(count =0 ; count < wifi_count; count++)
11776 {
developer86035662023-06-28 19:21:12 +080011777 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11778 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11779 pclose(fp);
11780 return RETURN_ERR;
11781 }
developera3511852023-06-14 14:12:59 +080011782 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11783 {
11784 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11785 {
11786 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080011787
developera3511852023-06-14 14:12:59 +080011788 }
11789 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11790 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]);
11791 }
11792 temp[count].cli_AuthenticationState = 1; //TODO
11793 temp[count].cli_Active = 1; //TODO
11794 }
11795 pclose(fp);
11796 }
developer72fb0bb2023-01-11 09:46:29 +080011797
developer86035662023-06-28 19:21:12 +080011798 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11799 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11800 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11801 return RETURN_ERR;
11802 }
11803
developera3511852023-06-14 14:12:59 +080011804 fp = popen(pipeCmd, "r");
11805 if(fp)
11806 {
11807 pclose(fp);
11808 }
11809 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11810 if(fp)
11811 {
11812 for(count =0 ; count < wifi_count ;count++)
11813 {
developer86035662023-06-28 19:21:12 +080011814 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11815 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11816 pclose(fp);
11817 return RETURN_ERR;
11818 }
developera3511852023-06-14 14:12:59 +080011819 signalstrength = atoi(str);
11820 temp[count].cli_SignalStrength = signalstrength;
11821 temp[count].cli_RSSI = signalstrength;
11822 temp[count].cli_SNR = signalstrength + 95;
11823 }
11824 pclose(fp);
11825 }
developer72fb0bb2023-01-11 09:46:29 +080011826
11827
developera3511852023-06-14 14:12:59 +080011828 if((apIndex == 0) || (apIndex == 4))
11829 {
11830 for(count =0 ; count < wifi_count ;count++)
11831 {
developer32f2a182023-06-27 19:50:41 +080011832 memcpy(temp[count].cli_OperatingStandard,"g", 1);
11833 temp[count].cli_OperatingStandard[1] = '\0';
11834 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
11835 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080011836 }
developer72fb0bb2023-01-11 09:46:29 +080011837
developera3511852023-06-14 14:12:59 +080011838 //BytesSent
developer86035662023-06-28 19:21:12 +080011839 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
11840 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11841 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11842 return RETURN_ERR;
11843 }
11844
developera3511852023-06-14 14:12:59 +080011845 fp = popen(pipeCmd, "r");
11846 if(fp)
11847 {
11848 pclose(fp);
11849 }
11850 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
11851 if(fp)
11852 {
11853 for (count = 0; count < wifi_count; count++)
11854 {
developer86035662023-06-28 19:21:12 +080011855 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11856 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11857 pclose(fp);
11858 return RETURN_ERR;
11859 }
developera3511852023-06-14 14:12:59 +080011860 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
11861 }
11862 pclose(fp);
11863 }
developer72fb0bb2023-01-11 09:46:29 +080011864
developera3511852023-06-14 14:12:59 +080011865 //BytesReceived
developer86035662023-06-28 19:21:12 +080011866 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
11867 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11868 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11869 return RETURN_ERR;
11870 }
11871
developera3511852023-06-14 14:12:59 +080011872 fp = popen(pipeCmd, "r");
11873 if (fp)
11874 {
11875 pclose(fp);
11876 }
11877 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
11878 if (fp)
11879 {
11880 for (count = 0; count < wifi_count; count++)
11881 {
developer86035662023-06-28 19:21:12 +080011882 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11883 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11884 pclose(fp);
11885 return RETURN_ERR;
11886 }
developera3511852023-06-14 14:12:59 +080011887 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
11888 }
11889 pclose(fp);
11890 }
developer72fb0bb2023-01-11 09:46:29 +080011891
developera3511852023-06-14 14:12:59 +080011892 //PacketsSent
developer86035662023-06-28 19:21:12 +080011893 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
11894 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11895 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11896 return RETURN_ERR;
11897 }
11898
developera3511852023-06-14 14:12:59 +080011899 fp = popen(pipeCmd, "r");
11900 if (fp)
11901 {
11902 pclose(fp);
11903 }
developer72fb0bb2023-01-11 09:46:29 +080011904
developera3511852023-06-14 14:12:59 +080011905 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
11906 if (fp)
11907 {
11908 for (count = 0; count < wifi_count; count++)
11909 {
developer86035662023-06-28 19:21:12 +080011910 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11911 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11912 pclose(fp);
11913 return RETURN_ERR;
11914 }
developera3511852023-06-14 14:12:59 +080011915 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
11916 }
11917 pclose(fp);
11918 }
developer72fb0bb2023-01-11 09:46:29 +080011919
developera3511852023-06-14 14:12:59 +080011920 //PacketsReceived
developer86035662023-06-28 19:21:12 +080011921 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
11922 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11923 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11924 return RETURN_ERR;
11925 }
11926
developera3511852023-06-14 14:12:59 +080011927 fp = popen(pipeCmd, "r");
11928 if (fp)
11929 {
11930 pclose(fp);
11931 }
11932 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
11933 if (fp)
11934 {
11935 for (count = 0; count < wifi_count; count++)
11936 {
developer86035662023-06-28 19:21:12 +080011937 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11938 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11939 pclose(fp);
11940 return RETURN_ERR;
11941 }
developera3511852023-06-14 14:12:59 +080011942 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
11943 }
11944 pclose(fp);
11945 }
developer72fb0bb2023-01-11 09:46:29 +080011946
developera3511852023-06-14 14:12:59 +080011947 //ErrorsSent
developer86035662023-06-28 19:21:12 +080011948 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
11949 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11950 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11951 return RETURN_ERR;
11952 }
11953
developera3511852023-06-14 14:12:59 +080011954 fp = popen(pipeCmd, "r");
11955 if (fp)
11956 {
11957 pclose(fp);
11958 }
11959 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
11960 if (fp)
11961 {
11962 for (count = 0; count < wifi_count; count++)
11963 {
developer86035662023-06-28 19:21:12 +080011964 if (fgets(str, MAX_BUF_SIZE, fp) == NULL){
11965 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11966 pclose(fp);
11967 return RETURN_ERR;
11968 }
developera3511852023-06-14 14:12:59 +080011969 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
11970 }
11971 pclose(fp);
11972 }
developer72fb0bb2023-01-11 09:46:29 +080011973
developera3511852023-06-14 14:12:59 +080011974 //ErrorsSent
developer86035662023-06-28 19:21:12 +080011975 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
11976 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11977 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11978 return RETURN_ERR;
11979 }
11980
developera3511852023-06-14 14:12:59 +080011981 fp = popen(pipeCmd, "r");
11982 if (fp)
11983 {
11984 pclose(fp);
11985 }
11986 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
11987 if (fp)
11988 {
11989 for (count = 0; count < wifi_count; count++)
11990 {
developer86035662023-06-28 19:21:12 +080011991 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
11992 wifi_debug(DEBUG_ERROR, "fgets fail\n");
11993 pclose(fp);
11994 return RETURN_ERR;
11995 }
developera3511852023-06-14 14:12:59 +080011996 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
11997 }
11998 pclose(fp);
11999 }
developer72fb0bb2023-01-11 09:46:29 +080012000
developera3511852023-06-14 14:12:59 +080012001 //LastDataDownlinkRate
developer86035662023-06-28 19:21:12 +080012002 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
12003 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12004 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12005 return RETURN_ERR;
12006 }
12007
developera3511852023-06-14 14:12:59 +080012008 fp = popen(pipeCmd, "r");
12009 if (fp)
12010 {
12011 pclose(fp);
12012 }
12013 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
12014 if (fp)
12015 {
12016 for (count = 0; count < wifi_count; count++)
12017 {
developer86035662023-06-28 19:21:12 +080012018 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12019 wifi_debug(DEBUG_ERROR, "fgets fail\n");
12020 pclose(fp);
12021 return RETURN_ERR;
12022 }
developera3511852023-06-14 14:12:59 +080012023 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
12024 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
12025 }
12026 pclose(fp);
12027 }
developer72fb0bb2023-01-11 09:46:29 +080012028
developera3511852023-06-14 14:12:59 +080012029 //LastDataUplinkRate
developer86035662023-06-28 19:21:12 +080012030 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
12031 if (os_snprintf_error(sizeof(pipeCmd), res)) {
12032 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12033 return RETURN_ERR;
12034 }
12035
developera3511852023-06-14 14:12:59 +080012036 fp = popen(pipeCmd, "r");
12037 if (fp)
12038 {
12039 pclose(fp);
12040 }
12041 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
12042 if (fp)
12043 {
12044 for (count = 0; count < wifi_count; count++)
12045 {
developer86035662023-06-28 19:21:12 +080012046 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
12047 wifi_debug(DEBUG_ERROR, "fgets fail\n");
12048 pclose(fp);
12049 return RETURN_ERR;
12050 }
developera3511852023-06-14 14:12:59 +080012051 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
12052 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
12053 }
12054 pclose(fp);
12055 }
developer72fb0bb2023-01-11 09:46:29 +080012056
developera3511852023-06-14 14:12:59 +080012057 }
12058 else if ((apIndex == 1) || (apIndex == 5))
12059 {
12060 for (count = 0; count < wifi_count; count++)
12061 {
developer32f2a182023-06-27 19:50:41 +080012062 memcpy(temp[count].cli_OperatingStandard, "a", 1);
12063 temp[count].cli_OperatingStandard[1] = '\0';
12064 memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
12065 temp[count].cli_OperatingChannelBandwidth[5] = '\0';
developera3511852023-06-14 14:12:59 +080012066 temp[count].cli_BytesSent = 0;
12067 temp[count].cli_BytesReceived = 0;
12068 temp[count].cli_LastDataUplinkRate = 0;
12069 temp[count].cli_LastDataDownlinkRate = 0;
12070 temp[count].cli_PacketsSent = 0;
12071 temp[count].cli_PacketsReceived = 0;
12072 temp[count].cli_ErrorsSent = 0;
12073 }
12074 }
developer72fb0bb2023-01-11 09:46:29 +080012075
developera3511852023-06-14 14:12:59 +080012076 for (count = 0; count < wifi_count; count++)
12077 {
12078 temp[count].cli_Retransmissions = 0;
12079 temp[count].cli_DataFramesSentAck = 0;
12080 temp[count].cli_DataFramesSentNoAck = 0;
12081 temp[count].cli_MinRSSI = 0;
12082 temp[count].cli_MaxRSSI = 0;
12083 strncpy(temp[count].cli_InterferenceSources, "", 64);
12084 memset(temp[count].cli_IPAddress, 0, 64);
12085 temp[count].cli_RetransCount = 0;
12086 temp[count].cli_FailedRetransCount = 0;
12087 temp[count].cli_RetryCount = 0;
12088 temp[count].cli_MultipleRetryCount = 0;
12089 }
12090 *associated_dev_array = temp;
12091 }
12092 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12093 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012094}
12095
developer7e4a2a62023-04-06 19:56:03 +080012096int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +080012097{
developera3511852023-06-14 14:12:59 +080012098 char cmd[MAX_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +080012099 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080012100 int res;
developer32f2a182023-06-27 19:50:41 +080012101 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080012102
developera3511852023-06-14 14:12:59 +080012103 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080012104
developere40952c2023-06-15 18:46:43 +080012105 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +080012106 interface_name);
developere40952c2023-06-15 18:46:43 +080012107 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
12108 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12109 return RETURN_ERR;
12110 }
12111
developera3511852023-06-14 14:12:59 +080012112 _syscmd(cmd, buf, MAX_BUF_SIZE);
developer7e4a2a62023-04-06 19:56:03 +080012113
developer32f2a182023-06-27 19:50:41 +080012114 len = strlen(buf);
12115 if (len >= sizeof(buf)) {
12116 wifi_debug(DEBUG_ERROR, "Unexpected buf size\n");
12117 return RETURN_ERR;
12118 }
12119 strncpy(wifi_status, buf, len); /* TBD: check wifi_status mem lenth and replace with strcpy later */
12120 wifi_status[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012121
developera3511852023-06-14 14:12:59 +080012122 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
12123 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012124}
12125
developer72fb0bb2023-01-11 09:46:29 +080012126static const char *get_line_from_str_buf(const char *buf, char *line)
12127{
developera3511852023-06-14 14:12:59 +080012128 int i;
12129 int n = strlen(buf);
developer72fb0bb2023-01-11 09:46:29 +080012130
developera3511852023-06-14 14:12:59 +080012131 for (i = 0; i < n; i++) {
12132 line[i] = buf[i];
12133 if (buf[i] == '\n') {
12134 line[i] = '\0';
12135 return &buf[i + 1];
12136 }
12137 }
developer72fb0bb2023-01-11 09:46:29 +080012138
developera3511852023-06-14 14:12:59 +080012139 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080012140}
12141
12142INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
12143{
developera3511852023-06-14 14:12:59 +080012144 char interface_name[16] = {0};
12145 FILE *f = NULL;
12146 int auth_temp= -1;
12147 char cmd[256] = {0}, buf[2048] = {0};
12148 char *param = NULL, *value = NULL, *line=NULL;
12149 size_t len = 0;
12150 wifi_associated_dev3_t *dev=NULL;
developer75bd10c2023-06-27 11:34:08 +080012151 int res;
developer72fb0bb2023-01-11 09:46:29 +080012152
developera3511852023-06-14 14:12:59 +080012153 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12154 *associated_dev_array = NULL;
12155 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12156 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080012157
12158 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
12159 if (os_snprintf_error(sizeof(cmd), res)) {
12160 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12161 return RETURN_ERR;
12162 }
12163
developera3511852023-06-14 14:12:59 +080012164 _syscmd(cmd, buf, sizeof(buf));
12165 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080012166
developera3511852023-06-14 14:12:59 +080012167 if (*output_array_size <= 0)
12168 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012169
developera3511852023-06-14 14:12:59 +080012170 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
developer86035662023-06-28 19:21:12 +080012171
12172 if (dev == NULL) {
12173 wifi_debug(DEBUG_ERROR, "calloc fail\n");
12174 return RETURN_ERR;
12175 }
developera3511852023-06-14 14:12:59 +080012176 *associated_dev_array = dev;
developer32f2a182023-06-27 19:50:41 +080012177 res = snprintf(cmd, sizeof(cmd),
12178 "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
developer75bd10c2023-06-27 11:34:08 +080012179 if (os_snprintf_error(sizeof(cmd), res)) {
12180 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12181 return RETURN_ERR;
12182 }
12183
developera3511852023-06-14 14:12:59 +080012184 _syscmd(cmd,buf,sizeof(buf));
12185 f = fopen("/tmp/diagnostic3_devices.txt", "r");
12186 if (f == NULL)
12187 {
12188 *output_array_size=0;
12189 return RETURN_ERR;
12190 }
12191 while ((getline(&line, &len, f)) != -1)
12192 {
12193 param = strtok(line, "=");
12194 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +080012195
developera3511852023-06-14 14:12:59 +080012196 if( strcmp("flags",param) == 0 )
12197 {
12198 value[strlen(value)-1]='\0';
12199 if(strstr (value,"AUTHORIZED") != NULL )
12200 {
12201 auth_temp++;
12202 dev[auth_temp].cli_AuthenticationState = 1;
12203 dev[auth_temp].cli_Active = 1;
12204 }
12205 } else if (auth_temp < 0) {
12206 continue;
12207 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
12208 {
12209 value[strlen(value)-1]='\0';
12210 sscanf(value, "%x:%x:%x:%x:%x:%x",
12211 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
12212 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
12213 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
12214 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
12215 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
12216 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
12217 } else if (strcmp("signal", param) == 0) {
12218 value[strlen(value)-1]='\0';
12219 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
12220 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
12221 }
12222 }
developer0d26f2c2023-05-25 19:46:36 +080012223 if (line)
developera3511852023-06-14 14:12:59 +080012224 free(line);
12225 fclose(f);
12226 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12227 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012228}
developer72fb0bb2023-01-11 09:46:29 +080012229
12230/* getIPAddress function */
12231/**
12232* @description Returning IpAddress of the Matched String
12233*
developer69b61b02023-03-07 17:17:44 +080012234* @param
developer72fb0bb2023-01-11 09:46:29 +080012235* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080012236* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080012237* @return The status of the operation
12238* @retval RETURN_OK if successful
12239* @retval RETURN_ERR if any error is detected
12240*
12241*/
12242
12243INT getIPAddress(char *str,char *ipaddr)
12244{
developera3511852023-06-14 14:12:59 +080012245 FILE *fp = NULL;
12246 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
12247 int LeaseTime = 0,ret = 0;
developer32f2a182023-06-27 19:50:41 +080012248 unsigned long len;
12249
developera3511852023-06-14 14:12:59 +080012250 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
12251 {
12252 return RETURN_ERR;
12253 }
developer72fb0bb2023-01-11 09:46:29 +080012254
developera3511852023-06-14 14:12:59 +080012255 while ( fgets(buf, sizeof(buf), fp)!= NULL )
12256 {
12257 /*
12258 Sample:sss
12259 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
12260 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
12261 */
12262 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
12263 &(LeaseTime),
12264 phyAddr,
12265 ipAddr,
12266 hostName
12267 );
12268 if(ret != 4)
12269 continue;
developer32f2a182023-06-27 19:50:41 +080012270 if (strcmp(str,phyAddr) == 0) {
12271 len = strlen(ipAddr);
12272 strncpy(ipaddr, ipAddr, len);
12273 ipaddr[len] = '\0';
12274 }
developera3511852023-06-14 14:12:59 +080012275 }
developer37646972023-06-29 10:58:43 +080012276 if (fclose(fp) == EOF) {
12277 wifi_debug(DEBUG_ERROR, "fclose fail\n");
12278 return RETURN_ERR;
12279 }
developera3511852023-06-14 14:12:59 +080012280 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012281}
12282
12283/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
12284/**
12285* @description Returning Inactive wireless connected clients informations
12286*
developer69b61b02023-03-07 17:17:44 +080012287* @param
developer72fb0bb2023-01-11 09:46:29 +080012288* @filename Holding private_wifi 2g/5g content files
12289* @associated_dev_array Having inactiv wireless clients informations
12290* @output_array_size Returning Inactive wireless counts
12291* @return The status of the operation
12292* @retval RETURN_OK if successful
12293* @retval RETURN_ERR if any error is detected
12294*
12295*/
12296
12297INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
12298{
developera3511852023-06-14 14:12:59 +080012299 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12300 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
12301 FILE *fp = NULL;
12302 int arr[MACADDRESS_SIZE] = {0};
12303 unsigned char mac[MACADDRESS_SIZE] = {0};
12304 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
developer86035662023-06-28 19:21:12 +080012305 int res;
12306
12307 res = snprintf(buf, sizeof(buf), "cat %s | grep Station | sort | uniq | wc -l",filename);
12308 if (os_snprintf_error(sizeof(buf), res)) {
12309 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12310 return RETURN_ERR;
12311 }
developera3511852023-06-14 14:12:59 +080012312 fp = popen(buf,"r");
12313 if(fp == NULL)
12314 return RETURN_ERR;
12315 else
12316 {
developerd14dff12023-06-28 22:47:44 +080012317 if (fgets(path,sizeof(path),fp) == NULL) {
12318 wifi_debug(DEBUG_ERROR, "fgets fail\n");
12319 pclose(fp);
12320 return RETURN_ERR;
12321 }
developera3511852023-06-14 14:12:59 +080012322 maccount = atoi(path);
12323 }
12324 pclose(fp);
12325 *output_array_size = maccount;
12326 wifi_associated_dev3_t* temp = NULL;
developer9ce44382023-06-28 11:09:37 +080012327 if(*output_array_size > 0 && *output_array_size < MAX_ASSOCIATED_STA_NUM){
12328 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
12329 } else {
12330 return RETURN_ERR;
12331 }
developer37646972023-06-29 10:58:43 +080012332
developera3511852023-06-14 14:12:59 +080012333 *associated_dev_array = temp;
12334 if(temp == NULL)
12335 {
12336 printf("Error Statement. Insufficient memory \n");
12337 return RETURN_ERR;
12338 }
12339 memset(buf,0,sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080012340 res = snprintf(buf, sizeof(buf),
12341 "cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
12342 if (os_snprintf_error(sizeof(buf), res)) {
12343 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12344 return RETURN_ERR;
12345 }
developera3511852023-06-14 14:12:59 +080012346 fp = popen(buf,"r");
12347 if (fp == NULL) {
developer37646972023-06-29 10:58:43 +080012348 res = fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
12349 if (res < 0) {
12350 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
12351 }
developera3511852023-06-14 14:12:59 +080012352 return RETURN_ERR;
12353 }
12354 for(count = 0; count < maccount ; count++)
12355 {
developer37646972023-06-29 10:58:43 +080012356 if (fgets(path,sizeof(path),fp) == NULL)
12357 continue;
developera3511852023-06-14 14:12:59 +080012358 for(i = 0; path[i]!='\n';i++)
12359 str[i]=path[i];
12360 str[i]='\0';
12361 getIPAddress(str,ipaddr);
12362 memset(buf,0,sizeof(buf));
12363 if(strlen(ipaddr) > 0)
12364 {
developer32f2a182023-06-27 19:50:41 +080012365 res = snprintf(buf, sizeof(buf), "ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1", ipaddr);
12366 if (os_snprintf_error(sizeof(buf), res)) {
12367 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer37646972023-06-29 10:58:43 +080012368 break;
developer32f2a182023-06-27 19:50:41 +080012369 }
developera3511852023-06-14 14:12:59 +080012370 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
12371 {
12372 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12373 {
12374 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12375 {
12376 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012377
developera3511852023-06-14 14:12:59 +080012378 }
12379 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
developer37646972023-06-29 10:58:43 +080012380 if (fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],
12381 temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2],
12382 temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4],
12383 temp[count].cli_MACAddress[5]) < 0) {
12384 wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
12385 break;
12386 }
developera3511852023-06-14 14:12:59 +080012387 }
12388 temp[count].cli_AuthenticationState = 0; //TODO
12389 temp[count].cli_Active = 0; //TODO
12390 temp[count].cli_SignalStrength = 0;
12391 }
12392 else //Active wireless clients info
12393 {
12394 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12395 {
12396 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12397 {
12398 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012399
developera3511852023-06-14 14:12:59 +080012400 }
12401 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
12402 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]);
12403 }
12404 temp[count].cli_Active = 1;
12405 }
12406 }
12407 memset(ipaddr,0,sizeof(ipaddr));
12408 }
12409 pclose(fp);
12410 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12411 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012412}
12413//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
12414//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
12415//To get Band Steering Capability
12416INT wifi_getBandSteeringCapability(BOOL *support)
12417{
developera3511852023-06-14 14:12:59 +080012418 *support = FALSE;
12419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012420}
12421
12422
12423//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
12424//To get Band Steering enable status
12425INT wifi_getBandSteeringEnable(BOOL *enable)
12426{
developera3511852023-06-14 14:12:59 +080012427 *enable = FALSE;
12428 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012429}
12430
12431//To turn on/off Band steering
12432INT wifi_setBandSteeringEnable(BOOL enable)
12433{
developera3511852023-06-14 14:12:59 +080012434 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012435}
12436
12437//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
12438//To get Band Steering AP group
12439INT wifi_getBandSteeringApGroup(char *output_ApGroup)
12440{
developera3511852023-06-14 14:12:59 +080012441 if (NULL == output_ApGroup)
12442 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012443
developer32f2a182023-06-27 19:50:41 +080012444 memcpy(output_ApGroup, "1,2", 3);
12445 output_ApGroup[3] = '\0';
developera3511852023-06-14 14:12:59 +080012446 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012447}
12448
12449//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
12450//to set and read the band steering BandUtilizationThreshold parameters
12451INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
12452{
developera3511852023-06-14 14:12:59 +080012453 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012454}
12455
12456INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
12457{
developera3511852023-06-14 14:12:59 +080012458 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012459}
12460
12461//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
12462//to set and read the band steering RSSIThreshold parameters
12463INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
12464{
developera3511852023-06-14 14:12:59 +080012465 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012466}
12467
12468INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
12469{
developera3511852023-06-14 14:12:59 +080012470 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012471}
12472
12473
12474//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
12475//to set and read the band steering physical modulation rate threshold parameters
12476INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
12477{
developera3511852023-06-14 14:12:59 +080012478 //If chip is not support, return -1
12479 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012480}
12481
12482INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
12483{
developera3511852023-06-14 14:12:59 +080012484 //If chip is not support, return -1
12485 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012486}
12487
12488//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
12489//to set and read the inactivity time (in seconds) for steering under overload condition
12490INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
12491{
developera3511852023-06-14 14:12:59 +080012492 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012493}
12494
12495INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
12496{
developera3511852023-06-14 14:12:59 +080012497 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012498}
12499
12500//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
12501//to set and read the inactivity time (in seconds) for steering under Idle condition
12502INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
12503{
developera3511852023-06-14 14:12:59 +080012504 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012505}
12506
12507INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
12508{
developera3511852023-06-14 14:12:59 +080012509 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012510}
12511
12512//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
12513//pClientMAC[64]
12514//pSourceSSIDIndex[64]
12515//pDestSSIDIndex[64]
12516//pSteeringReason[256]
12517INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
12518{
developera3511852023-06-14 14:12:59 +080012519 //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
12520 *pSteeringTime=time(NULL);
developerd14dff12023-06-28 22:47:44 +080012521 if (*pSteeringTime < 0) {
12522 wifi_debug(DEBUG_ERROR, "GET time fail\n");
12523 return RETURN_ERR;
12524 }
developera3511852023-06-14 14:12:59 +080012525 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
12526 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012527}
12528
12529INT wifi_ifConfigDown(INT apIndex)
12530{
developera3511852023-06-14 14:12:59 +080012531 INT status = RETURN_OK;
12532 char cmd[64];
developere40952c2023-06-15 18:46:43 +080012533 int res;
developer72fb0bb2023-01-11 09:46:29 +080012534
developere40952c2023-06-15 18:46:43 +080012535 res = snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
12536 if (os_snprintf_error(sizeof(cmd), res)) {
12537 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12538 return RETURN_ERR;
12539 }
developera3511852023-06-14 14:12:59 +080012540 printf("%s: %s\n", __func__, cmd);
12541 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080012542
developera3511852023-06-14 14:12:59 +080012543 return status;
developer72fb0bb2023-01-11 09:46:29 +080012544}
12545
12546INT wifi_ifConfigUp(INT apIndex)
12547{
developera3511852023-06-14 14:12:59 +080012548 char interface_name[16] = {0};
12549 char cmd[128];
12550 char buf[1024];
developere40952c2023-06-15 18:46:43 +080012551 int res;
developer72fb0bb2023-01-11 09:46:29 +080012552
developera3511852023-06-14 14:12:59 +080012553 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12554 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012555 res = snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
12556 if (os_snprintf_error(sizeof(cmd), res)) {
12557 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12558 return RETURN_ERR;
12559 }
developera3511852023-06-14 14:12:59 +080012560 _syscmd(cmd, buf, sizeof(buf));
12561 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012562}
12563
12564//>> Deprecated. Replace with wifi_applyRadioSettings
12565INT wifi_pushBridgeInfo(INT apIndex)
12566{
developerb2977562023-05-24 17:54:12 +080012567 char ip[32] = {0};
12568 char subnet[32] = {0};
12569 char bridge[32] = {0};
12570 char cmd[128] = {0};
12571 char buf[1024] = {0};
developere40952c2023-06-15 18:46:43 +080012572 int res;
developer72fb0bb2023-01-11 09:46:29 +080012573
developerb2977562023-05-24 17:54:12 +080012574 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080012575
developere40952c2023-06-15 18:46:43 +080012576 res = snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
12577 if (os_snprintf_error(sizeof(cmd), res)) {
12578 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12579 return RETURN_ERR;
12580 }
developerb2977562023-05-24 17:54:12 +080012581 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012582
developerb2977562023-05-24 17:54:12 +080012583 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012584}
12585
12586INT wifi_pushChannel(INT radioIndex, UINT channel)
12587{
developera3511852023-06-14 14:12:59 +080012588 char interface_name[16] = {0};
12589 char cmd[128];
12590 char buf[1024];
developere40952c2023-06-15 18:46:43 +080012591 int res;
developer72fb0bb2023-01-11 09:46:29 +080012592
developera3511852023-06-14 14:12:59 +080012593 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12594 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012595 res = snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
12596 if (os_snprintf_error(sizeof(cmd), res)) {
12597 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12598 return RETURN_ERR;
12599 }
developera3511852023-06-14 14:12:59 +080012600 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080012601
developera3511852023-06-14 14:12:59 +080012602 return 0;
developer72fb0bb2023-01-11 09:46:29 +080012603}
12604
12605INT wifi_pushChannelMode(INT radioIndex)
12606{
developera3511852023-06-14 14:12:59 +080012607 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
12608 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012609}
12610
12611INT wifi_pushDefaultValues(INT radioIndex)
12612{
developera3511852023-06-14 14:12:59 +080012613 //Apply Comcast specified default radio settings instantly
12614 //AMPDU=1
12615 //AMPDUFrames=32
12616 //AMPDULim=50000
12617 //txqueuelen=1000
developer72fb0bb2023-01-11 09:46:29 +080012618
developera3511852023-06-14 14:12:59 +080012619 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012620}
12621
12622INT wifi_pushTxChainMask(INT radioIndex)
12623{
developera3511852023-06-14 14:12:59 +080012624 //Apply default TxChainMask instantly
12625 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012626}
12627
12628INT wifi_pushRxChainMask(INT radioIndex)
12629{
developera3511852023-06-14 14:12:59 +080012630 //Apply default RxChainMask instantly
12631 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012632}
12633
12634INT wifi_pushSSID(INT apIndex, CHAR *ssid)
12635{
developer7e4a2a62023-04-06 19:56:03 +080012636 INT status;
developer72fb0bb2023-01-11 09:46:29 +080012637
developer7e4a2a62023-04-06 19:56:03 +080012638 status = wifi_setSSIDName(apIndex, ssid);
12639 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080012640
developer7e4a2a62023-04-06 19:56:03 +080012641 return status;
developer72fb0bb2023-01-11 09:46:29 +080012642}
12643
12644INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
12645{
developera3511852023-06-14 14:12:59 +080012646 int ret;
developerc1aa6532023-06-09 09:37:01 +080012647 ret = wifi_setApSsidAdvertisementEnable(apIndex, enable);
12648
12649 return ret;
developer72fb0bb2023-01-11 09:46:29 +080012650}
12651
12652INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
12653{
developera3511852023-06-14 14:12:59 +080012654 time_t now;
developere82c0ca2023-05-10 16:25:35 +080012655
developerd14dff12023-06-28 22:47:44 +080012656 now = time(NULL);
12657 if (now < 0) {
12658 wifi_debug(DEBUG_ERROR, "GET time fail\n");
12659 return RETURN_ERR;
12660 }
developere82c0ca2023-05-10 16:25:35 +080012661 if (now > radio_up_time[radioIndex])
12662 *output = now - radio_up_time[radioIndex];
12663 else {
12664 *output = 0;
12665 return RETURN_ERR;
12666 }
12667
developera3511852023-06-14 14:12:59 +080012668 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012669}
12670
12671INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
12672{
developera3511852023-06-14 14:12:59 +080012673 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012674}
12675
12676INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
12677{
developera3511852023-06-14 14:12:59 +080012678 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012679}
12680
12681//To-do
12682INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
12683{
developera3511852023-06-14 14:12:59 +080012684 char output[16]={'\0'};
12685 char config_file[MAX_BUF_SIZE] = {0};
12686 int res;
developer72fb0bb2023-01-11 09:46:29 +080012687
developera3511852023-06-14 14:12:59 +080012688 if (!output_string)
12689 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012690
developera3511852023-06-14 14:12:59 +080012691 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12692 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012693 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12694 return RETURN_ERR;
12695 }
developera3511852023-06-14 14:12:59 +080012696 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080012697
developera3511852023-06-14 14:12:59 +080012698 if (strlen(output) == 0)
developere40952c2023-06-15 18:46:43 +080012699 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080012700 else if (strncmp(output, "0", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012701 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080012702 else if (strncmp(output, "1", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012703 res = snprintf(output_string, 64, "Optional");
developera3511852023-06-14 14:12:59 +080012704 else if (strncmp(output, "2", 1) == 0)
developere40952c2023-06-15 18:46:43 +080012705 res = snprintf(output_string, 64, "Required");
developera3511852023-06-14 14:12:59 +080012706 else {
12707 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
12708 return RETURN_ERR;
12709 }
developere40952c2023-06-15 18:46:43 +080012710 if (os_snprintf_error(64, res)) {
12711 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12712 return RETURN_ERR;
12713 }
developer72fb0bb2023-01-11 09:46:29 +080012714
developera3511852023-06-14 14:12:59 +080012715 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
12716 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012717}
12718INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
12719{
developera3511852023-06-14 14:12:59 +080012720 struct params params;
12721 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080012722 int res;
developer72fb0bb2023-01-11 09:46:29 +080012723
developera3511852023-06-14 14:12:59 +080012724 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12725 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
12726 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012727
developera3511852023-06-14 14:12:59 +080012728 params.name = "ieee80211w";
12729 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
12730 params.value = "0";
12731 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
12732 params.value = "1";
12733 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
12734 params.value = "2";
12735 else{
12736 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
12737 return RETURN_ERR;
12738 }
developer75bd10c2023-06-27 11:34:08 +080012739
12740 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12741 if (os_snprintf_error(sizeof(config_file), res)) {
12742 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12743 return RETURN_ERR;
12744 }
12745
developera3511852023-06-14 14:12:59 +080012746 wifi_hostapdWrite(config_file, &params, 1);
12747 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
12748 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012749}
12750INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
12751{
developera3511852023-06-14 14:12:59 +080012752 char output[16]={'\0'};
12753 char config_file[MAX_BUF_SIZE] = {0};
12754 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080012755 int res;
developer72fb0bb2023-01-11 09:46:29 +080012756
developera3511852023-06-14 14:12:59 +080012757 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12758 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080012759 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
12760 if (os_snprintf_error(sizeof(config_file), res)) {
12761 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12762 return RETURN_ERR;
12763 }
developera3511852023-06-14 14:12:59 +080012764 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080012765
developera3511852023-06-14 14:12:59 +080012766 if (strncmp(output, "0", 1) == 0)
12767 *output_bool = FALSE;
12768 else if (strncmp(output, "1", 1) == 0)
12769 *output_bool = TRUE;
12770 else if (strncmp(output, "2", 1) == 0)
12771 *output_bool = TRUE;
12772 else if (strncmp(output, "3", 1) == 0)
12773 *output_bool = TRUE;
12774 else
12775 *output_bool = FALSE;
12776 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012777
developera3511852023-06-14 14:12:59 +080012778 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012779}
12780
12781INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
12782{
developera3511852023-06-14 14:12:59 +080012783 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012784}
12785
12786INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
12787{
developera3511852023-06-14 14:12:59 +080012788 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012789}
12790
12791INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
12792{
developera3511852023-06-14 14:12:59 +080012793 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012794}
12795
12796INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
12797{
developera3511852023-06-14 14:12:59 +080012798 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12799 char config_file[MAX_BUF_SIZE] = {0};
developer32f2a182023-06-27 19:50:41 +080012800 char tmp_output[MAX_BUF_SIZE] = {0};
developera3511852023-06-14 14:12:59 +080012801 int res;
developer72fb0bb2023-01-11 09:46:29 +080012802
developera3511852023-06-14 14:12:59 +080012803 if (NULL == output)
12804 return RETURN_ERR;
12805 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12806 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012807 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12808 return RETURN_ERR;
12809 }
developera3511852023-06-14 14:12:59 +080012810 wifi_hostapdRead(config_file,"hw_mode",output,64);
developer72fb0bb2023-01-11 09:46:29 +080012811
developer32f2a182023-06-27 19:50:41 +080012812 if(strcmp(output,"b")==0) {
12813 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,11");
12814 if (os_snprintf_error(sizeof(tmp_output), res)) {
12815 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12816 return RETURN_ERR;
12817 }
12818 } else if (strcmp(output,"a")==0) {
12819 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "6,9,11,12,18,24,36,48,54");
12820 if (os_snprintf_error(sizeof(tmp_output), res)) {
12821 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12822 return RETURN_ERR;
12823 }
12824 } else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) {
12825 res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
12826 if (os_snprintf_error(sizeof(tmp_output), res)) {
12827 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12828 return RETURN_ERR;
12829 }
developer75bd10c2023-06-27 11:34:08 +080012830 }
developer32f2a182023-06-27 19:50:41 +080012831 memcpy(output, tmp_output, strlen(tmp_output));
12832 output[strlen(tmp_output)] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012833
developera3511852023-06-14 14:12:59 +080012834 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12835 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012836}
12837
12838INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
12839{
developera3511852023-06-14 14:12:59 +080012840 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12841 char *temp;
developer32f2a182023-06-27 19:50:41 +080012842 char temp_output[128] = {0};
12843 char temp_TransmitRates[128] = {0};
developera3511852023-06-14 14:12:59 +080012844 char config_file[MAX_BUF_SIZE] = {0};
12845 int res;
developer32f2a182023-06-27 19:50:41 +080012846 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080012847
developera3511852023-06-14 14:12:59 +080012848 if (NULL == output)
12849 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012850
developera3511852023-06-14 14:12:59 +080012851 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12852 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080012853 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12854 return RETURN_ERR;
12855 }
developera3511852023-06-14 14:12:59 +080012856 wifi_hostapdRead(config_file,"supported_rates",output,64);
developer72fb0bb2023-01-11 09:46:29 +080012857
developera3511852023-06-14 14:12:59 +080012858 if (strlen(output) == 0) {
12859 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
12860 return RETURN_OK;
12861 }
developer32f2a182023-06-27 19:50:41 +080012862 len = strlen(output);
12863 if (len >= sizeof(temp_TransmitRates)) {
12864 wifi_debug(DEBUG_ERROR, "Unexpected strlen(output)\n");
12865 return RETURN_ERR;
12866 }
12867 strncpy(temp_TransmitRates, output, len);
developera3511852023-06-14 14:12:59 +080012868 temp = strtok(temp_TransmitRates," ");
12869 while(temp!=NULL)
12870 {
12871 temp[strlen(temp)-1]=0;
12872 if((temp[0]=='5') && (temp[1]=='\0'))
12873 {
12874 temp="5.5";
12875 }
developer32f2a182023-06-27 19:50:41 +080012876 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp)) {
12877 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12878 return RETURN_ERR;
12879 }
12880 strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012881 temp = strtok(NULL," ");
12882 if(temp!=NULL)
12883 {
developer32f2a182023-06-27 19:50:41 +080012884 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
12885 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12886 return RETURN_ERR;
12887 }
12888 strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012889 }
12890 }
developer32f2a182023-06-27 19:50:41 +080012891 len = strlen(temp_output);
12892 strncpy(output, temp_output, len);
12893 output[len] = '\0';
developera3511852023-06-14 14:12:59 +080012894 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012895
developera3511852023-06-14 14:12:59 +080012896 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012897}
12898
12899INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
12900{
developera3511852023-06-14 14:12:59 +080012901 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012902}
12903
12904
12905INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
12906{
developera3511852023-06-14 14:12:59 +080012907 int i=0;
12908 char *temp;
12909 char temp1[128] = {0};
12910 char temp_output[128] = {0};
12911 char temp_TransmitRates[128] = {0};
12912 struct params params={'\0'};
12913 char config_file[MAX_BUF_SIZE] = {0};
12914 wifi_band band = wifi_index_to_band(wlanIndex);
developer32f2a182023-06-27 19:50:41 +080012915 unsigned long len;
12916 int res;
developer72fb0bb2023-01-11 09:46:29 +080012917
developera3511852023-06-14 14:12:59 +080012918 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12919 if(NULL == output)
12920 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080012921
12922 len = strlen(output);
12923 if (len >= sizeof(temp_TransmitRates)) {
12924 wifi_debug(DEBUG_ERROR, "not enough room in temp_TransmitRates\n");
12925 return RETURN_ERR;
12926 }
12927 strncpy(temp_TransmitRates, output, len);
12928 temp_TransmitRates[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012929
developera3511852023-06-14 14:12:59 +080012930 for(i=0;i<strlen(temp_TransmitRates);i++)
12931 {
12932 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
12933 {
12934 continue;
12935 }
12936 else
12937 {
12938 return RETURN_ERR;
12939 }
12940 }
developera3511852023-06-14 14:12:59 +080012941 temp = strtok(temp_TransmitRates,",");
12942 while(temp!=NULL)
12943 {
developer32f2a182023-06-27 19:50:41 +080012944 len = strlen(temp);
12945 if (len >= sizeof(temp1)) {
12946 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
12947 return RETURN_ERR;
12948 }
12949 strncpy(temp1, temp, len);
12950 temp1[len] = '\0';
developera3511852023-06-14 14:12:59 +080012951 if(band == band_5)
12952 {
12953 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
12954 {
12955 return RETURN_ERR;
12956 }
12957 }
developer72fb0bb2023-01-11 09:46:29 +080012958
developer32f2a182023-06-27 19:50:41 +080012959 if(strcmp(temp,"5.5")==0) {
12960 strncpy(temp1, "55", 2);
12961 temp1[2] = '\0';
12962 } else {
12963 if ((sizeof(temp1) - strlen(temp1)) <= 1) {
12964 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
12965 return RETURN_ERR;
12966 }
12967 strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
developera3511852023-06-14 14:12:59 +080012968 }
developer32f2a182023-06-27 19:50:41 +080012969
12970 if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp1)) {
12971 wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
12972 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080012973 }
developer32f2a182023-06-27 19:50:41 +080012974 strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012975 temp = strtok(NULL,",");
12976 if(temp!=NULL)
12977 {
developer32f2a182023-06-27 19:50:41 +080012978 if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
12979 wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
12980 return RETURN_ERR;
12981 }
12982 strncat(temp_output, " ", sizeof(temp_output) - strlen(temp_output) - 1);
developera3511852023-06-14 14:12:59 +080012983 }
12984 }
developer32f2a182023-06-27 19:50:41 +080012985 len = strlen(temp_output);
12986 strncpy(output, temp_output, len);
12987 output[len] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080012988
developera3511852023-06-14 14:12:59 +080012989 params.name = "supported_rates";
12990 params.value = output;
developer72fb0bb2023-01-11 09:46:29 +080012991
developera3511852023-06-14 14:12:59 +080012992 wifi_dbg_printf("\n%s:",__func__);
12993 wifi_dbg_printf("params.value=%s\n",params.value);
developer32f2a182023-06-27 19:50:41 +080012994 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
12995 if (os_snprintf_error(sizeof(config_file), res)) {
12996 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12997 return RETURN_ERR;
12998 }
developera3511852023-06-14 14:12:59 +080012999 wifi_hostapdWrite(config_file,&params,1);
13000 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013001
developera3511852023-06-14 14:12:59 +080013002 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013003}
13004
13005
13006static char *sncopy(char *dst, int dst_sz, const char *src)
13007{
developera3511852023-06-14 14:12:59 +080013008 if (src && dst && dst_sz > 0) {
13009 strncpy(dst, src, dst_sz);
13010 dst[dst_sz - 1] = '\0';
13011 }
13012 return dst;
developer72fb0bb2023-01-11 09:46:29 +080013013}
13014
13015static int util_get_sec_chan_offset(int channel, const char* ht_mode)
13016{
developera3511852023-06-14 14:12:59 +080013017 if (0 == strcmp(ht_mode, "HT40") ||
13018 0 == strcmp(ht_mode, "HT80") ||
13019 0 == strcmp(ht_mode, "HT160")) {
13020 switch (channel) {
13021 case 1 ... 7:
13022 case 36:
13023 case 44:
13024 case 52:
13025 case 60:
13026 case 100:
13027 case 108:
13028 case 116:
13029 case 124:
13030 case 132:
13031 case 140:
13032 case 149:
13033 case 157:
13034 return 1;
13035 case 8 ... 13:
13036 case 40:
13037 case 48:
13038 case 56:
13039 case 64:
13040 case 104:
13041 case 112:
13042 case 120:
13043 case 128:
13044 case 136:
13045 case 144:
13046 case 153:
13047 case 161:
13048 return -1;
13049 default:
13050 return -EINVAL;
13051 }
13052 }
developer72fb0bb2023-01-11 09:46:29 +080013053
developera3511852023-06-14 14:12:59 +080013054 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080013055}
13056
13057static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
13058{
developera3511852023-06-14 14:12:59 +080013059 int idx = channel%8;
13060 if (0 == strcmp(ht_mode, "HT40") ||
13061 0 == strcmp(ht_mode, "HT80") ||
13062 0 == strcmp(ht_mode, "HT160")) {
13063 switch (idx) {
13064 case 1:
13065 return 1;
13066 case 5:
13067 return -1;
13068 default:
13069 return -EINVAL;
13070 }
13071 }
developer72fb0bb2023-01-11 09:46:29 +080013072
developera3511852023-06-14 14:12:59 +080013073 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080013074}
13075static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
13076{
developera3511852023-06-14 14:12:59 +080013077 if (NULL == hw_mode) return;
developer72fb0bb2023-01-11 09:46:29 +080013078
developera3511852023-06-14 14:12:59 +080013079 if (0 == strcmp(hw_mode, "ac"))
13080 sncopy(bw_mode, bw_mode_len, "ht vht");
developer72fb0bb2023-01-11 09:46:29 +080013081
developera3511852023-06-14 14:12:59 +080013082 if (0 == strcmp(hw_mode, "n"))
13083 sncopy(bw_mode, bw_mode_len, "ht");
developer72fb0bb2023-01-11 09:46:29 +080013084
developera3511852023-06-14 14:12:59 +080013085 return;
developer72fb0bb2023-01-11 09:46:29 +080013086}
13087
13088static int util_chan_to_freq(int chan)
13089{
developera3511852023-06-14 14:12:59 +080013090 if (chan == 14)
13091 return 2484;
13092 else if (chan < 14)
13093 return 2407 + chan * 5;
13094 else if (chan >= 182 && chan <= 196)
13095 return 4000 + chan * 5;
13096 else
13097 return 5000 + chan * 5;
13098 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013099}
13100
13101static int util_6G_chan_to_freq(int chan)
13102{
developera3511852023-06-14 14:12:59 +080013103 if (chan)
13104 return 5950 + chan * 5;
13105 else
13106 return 0;
developer69b61b02023-03-07 17:17:44 +080013107
developer72fb0bb2023-01-11 09:46:29 +080013108}
13109const int *util_unii_5g_chan2list(int chan, int width)
13110{
developera3511852023-06-14 14:12:59 +080013111 static const int lists[] = {
13112 // <width>, <chan1>, <chan2>..., 0,
13113 20, 36, 0,
13114 20, 40, 0,
13115 20, 44, 0,
13116 20, 48, 0,
13117 20, 52, 0,
13118 20, 56, 0,
13119 20, 60, 0,
13120 20, 64, 0,
13121 20, 100, 0,
13122 20, 104, 0,
13123 20, 108, 0,
13124 20, 112, 0,
13125 20, 116, 0,
13126 20, 120, 0,
13127 20, 124, 0,
13128 20, 128, 0,
13129 20, 132, 0,
13130 20, 136, 0,
13131 20, 140, 0,
13132 20, 144, 0,
13133 20, 149, 0,
13134 20, 153, 0,
13135 20, 157, 0,
13136 20, 161, 0,
13137 20, 165, 0,
13138 40, 36, 40, 0,
13139 40, 44, 48, 0,
13140 40, 52, 56, 0,
13141 40, 60, 64, 0,
13142 40, 100, 104, 0,
13143 40, 108, 112, 0,
13144 40, 116, 120, 0,
13145 40, 124, 128, 0,
13146 40, 132, 136, 0,
13147 40, 140, 144, 0,
13148 40, 149, 153, 0,
13149 40, 157, 161, 0,
13150 80, 36, 40, 44, 48, 0,
13151 80, 52, 56, 60, 64, 0,
13152 80, 100, 104, 108, 112, 0,
13153 80, 116, 120, 124, 128, 0,
13154 80, 132, 136, 140, 144, 0,
13155 80, 149, 153, 157, 161, 0,
13156 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
13157 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
13158 -1 // final delimiter
13159 };
13160 const int *start;
13161 const int *p;
developer72fb0bb2023-01-11 09:46:29 +080013162
developera3511852023-06-14 14:12:59 +080013163 for (p = lists; *p != -1; p++) {
13164 if (*p == width) {
13165 for (start = ++p; *p != 0; p++) {
13166 if (*p == chan)
13167 return start;
13168 }
13169 }
13170 // move to the end of channel list of given width
13171 while (*p != 0) {
13172 p++;
13173 }
13174 }
developer72fb0bb2023-01-11 09:46:29 +080013175
developera3511852023-06-14 14:12:59 +080013176 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080013177}
13178
13179static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
13180{
developera3511852023-06-14 14:12:59 +080013181 if (NULL == ht_mode)
13182 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013183
developera3511852023-06-14 14:12:59 +080013184 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
13185 const int *chans = util_unii_5g_chan2list(channel, width);
13186 int sum = 0;
13187 int cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013188
developera3511852023-06-14 14:12:59 +080013189 if (NULL == chans)
13190 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013191
developera3511852023-06-14 14:12:59 +080013192 while (*chans) {
13193 sum += *chans;
13194 cnt++;
13195 chans++;
13196 }
13197 if (cnt == 0)
13198 return 0;
13199 return sum / cnt;
developer72fb0bb2023-01-11 09:46:29 +080013200}
13201
13202static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
13203{
developera3511852023-06-14 14:12:59 +080013204 if (NULL == ht_mode)
13205 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013206
developera3511852023-06-14 14:12:59 +080013207 int width = strtol((ht_mode + 2), NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080013208
developera3511852023-06-14 14:12:59 +080013209 int idx = 0 ;
13210 int centerchan = 0;
13211 int chan_ofs = 1;
developer72fb0bb2023-01-11 09:46:29 +080013212
developera3511852023-06-14 14:12:59 +080013213 if (width == 40){
13214 idx = ((channel/4) + chan_ofs)%2;
13215 switch (idx) {
13216 case 0:
13217 centerchan = (channel - 2);
13218 break;
13219 case 1:
13220 centerchan = (channel + 2);
13221 break;
13222 default:
13223 return -EINVAL;
13224 }
13225 }else if (width == 80){
13226 idx = ((channel/4) + chan_ofs)%4;
13227 switch (idx) {
13228 case 0:
13229 centerchan = (channel - 6);
13230 break;
13231 case 1:
13232 centerchan = (channel + 6);
13233 break;
13234 case 2:
13235 centerchan = (channel + 2);
13236 break;
13237 case 3:
13238 centerchan = (channel - 2);
13239 break;
13240 default:
13241 return -EINVAL;
13242 }
13243 }else if (width == 160){
13244 switch (channel) {
13245 case 1 ... 29:
13246 centerchan = 15;
13247 break;
13248 case 33 ... 61:
13249 centerchan = 47;
13250 break;
13251 case 65 ... 93:
13252 centerchan = 79;
13253 break;
13254 case 97 ... 125:
13255 centerchan = 111;
13256 break;
13257 case 129 ... 157:
13258 centerchan = 143;
13259 break;
13260 case 161 ... 189:
13261 centerchan = 175;
13262 break;
13263 case 193 ... 221:
13264 centerchan = 207;
13265 break;
13266 default:
13267 return -EINVAL;
13268 }
13269 }
13270 return centerchan;
developer72fb0bb2023-01-11 09:46:29 +080013271}
13272static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
13273{
developera3511852023-06-14 14:12:59 +080013274 BOOL onlyG, onlyN, onlyA;
13275 CHAR tmp[64];
13276 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
13277 if (ret == RETURN_OK) {
13278 sncopy(hw_mode, hw_mode_size, tmp);
13279 }
13280 return ret;
developer72fb0bb2023-01-11 09:46:29 +080013281}
13282
13283INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
13284{
developera3511852023-06-14 14:12:59 +080013285 // Sample commands:
13286 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
13287 // hostapd_cli -i wifi0 chan_switch 30 2437
13288 int ret = 0;
13289 char center_freq1_str[32] = ""; // center_freq1=%d
13290 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
13291 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
13292 char hw_mode[16] = ""; // n|ac
13293 char bw_mode[16] = ""; // ht|ht vht
13294 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
13295 char interface_name[16] = {0};
13296 int sec_chan_offset;
13297 int width;
13298 char config_file[64] = {0};
13299 char *ext_str = "None";
13300 wifi_band band = band_invalid;
13301 int center_chan = 0;
13302 int center_freq1 = 0;
developere40952c2023-06-15 18:46:43 +080013303 int res;
developer72fb0bb2023-01-11 09:46:29 +080013304
developere40952c2023-06-15 18:46:43 +080013305 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
13306 if (os_snprintf_error(sizeof(config_file), res)) {
13307 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13308 return RETURN_ERR;
13309 }
developer72fb0bb2023-01-11 09:46:29 +080013310
developera3511852023-06-14 14:12:59 +080013311 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
13312 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013313
developera3511852023-06-14 14:12:59 +080013314 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013315
developera3511852023-06-14 14:12:59 +080013316 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013317
developera3511852023-06-14 14:12:59 +080013318 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
developer72fb0bb2023-01-11 09:46:29 +080013319
developera3511852023-06-14 14:12:59 +080013320 // Get radio mode HT20|HT40|HT80 etc.
13321 if (channel){
developere40952c2023-06-15 18:46:43 +080013322 res = snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
13323 if (os_snprintf_error(sizeof(ht_mode), res)) {
13324 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13325 return RETURN_ERR;
13326 }
developer72fb0bb2023-01-11 09:46:29 +080013327
developera3511852023-06-14 14:12:59 +080013328 // Provide bandwith if specified
13329 if (channel_width_MHz > 20) {
13330 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
13331 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
13332 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
developer72fb0bb2023-01-11 09:46:29 +080013333
developere40952c2023-06-15 18:46:43 +080013334 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
developera3511852023-06-14 14:12:59 +080013335 }else if (channel_width_MHz == 20){
developere40952c2023-06-15 18:46:43 +080013336 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
developera3511852023-06-14 14:12:59 +080013337 }
developer72fb0bb2023-01-11 09:46:29 +080013338
developere40952c2023-06-15 18:46:43 +080013339 if (os_snprintf_error(sizeof(opt_chan_info_str), res)) {
13340 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13341 return RETURN_ERR;
13342 }
developer72fb0bb2023-01-11 09:46:29 +080013343
developera3511852023-06-14 14:12:59 +080013344 if (channel_width_MHz > 20) {
13345 if (band == band_6){
13346 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
13347 if(center_chan){
13348 center_freq1 = util_6G_chan_to_freq(center_chan);
13349 }
13350 }else{
13351 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
13352 if(center_chan){
13353 center_freq1 = util_chan_to_freq(center_chan);
13354 }
13355 }
developer69b61b02023-03-07 17:17:44 +080013356
developera3511852023-06-14 14:12:59 +080013357 if (center_freq1)
developere40952c2023-06-15 18:46:43 +080013358 res = snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080013359
developera3511852023-06-14 14:12:59 +080013360 }
developere40952c2023-06-15 18:46:43 +080013361 if (os_snprintf_error(sizeof(center_freq1_str), res)) {
13362 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13363 return RETURN_ERR;
13364 }
developer72fb0bb2023-01-11 09:46:29 +080013365
developera3511852023-06-14 14:12:59 +080013366 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
13367 if (band == band_6){
13368 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
13369 }else{
13370 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
13371 }
developere40952c2023-06-15 18:46:43 +080013372 if (sec_chan_offset != -EINVAL) {
13373 res = snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
13374 if (os_snprintf_error(sizeof(sec_chan_offset_str), res)) {
13375 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13376 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013377 }
developere40952c2023-06-15 18:46:43 +080013378 }
developera3511852023-06-14 14:12:59 +080013379 // Only the first AP, other are hanging on the same radio
13380 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
13381 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080013382 wifi_debug(DEBUG_ERROR,"wifi_setChannel return error.\n");
developera3511852023-06-14 14:12:59 +080013383 return RETURN_ERR;
13384 }
13385 /* wifi_dbg_printf("execute: '%s'\n", cmd);
13386 ret = _syscmd(cmd, buf, sizeof(buf));
13387 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080013388
developera3511852023-06-14 14:12:59 +080013389 ret = wifi_setRadioChannel(radioIndex, channel);
13390 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080013391 wifi_debug(DEBUG_ERROR,"wifi_setRadioChannel return error.\n");
developera3511852023-06-14 14:12:59 +080013392 return RETURN_ERR;
13393 }
developer72fb0bb2023-01-11 09:46:29 +080013394
developera3511852023-06-14 14:12:59 +080013395 if (sec_chan_offset == 1)
13396 ext_str = "Above";
13397 else if (sec_chan_offset == -1)
13398 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080013399
developera3511852023-06-14 14:12:59 +080013400 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080013401
developera3511852023-06-14 14:12:59 +080013402 } else {
13403 if (channel_width_MHz > 20)
13404 ext_str = "Above";
13405 }
developer72fb0bb2023-01-11 09:46:29 +080013406
developera3511852023-06-14 14:12:59 +080013407 wifi_setRadioExtChannel(radioIndex, ext_str);
developer72fb0bb2023-01-11 09:46:29 +080013408
developera3511852023-06-14 14:12:59 +080013409 char mhz_str[16];
developere40952c2023-06-15 18:46:43 +080013410 res = snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
13411 if (os_snprintf_error(sizeof(mhz_str), res)) {
13412 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13413 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013414 }
developera3511852023-06-14 14:12:59 +080013415 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
developer72fb0bb2023-01-11 09:46:29 +080013416
developera3511852023-06-14 14:12:59 +080013417 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013418
developera3511852023-06-14 14:12:59 +080013419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013420}
13421
13422INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
13423{
developera3511852023-06-14 14:12:59 +080013424 int index = -1;
13425 wifi_neighbor_ap2_t *scan_array = NULL;
13426 char cmd[256]={0};
13427 char buf[128]={0};
13428 char file_name[32] = {0};
13429 char filter_SSID[32] = {0};
13430 char line[256] = {0};
13431 char interface_name[16] = {0};
13432 char *ret = NULL;
13433 int freq=0;
13434 FILE *f = NULL;
developer86035662023-06-28 19:21:12 +080013435 long int channels_num = 0;
developera3511852023-06-14 14:12:59 +080013436 int vht_channel_width = 0;
13437 int get_noise_ret = RETURN_ERR;
13438 bool filter_enable = false;
13439 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
13440 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080013441 int res;
developer32f2a182023-06-27 19:50:41 +080013442 unsigned long len;
developer72fb0bb2023-01-11 09:46:29 +080013443
developera3511852023-06-14 14:12:59 +080013444 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013445
developere40952c2023-06-15 18:46:43 +080013446 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
13447 if (os_snprintf_error(sizeof(file_name), res)) {
13448 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13449 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080013450 }
developera3511852023-06-14 14:12:59 +080013451 f = fopen(file_name, "r");
13452 if (f != NULL) {
developer86035662023-06-28 19:21:12 +080013453 if (fgets(filter_SSID, sizeof(file_name), f) == NULL) {
13454 wifi_debug(DEBUG_ERROR, "fgets fail\n");
developerd14dff12023-06-28 22:47:44 +080013455 fclose(f);
developer86035662023-06-28 19:21:12 +080013456 return RETURN_ERR;
13457 }
developera3511852023-06-14 14:12:59 +080013458 if (strlen(filter_SSID) != 0)
13459 filter_enable = true;
developerd14dff12023-06-28 22:47:44 +080013460 if (fclose(f) != 0) {
13461 wifi_debug(DEBUG_ERROR, "fclose fail\n");
13462 return RETURN_ERR;
13463 }
developera3511852023-06-14 14:12:59 +080013464 }
developer72fb0bb2023-01-11 09:46:29 +080013465
developera3511852023-06-14 14:12:59 +080013466 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
13467 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013468
developera3511852023-06-14 14:12:59 +080013469 phyId = radio_index_to_phy(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013470
developere40952c2023-06-15 18:46:43 +080013471 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
13472 if (os_snprintf_error(sizeof(cmd), res)) {
13473 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13474 return RETURN_ERR;
13475 }
developera3511852023-06-14 14:12:59 +080013476 _syscmd(cmd, buf, sizeof(buf));
developer86035662023-06-28 19:21:12 +080013477 if (hal_strtol(buf, 10, &channels_num) < 0) {
13478 wifi_debug(DEBUG_ERROR, "strtol fail\n");
13479 return RETURN_ERR;
13480 }
developer72fb0bb2023-01-11 09:46:29 +080013481
developer32f2a182023-06-27 19:50:41 +080013482 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 +080013483 // 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 +080013484 if (os_snprintf_error(sizeof(cmd), res)) {
13485 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13486 return RETURN_ERR;
13487 }
13488
developer86035662023-06-28 19:21:12 +080013489 wifi_debug(DEBUG_ERROR, "cmd: %s\n", cmd);
developera3511852023-06-14 14:12:59 +080013490 if ((f = popen(cmd, "r")) == NULL) {
13491 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
13492 return RETURN_ERR;
13493 }
developer69b61b02023-03-07 17:17:44 +080013494
developera3511852023-06-14 14:12:59 +080013495 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
developer86035662023-06-28 19:21:12 +080013496
13497 if (channels_noise_arr == NULL) {
13498 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13499 goto err;
developer9ce44382023-06-28 11:09:37 +080013500 }
developer86035662023-06-28 19:21:12 +080013501 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
13502
developera3511852023-06-14 14:12:59 +080013503 ret = fgets(line, sizeof(line), f);
13504 while (ret != NULL) {
13505 if(strstr(line, "BSS") != NULL) { // new neighbor info
13506 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
13507 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
13508 // 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 +080013509
developera3511852023-06-14 14:12:59 +080013510 if (!filter_BSS) {
13511 index++;
13512 wifi_neighbor_ap2_t *tmp;
13513 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
13514 if (tmp == NULL) { // no more memory to use
13515 index--;
13516 wifi_dbg_printf("%s: realloc failed\n", __func__);
13517 break;
13518 }
13519 scan_array = tmp;
13520 }
13521 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +080013522
developera3511852023-06-14 14:12:59 +080013523 filter_BSS = false;
developer86035662023-06-28 19:21:12 +080013524 if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
13525 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13526 goto err;
13527 }
developerc79e9172023-06-06 19:48:03 +080013528 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +080013529 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +080013530 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +080013531 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +080013532 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +080013533 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
13534 } else if (strstr(line, "freq") != NULL) {
developer86035662023-06-28 19:21:12 +080013535 if (sscanf(line," freq: %d", &freq) != 1) {
13536 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13537 goto err;
13538 }
developera3511852023-06-14 14:12:59 +080013539 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080013540
developera3511852023-06-14 14:12:59 +080013541 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +080013542 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080013543 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +080013544 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080013545 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +080013546 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080013547 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
13548 }
13549 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +080013550 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080013551 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +080013552 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080013553 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +080013554 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080013555 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
13556 }
developer72fb0bb2023-01-11 09:46:29 +080013557
developera3511852023-06-14 14:12:59 +080013558 scan_array[index].ap_Noise = 0;
13559 if (get_noise_ret == RETURN_OK) {
13560 for (int i = 0; i < channels_num; i++) {
13561 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
13562 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
13563 break;
13564 }
13565 }
13566 }
13567 } else if (strstr(line, "beacon interval") != NULL) {
developer86035662023-06-28 19:21:12 +080013568 if (sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
13569 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13570 goto err;
13571 }
developera3511852023-06-14 14:12:59 +080013572 } else if (strstr(line, "signal") != NULL) {
developer86035662023-06-28 19:21:12 +080013573 if (sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
13574 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13575 goto err;
13576 }
developera3511852023-06-14 14:12:59 +080013577 } else if (strstr(line,"SSID") != NULL) {
developer86035662023-06-28 19:21:12 +080013578 if (sscanf(line," SSID: %63s", scan_array[index].ap_SSID) != 1) {
13579 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13580 goto err;
13581 }
developera3511852023-06-14 14:12:59 +080013582 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
13583 filter_BSS = true;
13584 }
13585 } else if (strstr(line, "Supported rates") != NULL) {
13586 char SRate[80] = {0}, *tmp = NULL;
13587 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080013588 len = strlen(line);
13589 if (len >= sizeof(SRate)) {
13590 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013591 goto err;
developer32f2a182023-06-27 19:50:41 +080013592 }
13593 strncpy(SRate, line, len);
developera3511852023-06-14 14:12:59 +080013594 tmp = strtok(SRate, ":");
developer86035662023-06-28 19:21:12 +080013595 if (tmp == NULL)
13596 goto err;
developera3511852023-06-14 14:12:59 +080013597 tmp = strtok(NULL, ":");
developer86035662023-06-28 19:21:12 +080013598 if (tmp == NULL)
13599 goto err;
13600
developer32f2a182023-06-27 19:50:41 +080013601 len = strlen(tmp);
13602 if (len >= sizeof(buf)) {
13603 wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
developer86035662023-06-28 19:21:12 +080013604 goto err;
developer32f2a182023-06-27 19:50:41 +080013605 }
13606 strncpy(buf, tmp, len);
developera3511852023-06-14 14:12:59 +080013607 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +080013608
developera3511852023-06-14 14:12:59 +080013609 tmp = strtok(buf, " \n");
13610 while (tmp != NULL) {
developer32f2a182023-06-27 19:50:41 +080013611 if ((sizeof(SRate) - strlen(SRate)) <= strlen(tmp)) {
13612 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013613 goto err;
developer32f2a182023-06-27 19:50:41 +080013614 }
13615 strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
developera3511852023-06-14 14:12:59 +080013616 if (SRate[strlen(SRate) - 1] == '*') {
13617 SRate[strlen(SRate) - 1] = '\0';
13618 }
developer32f2a182023-06-27 19:50:41 +080013619 if ((sizeof(SRate) - strlen(SRate)) <= 1) {
13620 wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
developer86035662023-06-28 19:21:12 +080013621 goto err;
developer32f2a182023-06-27 19:50:41 +080013622 }
13623 strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
developer72fb0bb2023-01-11 09:46:29 +080013624
developera3511852023-06-14 14:12:59 +080013625 tmp = strtok(NULL, " \n");
13626 }
13627 SRate[strlen(SRate) - 1] = '\0';
developer32f2a182023-06-27 19:50:41 +080013628 len = strlen(SRate);
13629 if (len >= sizeof(scan_array[index].ap_SupportedDataTransferRates)) {
13630 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedDataTransferRates\n");
developer86035662023-06-28 19:21:12 +080013631 goto err;
developer32f2a182023-06-27 19:50:41 +080013632 }
13633 strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, len);
13634 scan_array[index].ap_SupportedDataTransferRates[len] = '\0';
developera3511852023-06-14 14:12:59 +080013635 } else if (strstr(line, "DTIM") != NULL) {
developer86035662023-06-28 19:21:12 +080013636 if (sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod)) != 1) {
13637 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13638 goto err;
13639 }
developera3511852023-06-14 14:12:59 +080013640 } else if (strstr(line, "VHT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013641 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
13642 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013643 goto err;
developer32f2a182023-06-27 19:50:41 +080013644 }
13645 strncat(scan_array[index].ap_SupportedStandards, ",ac",
13646 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13647 memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
13648 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +080013649 } else if (strstr(line, "HT capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013650 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 2) {
13651 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013652 goto err;
developer32f2a182023-06-27 19:50:41 +080013653 }
13654 strncat(scan_array[index].ap_SupportedStandards, ",n",
13655 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13656 memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
13657 scan_array[index].ap_OperatingStandards[1] = '\0';
developera3511852023-06-14 14:12:59 +080013658 } else if (strstr(line, "VHT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080013659 if (fgets(line, sizeof(line), f) == NULL) {
13660 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13661 goto err;
13662 }
13663 if (sscanf(line," * channel width: %d", &vht_channel_width) != 1) {
13664 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13665 goto err;
13666 }
developera3511852023-06-14 14:12:59 +080013667 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +080013668 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +080013669 } else {
developere40952c2023-06-15 18:46:43 +080013670 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +080013671 }
developere40952c2023-06-15 18:46:43 +080013672 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
13673 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080013674 goto err;
developer32f2a182023-06-27 19:50:41 +080013675 }
developere40952c2023-06-15 18:46:43 +080013676
developera3511852023-06-14 14:12:59 +080013677 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
13678 continue;
13679 } else if (strstr(line, "HT operation") != NULL) {
developer86035662023-06-28 19:21:12 +080013680 if (fgets(line, sizeof(line), f) == NULL) {
13681 wifi_debug(DEBUG_ERROR, "fgets fail\n");
13682 goto err;
13683 }
13684 goto err;
13685 if (sscanf(line," * secondary channel offset: %127s", buf) != 1) {
13686 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13687 goto err;
13688 }
developera3511852023-06-14 14:12:59 +080013689 if (!strcmp(buf, "above")) {
13690 //40Mhz +
developere40952c2023-06-15 18:46:43 +080013691 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 +080013692 }
13693 else if (!strcmp(buf, "below")) {
13694 //40Mhz -
developere40952c2023-06-15 18:46:43 +080013695 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 +080013696 } else {
13697 //20Mhz
developere40952c2023-06-15 18:46:43 +080013698 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 +080013699 }
developere40952c2023-06-15 18:46:43 +080013700 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
13701 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer86035662023-06-28 19:21:12 +080013702 goto err;
developer32f2a182023-06-27 19:50:41 +080013703 }
developere40952c2023-06-15 18:46:43 +080013704
developera3511852023-06-14 14:12:59 +080013705 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
13706 continue;
13707 } else if (strstr(line, "HE capabilities") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013708 if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
13709 wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
developer86035662023-06-28 19:21:12 +080013710 goto err;
developer32f2a182023-06-27 19:50:41 +080013711 }
13712 strncat(scan_array[index].ap_SupportedStandards, ",ax",
13713 sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
13714 memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
13715 scan_array[index].ap_OperatingStandards[2] = '\0';
developera3511852023-06-14 14:12:59 +080013716 ret = fgets(line, sizeof(line), f);
13717 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
developer32f2a182023-06-27 19:50:41 +080013718 if (strstr(line, "HE40/2.4GHz") != NULL) {
13719 len = strlen("11AXHE40PLUS");
13720 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
13721 } else {
13722 len = strlen("11AXHE20");
13723 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
13724 }
13725 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080013726 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
13727 if (strstr(line, "HE80/5GHz") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013728 len = strlen("11AXHE80");
13729 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
13730 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
developera3511852023-06-14 14:12:59 +080013731 ret = fgets(line, sizeof(line), f);
13732 } else
13733 continue;
developer32f2a182023-06-27 19:50:41 +080013734 if (strstr(line, "HE160/5GHz") != NULL) {
13735 len = strlen("11AXHE160");
13736 memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
13737 scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
13738 }
developera3511852023-06-14 14:12:59 +080013739 }
13740 continue;
13741 } else if (strstr(line, "WPA") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013742 memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
13743 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080013744 } else if (strstr(line, "RSN") != NULL) {
developer32f2a182023-06-27 19:50:41 +080013745 memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
13746 scan_array[index].ap_SecurityModeEnabled[3] = '\0';
developera3511852023-06-14 14:12:59 +080013747 } else if (strstr(line, "Group cipher") != NULL) {
developer86035662023-06-28 19:21:12 +080013748 if (sscanf(line, " * Group cipher: %63s", scan_array[index].ap_EncryptionMode) != 1) {
13749 wifi_debug(DEBUG_ERROR, "sscanf fail\n");
13750 goto err;
13751 }
developera3511852023-06-14 14:12:59 +080013752 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
developer32f2a182023-06-27 19:50:41 +080013753 memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
13754 scan_array[index].ap_EncryptionMode[3] = '\0';
developera3511852023-06-14 14:12:59 +080013755 }
13756 }
13757 ret = fgets(line, sizeof(line), f);
13758 }
developer72fb0bb2023-01-11 09:46:29 +080013759
developera3511852023-06-14 14:12:59 +080013760 if (!filter_BSS) {
13761 *output_array_size = index + 1;
13762 } else {
13763 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
13764 *output_array_size = index;
13765 }
13766 *neighbor_ap_array = scan_array;
13767 pclose(f);
13768 free(channels_noise_arr);
13769 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13770 return RETURN_OK;
developer86035662023-06-28 19:21:12 +080013771err:
13772 fclose(f);
13773 free(channels_noise_arr);
13774 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013775}
13776
13777INT wifi_getApAssociatedDeviceStats(
developera3511852023-06-14 14:12:59 +080013778 INT apIndex,
13779 mac_address_t *clientMacAddress,
13780 wifi_associated_dev_stats_t *associated_dev_stats,
13781 u64 *handle)
developer72fb0bb2023-01-11 09:46:29 +080013782{
developera3511852023-06-14 14:12:59 +080013783 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
13784 char interface_name[50] = {0};
13785 char cmd[1024] = {0};
13786 char mac_str[18] = {0};
13787 char *key = NULL;
13788 char *val = NULL;
13789 FILE *f = NULL;
13790 char *line = NULL;
13791 size_t len = 0;
developer75bd10c2023-06-27 11:34:08 +080013792 int res;
developer72fb0bb2023-01-11 09:46:29 +080013793
developera3511852023-06-14 14:12:59 +080013794 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
13795 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
13796 return RETURN_ERR;
13797 }
developer72fb0bb2023-01-11 09:46:29 +080013798
developer32f2a182023-06-27 19:50:41 +080013799 res = snprintf(mac_str, sizeof(mac_str), "%x:%x:%x:%x:%x:%x",
13800 (*clientMacAddress)[0], (*clientMacAddress)[1], (*clientMacAddress)[2],
13801 (*clientMacAddress)[3], (*clientMacAddress)[4], (*clientMacAddress)[5]);
developer75bd10c2023-06-27 11:34:08 +080013802 if (os_snprintf_error(sizeof(mac_str), res)) {
13803 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13804 return RETURN_ERR;
13805 }
13806
13807 res = snprintf(cmd, sizeof(cmd), "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
13808 if (os_snprintf_error(sizeof(cmd), res)) {
13809 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13810 return RETURN_ERR;
13811 }
13812
developera3511852023-06-14 14:12:59 +080013813 if((f = popen(cmd, "r")) == NULL) {
13814 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
13815 return RETURN_ERR;
13816 }
developer72fb0bb2023-01-11 09:46:29 +080013817
developera3511852023-06-14 14:12:59 +080013818 while ((getline(&line, &len, f)) != -1) {
13819 key = strtok(line,":");
developer37646972023-06-29 10:58:43 +080013820 if (key == NULL)
13821 continue;
developera3511852023-06-14 14:12:59 +080013822 val = strtok(NULL,":");
developer37646972023-06-29 10:58:43 +080013823 if (val == NULL)
13824 continue;
developer72fb0bb2023-01-11 09:46:29 +080013825
13826 if(!strncmp(key,"rx bytes",8))
developerd14dff12023-06-28 22:47:44 +080013827 if (sscanf(val, "%llu", &dev_stats->cli_rx_bytes) != 1) {
13828 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
developer37646972023-06-29 10:58:43 +080013829 continue;
developerd14dff12023-06-28 22:47:44 +080013830 }
developer72fb0bb2023-01-11 09:46:29 +080013831 if(!strncmp(key,"tx bytes",8))
developerd14dff12023-06-28 22:47:44 +080013832 if (sscanf(val, "%llu", &dev_stats->cli_tx_bytes) != 1) {
13833 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
developer37646972023-06-29 10:58:43 +080013834 continue;
13835 }
13836 if(!strncmp(key,"rx packets",10)) {
13837 if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
13838 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13839 continue;
13840 }
13841 }
13842 if(!strncmp(key,"tx packets",10)) {
13843 if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
13844 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13845 continue;
13846 }
13847 }
13848 if(!strncmp(key,"tx retries",10)) {
13849 if (sscanf(val, "%llu", &dev_stats->cli_tx_retries) == EOF) {
13850 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13851 continue;
13852 }
13853 }
13854 if(!strncmp(key,"tx failed",9)) {
13855 if (sscanf(val, "%llu", &dev_stats->cli_tx_errors) == EOF) {
13856 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13857 continue;
13858 }
13859 }
13860 if(!strncmp(key,"rx drop misc",13)) {
13861 if (sscanf(val, "%llu", &dev_stats->cli_rx_errors) == EOF) {
13862 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13863 continue;
13864 }
developerd14dff12023-06-28 22:47:44 +080013865 }
developera3511852023-06-14 14:12:59 +080013866 if(!strncmp(key,"rx bitrate",10)) {
13867 val = strtok(val, " ");
developer37646972023-06-29 10:58:43 +080013868 if (sscanf(val, "%lf", &dev_stats->cli_rx_rate) == EOF) {
13869 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13870 continue;
13871 }
developera3511852023-06-14 14:12:59 +080013872 }
13873 if(!strncmp(key,"tx bitrate",10)) {
13874 val = strtok(val, " ");
developer37646972023-06-29 10:58:43 +080013875 if (sscanf(val, "%lf", &dev_stats->cli_tx_rate) == EOF) {
13876 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
13877 continue;
13878 }
developera3511852023-06-14 14:12:59 +080013879 }
13880 }
13881 free(line);
13882 pclose(f);
13883 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013884}
13885
13886INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
13887{
developera3511852023-06-14 14:12:59 +080013888 char interface_name[IF_NAME_SIZE] = {0};
13889 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
developere40952c2023-06-15 18:46:43 +080013890 int res;
developer72fb0bb2023-01-11 09:46:29 +080013891
developera3511852023-06-14 14:12:59 +080013892 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080013893
developera3511852023-06-14 14:12:59 +080013894 if (NULL == output_string)
13895 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013896
developera3511852023-06-14 14:12:59 +080013897 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13898 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080013899
developere40952c2023-06-15 18:46:43 +080013900 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
13901 if (os_snprintf_error(sizeof(cmd), res)) {
13902 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13903 return RETURN_ERR;
13904 }
developera3511852023-06-14 14:12:59 +080013905 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080013906
developera3511852023-06-14 14:12:59 +080013907 //size of SSID name restricted to value less than 32 bytes
developere40952c2023-06-15 18:46:43 +080013908 res = snprintf(output_string, 32, "%s", buf);
13909 if (os_snprintf_error(32, res)) {
13910 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13911 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080013912 }
developera3511852023-06-14 14:12:59 +080013913 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013914
developera3511852023-06-14 14:12:59 +080013915 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013916}
13917
13918INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
13919{
developer2edaf012023-05-24 14:24:53 +080013920 char *mac_arry_buf = NULL;
13921 INT policy = -1;
13922 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080013923
developer2edaf012023-05-24 14:24:53 +080013924 mac_arry_buf = malloc(buf_size);
13925 if (!mac_arry_buf) {
13926 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080013927 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080013928 }
13929 memset(mac_arry_buf, 0, buf_size);
13930 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
13931 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
13932 goto err;
13933 }
13934 /*
13935 mtk format to get policy:
13936 "policy=1
13937 00:11:22:33:44:55
13938 00:11:22:33:44:66
13939 "
13940 */
13941 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
13942 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
13943 goto err;
13944 }
13945 if (!(policy >=0 && policy <= 2)){
13946 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
13947 goto err;
13948 }
13949 *output_filterMode = policy;
13950 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
13951 free(mac_arry_buf);
13952 mac_arry_buf = NULL;
13953 return RETURN_OK;
13954err:
13955 free(mac_arry_buf);
13956 mac_arry_buf = NULL;
13957 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
13958 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013959}
13960
developer2edaf012023-05-24 14:24:53 +080013961
developer72fb0bb2023-01-11 09:46:29 +080013962INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
13963{
developera3511852023-06-14 14:12:59 +080013964 FILE *fp = NULL;
13965 char str[MAX_BUF_SIZE] = {0};
13966 int wificlientindex = 0 ;
13967 int count = 0;
13968 int signalstrength = 0;
13969 int arr[MACADDRESS_SIZE] = {0};
13970 unsigned char mac[MACADDRESS_SIZE] = {0};
13971 UINT wifi_count = 0;
13972 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080013973 int res;
developer72fb0bb2023-01-11 09:46:29 +080013974
developera3511852023-06-14 14:12:59 +080013975 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13976 *output_array_size = 0;
13977 *associated_dev_array = NULL;
13978 char interface_name[50] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013979
developera3511852023-06-14 14:12:59 +080013980 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
13981 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
13982 return RETURN_ERR;
13983 }
developer72fb0bb2023-01-11 09:46:29 +080013984
developer75bd10c2023-06-27 11:34:08 +080013985 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
13986 if (os_snprintf_error(sizeof(pipeCmd), res)) {
13987 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13988 return RETURN_ERR;
13989 }
developera3511852023-06-14 14:12:59 +080013990 fp = popen(pipeCmd, "r");
13991 if (fp == NULL)
13992 {
13993 printf("Failed to run command inside function %s\n",__FUNCTION__ );
13994 return RETURN_ERR;
13995 }
developer72fb0bb2023-01-11 09:46:29 +080013996
developera3511852023-06-14 14:12:59 +080013997 /* Read the output a line at a time - output it. */
developer86035662023-06-28 19:21:12 +080013998 if (fgets(str, sizeof(str)-1, fp) == NULL) {
13999 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14000 pclose(fp);
14001 return RETURN_ERR;
14002 }
developera3511852023-06-14 14:12:59 +080014003 wifi_count = (unsigned int) atoi ( str );
14004 *output_array_size = wifi_count;
14005 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
14006 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014007
developera3511852023-06-14 14:12:59 +080014008 if(wifi_count == 0)
14009 {
14010 return RETURN_OK;
14011 }
14012 else
14013 {
14014 wifi_associated_dev2_t* temp = NULL;
14015 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
14016 *associated_dev_array = temp;
14017 if(temp == NULL)
14018 {
14019 printf("Error Statement. Insufficient memory \n");
14020 return RETURN_ERR;
14021 }
developer72fb0bb2023-01-11 09:46:29 +080014022
developere40952c2023-06-15 18:46:43 +080014023 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
14024 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14025 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14026 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014027 }
developere40952c2023-06-15 18:46:43 +080014028
developera3511852023-06-14 14:12:59 +080014029 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080014030
developera3511852023-06-14 14:12:59 +080014031 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
14032 if(fp == NULL)
14033 {
14034 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
14035 return RETURN_ERR;
14036 }
14037 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014038
developer86035662023-06-28 19:21:12 +080014039 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
14040 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14041 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14042 return RETURN_ERR;
14043 }
developera3511852023-06-14 14:12:59 +080014044 fp = popen(pipeCmd, "r");
14045 if(fp)
14046 {
14047 for(count =0 ; count < wifi_count; count++)
14048 {
developer86035662023-06-28 19:21:12 +080014049 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14050 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14051 pclose(fp);
14052 return RETURN_ERR;
14053 }
developera3511852023-06-14 14:12:59 +080014054 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
14055 {
14056 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
14057 {
14058 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080014059
developera3511852023-06-14 14:12:59 +080014060 }
14061 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
14062 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]);
14063 }
14064 temp[count].cli_AuthenticationState = 1; //TODO
14065 temp[count].cli_Active = 1; //TODO
14066 }
14067 pclose(fp);
14068 }
developer72fb0bb2023-01-11 09:46:29 +080014069
developera3511852023-06-14 14:12:59 +080014070 //Updating RSSI per client
developer86035662023-06-28 19:21:12 +080014071 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
14072 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14073 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14074 return RETURN_ERR;
14075 }
14076
developera3511852023-06-14 14:12:59 +080014077 fp = popen(pipeCmd, "r");
14078 if(fp)
14079 {
14080 pclose(fp);
14081 }
14082 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
14083 if(fp)
14084 {
14085 for(count =0 ; count < wifi_count ;count++)
14086 {
developer86035662023-06-28 19:21:12 +080014087 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14088 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14089 pclose(fp);
14090 return RETURN_ERR;
14091 }
developera3511852023-06-14 14:12:59 +080014092 signalstrength = atoi(str);
14093 temp[count].cli_RSSI = signalstrength;
14094 }
14095 pclose(fp);
14096 }
developer72fb0bb2023-01-11 09:46:29 +080014097
14098
developera3511852023-06-14 14:12:59 +080014099 //LastDataDownlinkRate
developer86035662023-06-28 19:21:12 +080014100 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
14101 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14102 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14103 return RETURN_ERR;
14104 }
developera3511852023-06-14 14:12:59 +080014105 fp = popen(pipeCmd, "r");
14106 if (fp)
14107 {
14108 pclose(fp);
14109 }
14110 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
14111 if (fp)
14112 {
14113 for (count = 0; count < wifi_count; count++)
14114 {
developer86035662023-06-28 19:21:12 +080014115 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14116 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14117 pclose(fp);
14118 return RETURN_ERR;
14119 }
developera3511852023-06-14 14:12:59 +080014120 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
14121 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
14122 }
14123 pclose(fp);
14124 }
developer72fb0bb2023-01-11 09:46:29 +080014125
developera3511852023-06-14 14:12:59 +080014126 //LastDataUplinkRate
developer86035662023-06-28 19:21:12 +080014127 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
14128 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14129 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14130 return RETURN_ERR;
14131 }
developera3511852023-06-14 14:12:59 +080014132 fp = popen(pipeCmd, "r");
14133 if (fp)
14134 {
14135 pclose(fp);
14136 }
14137 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
14138 if (fp)
14139 {
14140 for (count = 0; count < wifi_count; count++)
14141 {
developer86035662023-06-28 19:21:12 +080014142 if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
14143 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14144 pclose(fp);
14145 return RETURN_ERR;
14146 }
developera3511852023-06-14 14:12:59 +080014147 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
14148 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
14149 }
14150 pclose(fp);
14151 }
14152 }
14153 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14154 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014155
14156}
14157
14158INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
14159{
developera3511852023-06-14 14:12:59 +080014160 FILE *fp = NULL;
14161 char interface_name[50] = {0};
14162 char pipeCmd[128] = {0};
14163 char str[256] = {0};
14164 wifi_ssidTrafficStats2_t *out = output_struct;
developer75bd10c2023-06-27 11:34:08 +080014165 int res;
developerd14dff12023-06-28 22:47:44 +080014166 unsigned int recv;
developer72fb0bb2023-01-11 09:46:29 +080014167
developera3511852023-06-14 14:12:59 +080014168 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
14169 if (!output_struct)
14170 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014171
developera3511852023-06-14 14:12:59 +080014172 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
14173 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
14174 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080014175 res = snprintf(pipeCmd, sizeof(pipeCmd), "cat /proc/net/dev | grep %s", interface_name);
14176 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14177 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14178 return RETURN_ERR;
14179 }
developer72fb0bb2023-01-11 09:46:29 +080014180
developera3511852023-06-14 14:12:59 +080014181 fp = popen(pipeCmd, "r");
14182 if (fp == NULL) {
developer86035662023-06-28 19:21:12 +080014183 wifi_debug(DEBUG_ERROR, "%s: popen failed\n", __func__);
14184 return RETURN_ERR;
14185 }
14186 if (fgets(str, sizeof(str), fp) == NULL) {
14187 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14188 pclose(fp);
developera3511852023-06-14 14:12:59 +080014189 return RETURN_ERR;
14190 }
developer86035662023-06-28 19:21:12 +080014191
developera3511852023-06-14 14:12:59 +080014192 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014193
developera3511852023-06-14 14:12:59 +080014194 if (strlen(str) == 0) // interface not exist
14195 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014196
developerd14dff12023-06-28 22:47:44 +080014197 recv = sscanf(str, "%*[^:]: %lu %lu %lu %lu %*d %*d %*d %*d %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
developera3511852023-06-14 14:12:59 +080014198 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
developerd14dff12023-06-28 22:47:44 +080014199 if (recv != 8) {
14200 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
14201 return RETURN_ERR;
14202 }
developer72fb0bb2023-01-11 09:46:29 +080014203
developera3511852023-06-14 14:12:59 +080014204 memset(str, 0, sizeof(str));
developer75bd10c2023-06-27 11:34:08 +080014205
14206 res = snprintf(pipeCmd, sizeof(pipeCmd), "tail -n1 /proc/net/netstat");
14207 if (os_snprintf_error(sizeof(pipeCmd), res)) {
14208 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14209 return RETURN_ERR;
14210 }
developera3511852023-06-14 14:12:59 +080014211 fp = popen(pipeCmd, "r");
14212 if (fp == NULL) {
developer75bd10c2023-06-27 11:34:08 +080014213 wifi_debug(DEBUG_ERROR, "popen failed\n");
developera3511852023-06-14 14:12:59 +080014214 return RETURN_ERR;
14215 }
developer86035662023-06-28 19:21:12 +080014216
14217 if (fgets(str, sizeof(str), fp) == NULL) {
14218 wifi_debug(DEBUG_ERROR, "fgets fail\n");
14219 pclose(fp);
14220 return RETURN_ERR;
14221 }
developer72fb0bb2023-01-11 09:46:29 +080014222
developer37646972023-06-29 10:58:43 +080014223 if (sscanf(str, "%*[^:]: %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
14224 &out->ssid_BroadcastPacketsSent) == EOF)
14225 wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
developera3511852023-06-14 14:12:59 +080014226 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080014227
developera3511852023-06-14 14:12:59 +080014228 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
14229 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +080014230
developera3511852023-06-14 14:12:59 +080014231 // Not supported
14232 output_struct->ssid_RetransCount = 0;
14233 output_struct->ssid_FailedRetransCount = 0;
14234 output_struct->ssid_RetryCount = 0;
14235 output_struct->ssid_MultipleRetryCount = 0;
14236 output_struct->ssid_ACKFailureCount = 0;
14237 output_struct->ssid_AggregatedPacketCount = 0;
developer72fb0bb2023-01-11 09:46:29 +080014238
developera3511852023-06-14 14:12:59 +080014239 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014240}
14241
14242//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).
14243INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
14244{
developera3511852023-06-14 14:12:59 +080014245 char output_val[16]={'\0'};
14246 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080014247 int res;
developer72fb0bb2023-01-11 09:46:29 +080014248
developera3511852023-06-14 14:12:59 +080014249 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14250 if (!output)
14251 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080014252
14253 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14254 if (os_snprintf_error(sizeof(config_file), res)) {
14255 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14256 return RETURN_ERR;
14257 }
developera3511852023-06-14 14:12:59 +080014258 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
developer72fb0bb2023-01-11 09:46:29 +080014259
developera3511852023-06-14 14:12:59 +080014260 if( strcmp(output_val,"1") == 0 )
14261 *output = TRUE;
14262 else
14263 *output = FALSE;
14264 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014265
developera3511852023-06-14 14:12:59 +080014266 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014267}
14268
14269INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
14270{
developera3511852023-06-14 14:12:59 +080014271 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14272 char string[MAX_BUF_SIZE]={'\0'};
14273 char config_file[MAX_BUF_SIZE] = {0};
14274 struct params params;
developer75bd10c2023-06-27 11:34:08 +080014275 int res;
developer72fb0bb2023-01-11 09:46:29 +080014276
developer32f2a182023-06-27 19:50:41 +080014277 string[0] = enable == TRUE ? '1' : '0';
developer72fb0bb2023-01-11 09:46:29 +080014278
developera3511852023-06-14 14:12:59 +080014279 params.name = "ap_isolate";
14280 params.value = string;
developer72fb0bb2023-01-11 09:46:29 +080014281
developer75bd10c2023-06-27 11:34:08 +080014282 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
14283 if (os_snprintf_error(sizeof(config_file), res)) {
14284 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14285 return RETURN_ERR;
14286 }
14287
developera3511852023-06-14 14:12:59 +080014288 wifi_hostapdWrite(config_file,&params,1);
14289 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014290
developera3511852023-06-14 14:12:59 +080014291 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014292}
14293
14294INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
14295{
developera3511852023-06-14 14:12:59 +080014296 char mgmtpwr_file[32] = {0};
14297 char cmd[64] = {0};
14298 char buf[32]={0};
developere40952c2023-06-15 18:46:43 +080014299 int res;
developera1255e42023-05-13 17:45:02 +080014300
developera3511852023-06-14 14:12:59 +080014301 if (NULL == output_dBm)
14302 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080014303 res = snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
14304 if (os_snprintf_error(sizeof(mgmtpwr_file), res)) {
14305 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14306 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014307 }
developere40952c2023-06-15 18:46:43 +080014308
14309 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
14310 if (os_snprintf_error(sizeof(cmd), res)) {
14311 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14312 return RETURN_ERR;
14313 }
developera3511852023-06-14 14:12:59 +080014314 _syscmd(cmd, buf, sizeof(buf));
developerd14dff12023-06-28 22:47:44 +080014315 if (strlen(buf) > 0) {
developera3511852023-06-14 14:12:59 +080014316 *output_dBm = strtol(buf, NULL, 10);
developerd14dff12023-06-28 22:47:44 +080014317 if (*output_dBm == 0 && buf[0] != '0') {
14318 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
14319 return RETURN_ERR;
14320 }
14321 } else
developera1255e42023-05-13 17:45:02 +080014322 *output_dBm = 23;
developera3511852023-06-14 14:12:59 +080014323 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014324}
14325
14326INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
14327{
developera1255e42023-05-13 17:45:02 +080014328 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080014329 char mgmt_pwr_file[128]={0};
14330 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080014331 int if_idx, ret = 0;
14332 struct nl_msg *msg = NULL;
14333 struct nlattr * msg_data = NULL;
14334 struct mtk_nl80211_param param;
14335 struct unl unl_ins;
14336 char power[16] = {0};
developere40952c2023-06-15 18:46:43 +080014337 int res;
developera1255e42023-05-13 17:45:02 +080014338
14339 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14340
14341 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
14342 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080014343
14344 if_idx = if_nametoindex(interface_name);
14345 /*init mtk nl80211 vendor cmd*/
14346 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
14347 param.if_type = NL80211_ATTR_IFINDEX;
14348 param.if_idx = if_idx;
14349
14350 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
14351 if (ret) {
14352 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
14353 return RETURN_ERR;
14354 }
14355
14356 /*add mtk vendor cmd data*/
developere40952c2023-06-15 18:46:43 +080014357 res = snprintf(power, sizeof(power), "%d", dBm);
14358 if (os_snprintf_error(sizeof(power), res)) {
14359 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14360 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014361 }
developere40952c2023-06-15 18:46:43 +080014362
developerfead3972023-05-25 20:15:02 +080014363 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
14364 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
14365 nlmsg_free(msg);
14366 goto err;
14367 }
14368
14369 /*send mtk nl80211 vendor msg*/
14370 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
14371 if (ret) {
14372 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
14373 goto err;
14374 }
14375
14376 /*deinit mtk nl80211 vendor msg*/
14377 mtk_nl80211_deint(&unl_ins);
14378 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
14379
developere40952c2023-06-15 18:46:43 +080014380 res = snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
14381 if (os_snprintf_error(sizeof(mgmt_pwr_file), res)) {
14382 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14383 return RETURN_ERR;
developerb758dfd2023-06-21 17:32:07 +080014384 }
developere40952c2023-06-15 18:46:43 +080014385
developera1255e42023-05-13 17:45:02 +080014386 f = fopen(mgmt_pwr_file, "w");
14387 if (f == NULL) {
14388 fprintf(stderr, "%s: fopen failed\n", __func__);
14389 return RETURN_ERR;
14390 }
14391 fprintf(f, "%d", dBm);
14392 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080014393 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080014394err:
14395 mtk_nl80211_deint(&unl_ins);
14396 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
14397 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014398}
14399INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
14400{
developera3511852023-06-14 14:12:59 +080014401 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014402}
14403INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
14404{
developera3511852023-06-14 14:12:59 +080014405 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014406}
14407INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
14408{
developera3511852023-06-14 14:12:59 +080014409 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014410}
14411INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
14412{
developera3511852023-06-14 14:12:59 +080014413 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014414}
14415INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
14416{
developera3511852023-06-14 14:12:59 +080014417 char config_file[MAX_BUF_SIZE] = {0};
14418 struct params list;
developere40952c2023-06-15 18:46:43 +080014419 int res;
developer72fb0bb2023-01-11 09:46:29 +080014420
developera3511852023-06-14 14:12:59 +080014421 list.name = "bss_transition";
14422 list.value = activate?"1":"0";
developere40952c2023-06-15 18:46:43 +080014423 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
14424 if (os_snprintf_error(sizeof(config_file), res)) {
14425 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14426 return RETURN_ERR;
14427 }
developera3511852023-06-14 14:12:59 +080014428 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080014429
developera3511852023-06-14 14:12:59 +080014430 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014431}
14432wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
14433
14434void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
14435{
developera3511852023-06-14 14:12:59 +080014436 return;
developer72fb0bb2023-01-11 09:46:29 +080014437}
14438
14439INT wifi_setApCsaDeauth(INT apIndex, INT mode)
14440{
developera3511852023-06-14 14:12:59 +080014441 // TODO Implement me!
14442 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014443}
14444
14445INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
14446{
developera3511852023-06-14 14:12:59 +080014447 char file_name[128] = {0};
14448 FILE *f = NULL;
14449 int max_num_radios = 0;
developer75bd10c2023-06-27 11:34:08 +080014450 int res, ret;
developer72fb0bb2023-01-11 09:46:29 +080014451
developera3511852023-06-14 14:12:59 +080014452 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014453
developera3511852023-06-14 14:12:59 +080014454 wifi_getMaxRadioNumber(&max_num_radios);
14455 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
14456 for (int index = 0; index < max_num_radios; index++) {
developere40952c2023-06-15 18:46:43 +080014457 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
14458 if (os_snprintf_error(sizeof(file_name), res)) {
14459 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14460 return RETURN_ERR;
14461 }
14462
developera3511852023-06-14 14:12:59 +080014463 f = fopen(file_name, "w");
14464 if (f == NULL)
14465 return RETURN_ERR;
14466 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080014467 if (mode) {
14468 ret = fprintf(f, "%s", essid);
14469 if (ret < 0)
14470 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
14471 }
developer72fb0bb2023-01-11 09:46:29 +080014472
developerd14dff12023-06-28 22:47:44 +080014473 if (fclose(f) != 0) {
14474 wifi_debug(DEBUG_ERROR, "fclose fail\n");
14475 return RETURN_ERR;
14476 }
developera3511852023-06-14 14:12:59 +080014477 }
14478 } else { // special case, need to set AP's SSID as filter for each radio.
developere40952c2023-06-15 18:46:43 +080014479 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
14480 if (os_snprintf_error(sizeof(file_name), res)) {
14481 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14482 return RETURN_ERR;
14483 }
14484
developera3511852023-06-14 14:12:59 +080014485 f = fopen(file_name, "w");
14486 if (f == NULL)
14487 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014488
developera3511852023-06-14 14:12:59 +080014489 // For mode == 0 is to disable filter, just don't write to the file.
developer75bd10c2023-06-27 11:34:08 +080014490 if (mode) {
14491 ret = fprintf(f, "%s", essid);
14492 if (ret < 0)
14493 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
14494 }
developer72fb0bb2023-01-11 09:46:29 +080014495
developer37646972023-06-29 10:58:43 +080014496 if (fclose(f) == EOF) {
14497 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
14498 return RETURN_ERR;
14499 }
developera3511852023-06-14 14:12:59 +080014500 }
developer72fb0bb2023-01-11 09:46:29 +080014501
developera3511852023-06-14 14:12:59 +080014502 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14503 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014504}
14505
14506INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
14507{
developera3511852023-06-14 14:12:59 +080014508 // TODO Implement me!
14509 //Apply wifi_pushRadioChannel() instantly
14510 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014511}
14512
14513INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
14514{
developera3511852023-06-14 14:12:59 +080014515 // TODO Implement me!
14516 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014517}
14518
developer72fb0bb2023-01-11 09:46:29 +080014519
developera3511852023-06-14 14:12:59 +080014520static int tidStats_callback(struct nl_msg *msg, void *arg) {
14521 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14522 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14523 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14524 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
14525 int rem , tid_index = 0;
developer72fb0bb2023-01-11 09:46:29 +080014526
developera3511852023-06-14 14:12:59 +080014527 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
14528 wifi_associated_dev_tid_entry_t *stats_entry;
developer72fb0bb2023-01-11 09:46:29 +080014529
developera3511852023-06-14 14:12:59 +080014530 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
14531 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
14532 };
14533 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
14534 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
14535 };
developer72fb0bb2023-01-11 09:46:29 +080014536
developera3511852023-06-14 14:12:59 +080014537 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
14538 genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080014539
developer72fb0bb2023-01-11 09:46:29 +080014540
developera3511852023-06-14 14:12:59 +080014541 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014542 wifi_debug(DEBUG_ERROR, "station stats missing!\n");
developera3511852023-06-14 14:12:59 +080014543 return NL_SKIP;
14544 }
developer72fb0bb2023-01-11 09:46:29 +080014545
developera3511852023-06-14 14:12:59 +080014546 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
14547 tb[NL80211_ATTR_STA_INFO],
14548 stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014549 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014550 return NL_SKIP;
14551 }
developer72fb0bb2023-01-11 09:46:29 +080014552
developera3511852023-06-14 14:12:59 +080014553 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14554 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
14555 {
14556 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080014557
developera3511852023-06-14 14:12:59 +080014558 stats_entry->tid = tid_index;
14559 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080014560
developera3511852023-06-14 14:12:59 +080014561 if(sinfo[NL80211_STA_INFO_TID_STATS])
14562 {
14563 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
14564 printf("failed to parse nested stats attributes!");
14565 return NL_SKIP;
14566 }
14567 }
14568 if(stats_info[NL80211_TID_STATS_TX_MSDU])
14569 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080014570
developera3511852023-06-14 14:12:59 +080014571 if(tid_index < (PS_MAX_TID - 1))
14572 tid_index++;
14573 }
14574 }
14575 //ToDo: sum_time_ms, ewma_time_ms
14576 return NL_SKIP;
14577}
developer72fb0bb2023-01-11 09:46:29 +080014578
developera3511852023-06-14 14:12:59 +080014579INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
14580{
14581 Netlink nl;
14582 char if_name[IF_NAME_SIZE];
14583 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014584 int res;
developer72fb0bb2023-01-11 09:46:29 +080014585
developera3511852023-06-14 14:12:59 +080014586 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
14587 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014588
developere40952c2023-06-15 18:46:43 +080014589 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
14590 if (os_snprintf_error(sizeof(if_name), res)) {
14591 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14592 return RETURN_ERR;
14593 }
developer72fb0bb2023-01-11 09:46:29 +080014594
developera3511852023-06-14 14:12:59 +080014595 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014596
developera3511852023-06-14 14:12:59 +080014597 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080014598 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080014599 return -1;
14600 }
developer72fb0bb2023-01-11 09:46:29 +080014601
developera3511852023-06-14 14:12:59 +080014602 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014603
developera3511852023-06-14 14:12:59 +080014604 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080014605 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080014606 nlfree(&nl);
14607 return -2;
14608 }
developer72fb0bb2023-01-11 09:46:29 +080014609
developera3511852023-06-14 14:12:59 +080014610 genlmsg_put(msg,
14611 NL_AUTO_PID,
14612 NL_AUTO_SEQ,
14613 nl.id,
14614 0,
14615 0,
14616 NL80211_CMD_GET_STATION,
14617 0);
developer72fb0bb2023-01-11 09:46:29 +080014618
developera3511852023-06-14 14:12:59 +080014619 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
14620 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14621 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
14622 nl_send_auto_complete(nl.socket, msg);
14623 nl_recvmsgs(nl.socket, nl.cb);
14624 nlmsg_free(msg);
14625 nlfree(&nl);
14626 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014627}
14628
14629
14630INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
14631{
developera3511852023-06-14 14:12:59 +080014632 char interface_name[16] = {0};
14633 char cmd[128]={0};
14634 char buf[128]={0};
14635 int freq = 0;
developere40952c2023-06-15 18:46:43 +080014636 int res;
developer72fb0bb2023-01-11 09:46:29 +080014637
developera3511852023-06-14 14:12:59 +080014638 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014639
developera3511852023-06-14 14:12:59 +080014640 // full mode is used to scan all channels.
14641 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
14642 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
14643 ieee80211_channel_to_frequency(chan_list[0], &freq);
developer72fb0bb2023-01-11 09:46:29 +080014644
developera3511852023-06-14 14:12:59 +080014645 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14646 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014647
developera3511852023-06-14 14:12:59 +080014648 if (freq)
developere40952c2023-06-15 18:46:43 +080014649 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 +080014650 else
developere40952c2023-06-15 18:46:43 +080014651 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
14652 if (os_snprintf_error(sizeof(cmd), res)) {
14653 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14654 return RETURN_ERR;
14655 }
developer72fb0bb2023-01-11 09:46:29 +080014656
developera3511852023-06-14 14:12:59 +080014657 _syscmd(cmd, buf, sizeof(buf));
14658 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014659
developera3511852023-06-14 14:12:59 +080014660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014661}
14662
14663
14664INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
14665{
developera3511852023-06-14 14:12:59 +080014666 // TODO Implement me!
14667 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014668}
14669
14670INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
14671{
developera3511852023-06-14 14:12:59 +080014672 // TODO Implement me!
14673 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014674}
14675
14676INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
14677{
developera3511852023-06-14 14:12:59 +080014678 // TODO Implement me!
14679 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014680}
14681
14682INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
14683{
developera3511852023-06-14 14:12:59 +080014684 // TODO Implement me!
14685 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014686}
14687
14688INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
14689{
developera3511852023-06-14 14:12:59 +080014690 // TODO Implement me!
14691 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014692}
14693
14694INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
14695{
developera3511852023-06-14 14:12:59 +080014696 // TODO Implement me!
14697 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014698}
14699
14700INT wifi_steering_eventUnregister(void)
14701{
developera3511852023-06-14 14:12:59 +080014702 // TODO Implement me!
14703 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014704}
14705
14706INT wifi_delApAclDevices(INT apIndex)
14707{
developer7e4a2a62023-04-06 19:56:03 +080014708 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080014709 struct unl unl_ins;
14710 int if_idx = 0, ret = 0;
14711 struct nl_msg *msg = NULL;
14712 struct nlattr * msg_data = NULL;
14713 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080014714
developer7e4a2a62023-04-06 19:56:03 +080014715 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
14716 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080014717 if_idx = if_nametoindex(inf_name);
14718 if (!if_idx) {
14719 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
14720 return RETURN_ERR;
14721 }
14722 /*init mtk nl80211 vendor cmd*/
14723 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
14724 param.if_type = NL80211_ATTR_IFINDEX;
14725 param.if_idx = if_idx;
14726 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
14727 if (ret) {
14728 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
14729 return RETURN_ERR;
14730 }
14731 /*add mtk vendor cmd data*/
14732 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
14733 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
14734 nlmsg_free(msg);
14735 goto err;
14736 }
14737 /*send mtk nl80211 vendor msg*/
14738 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
14739 if (ret) {
14740 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
14741 goto err;
14742 }
14743 /*deinit mtk nl80211 vendor msg*/
14744 mtk_nl80211_deint(&unl_ins);
14745 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
14746 return RETURN_OK;
14747err:
14748 mtk_nl80211_deint(&unl_ins);
14749 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
14750 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014751
developera3511852023-06-14 14:12:59 +080014752 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014753}
14754
developer72fb0bb2023-01-11 09:46:29 +080014755static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080014756 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14757 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14758 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14759 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
14760 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
14761 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080014762
developera3511852023-06-14 14:12:59 +080014763 nla_parse(tb,
14764 NL80211_ATTR_MAX,
14765 genlmsg_attrdata(gnlh, 0),
14766 genlmsg_attrlen(gnlh, 0),
14767 NULL);
developer72fb0bb2023-01-11 09:46:29 +080014768
developera3511852023-06-14 14:12:59 +080014769 if (!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014770 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080014771 return NL_SKIP;
14772 }
developer72fb0bb2023-01-11 09:46:29 +080014773
developera3511852023-06-14 14:12:59 +080014774 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014775 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014776 return NL_SKIP;
14777 }
14778 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080014779
developera3511852023-06-14 14:12:59 +080014780 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080014781
developera3511852023-06-14 14:12:59 +080014782 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
14783 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
developer75bd10c2023-06-27 11:34:08 +080014784 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080014785 return NL_SKIP;
14786 }
14787 }
developer72fb0bb2023-01-11 09:46:29 +080014788
developera3511852023-06-14 14:12:59 +080014789 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14790 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
14791 printf("failed to parse nested stats attributes!");
14792 return NL_SKIP;
14793 }
14794 }
14795 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080014796
developera3511852023-06-14 14:12:59 +080014797 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
14798 {
14799 printf("Type is VHT\n");
14800 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
14801 ((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 +080014802
developera3511852023-06-14 14:12:59 +080014803 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
14804 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
14805 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
14806 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14807 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
14808 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14809 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
14810 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
14811 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
14812 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
14813 } else {
14814 printf(" OFDM or CCK \n");
14815 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
14816 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
14817 }
14818 }
developer72fb0bb2023-01-11 09:46:29 +080014819
developera3511852023-06-14 14:12:59 +080014820 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
developereff896f2023-05-29 14:52:55 +080014821 if(rinfo[NL80211_RATE_INFO_MCS])
14822 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
14823 }
developera3511852023-06-14 14:12:59 +080014824 if (sinfo[NL80211_STA_INFO_RX_BYTES64])
developereff896f2023-05-29 14:52:55 +080014825 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
14826 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
14827 ((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 +080014828
developera3511852023-06-14 14:12:59 +080014829 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
14830 if (stats_info[NL80211_TID_STATS_RX_MSDU])
developereff896f2023-05-29 14:52:55 +080014831 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
14832 }
developer72fb0bb2023-01-11 09:46:29 +080014833
developereff896f2023-05-29 14:52:55 +080014834 if (sinfo[NL80211_STA_INFO_SIGNAL])
14835 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
14836 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
14837 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
14838 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
14839 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
14840 //rssi_array need to be filled
14841 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080014842}
developer72fb0bb2023-01-11 09:46:29 +080014843
14844INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
14845{
developera3511852023-06-14 14:12:59 +080014846 Netlink nl;
14847 char if_name[32];
14848 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
14849 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014850
developera3511852023-06-14 14:12:59 +080014851 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080014852
developera3511852023-06-14 14:12:59 +080014853 if (*output_array_size <= 0)
14854 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014855
developera3511852023-06-14 14:12:59 +080014856 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080014857
developera3511852023-06-14 14:12:59 +080014858 if (nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080014859 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080014860 return 0;
14861 }
developer72fb0bb2023-01-11 09:46:29 +080014862
developera3511852023-06-14 14:12:59 +080014863 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080014864
developera3511852023-06-14 14:12:59 +080014865 if (!msg) {
developer75bd10c2023-06-27 11:34:08 +080014866 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080014867 nlfree(&nl);
14868 return 0;
14869 }
developer72fb0bb2023-01-11 09:46:29 +080014870
developera3511852023-06-14 14:12:59 +080014871 genlmsg_put(msg,
14872 NL_AUTO_PID,
14873 NL_AUTO_SEQ,
14874 nl.id,
14875 0,
14876 0,
14877 NL80211_CMD_GET_STATION,
14878 0);
developer72fb0bb2023-01-11 09:46:29 +080014879
developera3511852023-06-14 14:12:59 +080014880 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
14881 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
14882 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
14883 nl_send_auto_complete(nl.socket, msg);
14884 nl_recvmsgs(nl.socket, nl.cb);
14885 nlmsg_free(msg);
14886 nlfree(&nl);
14887 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014888}
14889
developer72fb0bb2023-01-11 09:46:29 +080014890static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080014891 struct nlattr *tb[NL80211_ATTR_MAX + 1];
14892 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
14893 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
14894 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
14895 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
14896 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080014897
developera3511852023-06-14 14:12:59 +080014898 nla_parse(tb,
14899 NL80211_ATTR_MAX,
14900 genlmsg_attrdata(gnlh, 0),
14901 genlmsg_attrlen(gnlh, 0),
14902 NULL);
developer72fb0bb2023-01-11 09:46:29 +080014903
developera3511852023-06-14 14:12:59 +080014904 if(!tb[NL80211_ATTR_STA_INFO]) {
developer75bd10c2023-06-27 11:34:08 +080014905 wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
developera3511852023-06-14 14:12:59 +080014906 return NL_SKIP;
14907 }
developer72fb0bb2023-01-11 09:46:29 +080014908
developera3511852023-06-14 14:12:59 +080014909 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014910 wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
developera3511852023-06-14 14:12:59 +080014911 return NL_SKIP;
14912 }
developer72fb0bb2023-01-11 09:46:29 +080014913
developera3511852023-06-14 14:12:59 +080014914 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080014915
developera3511852023-06-14 14:12:59 +080014916 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080014917
developera3511852023-06-14 14:12:59 +080014918 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
14919 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
developer75bd10c2023-06-27 11:34:08 +080014920 wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
developera3511852023-06-14 14:12:59 +080014921 return NL_SKIP;
14922 }
14923 }
developer72fb0bb2023-01-11 09:46:29 +080014924
developera3511852023-06-14 14:12:59 +080014925 if(sinfo[NL80211_STA_INFO_TID_STATS])
14926 {
14927 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
14928 printf("failed to parse nested stats attributes!");
14929 return NL_SKIP;
14930 }
14931 }
14932 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
14933 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
14934 {
14935 printf("Type is VHT\n");
14936 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
14937 ((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 +080014938
developera3511852023-06-14 14:12:59 +080014939 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
14940 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
14941 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
14942 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
14943 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
14944 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
14945 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
14946 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
14947 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
14948 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
14949 }
14950 else
14951 {
14952 printf(" OFDM or CCK \n");
14953 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
14954 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
14955 }
14956 }
developer72fb0bb2023-01-11 09:46:29 +080014957
developera3511852023-06-14 14:12:59 +080014958 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
14959 if(rinfo[NL80211_RATE_INFO_MCS])
14960 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
14961 }
developer72fb0bb2023-01-11 09:46:29 +080014962
developera3511852023-06-14 14:12:59 +080014963 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
14964 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
14965 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
14966 ((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 +080014967
developera3511852023-06-14 14:12:59 +080014968 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
14969 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
14970 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080014971
developera3511852023-06-14 14:12:59 +080014972 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
14973 if(stats_info[NL80211_TID_STATS_TX_MSDU])
14974 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
14975 }
developer72fb0bb2023-01-11 09:46:29 +080014976
developera3511852023-06-14 14:12:59 +080014977 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
14978 ((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 +080014979
developera3511852023-06-14 14:12:59 +080014980 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
14981 ((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 +080014982
developera3511852023-06-14 14:12:59 +080014983 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080014984}
developer72fb0bb2023-01-11 09:46:29 +080014985
14986INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
14987{
developera3511852023-06-14 14:12:59 +080014988 Netlink nl;
14989 char if_name[IF_NAME_SIZE];
14990 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080014991 int res;
14992
developera3511852023-06-14 14:12:59 +080014993 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
14994 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014995
developera3511852023-06-14 14:12:59 +080014996 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080014997
developera3511852023-06-14 14:12:59 +080014998 if (*output_array_size <= 0)
14999 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015000
developere40952c2023-06-15 18:46:43 +080015001 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
15002 if (os_snprintf_error(sizeof(if_name), res)) {
15003 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15004 return RETURN_ERR;
15005 }
developer72fb0bb2023-01-11 09:46:29 +080015006
developera3511852023-06-14 14:12:59 +080015007 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080015008
developera3511852023-06-14 14:12:59 +080015009 if(nl.id < 0) {
developer75bd10c2023-06-27 11:34:08 +080015010 wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
developera3511852023-06-14 14:12:59 +080015011 return 0;
15012 }
developer72fb0bb2023-01-11 09:46:29 +080015013
developera3511852023-06-14 14:12:59 +080015014 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080015015
developera3511852023-06-14 14:12:59 +080015016 if(!msg) {
developer75bd10c2023-06-27 11:34:08 +080015017 wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
developera3511852023-06-14 14:12:59 +080015018 nlfree(&nl);
15019 return 0;
15020 }
developer72fb0bb2023-01-11 09:46:29 +080015021
developera3511852023-06-14 14:12:59 +080015022 genlmsg_put(msg,
15023 NL_AUTO_PID,
15024 NL_AUTO_SEQ,
15025 nl.id,
15026 0,
15027 0,
15028 NL80211_CMD_GET_STATION,
15029 0);
developer72fb0bb2023-01-11 09:46:29 +080015030
developera3511852023-06-14 14:12:59 +080015031 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
15032 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
15033 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
15034 nl_send_auto_complete(nl.socket, msg);
15035 nl_recvmsgs(nl.socket, nl.cb);
15036 nlmsg_free(msg);
15037 nlfree(&nl);
15038 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015039}
15040
15041INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
15042{
developera3511852023-06-14 14:12:59 +080015043 // TODO Implement me!
15044 char buf[MAX_BUF_SIZE] = {0};
15045 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080015046 int res;
developer72fb0bb2023-01-11 09:46:29 +080015047
developere40952c2023-06-15 18:46:43 +080015048 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15049 if (os_snprintf_error(sizeof(config_file), res)) {
15050 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15051 return RETURN_ERR;
15052 }
developera3511852023-06-14 14:12:59 +080015053 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
15054 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080015055
developera3511852023-06-14 14:12:59 +080015056 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015057}
15058
15059INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
15060{
developera3511852023-06-14 14:12:59 +080015061 char config_file[MAX_BUF_SIZE] = {0};
15062 struct params list;
developer75bd10c2023-06-27 11:34:08 +080015063 int res;
developer72fb0bb2023-01-11 09:46:29 +080015064
developera3511852023-06-14 14:12:59 +080015065 list.name = "rrm_neighbor_report";
15066 list.value = activate?"1":"0";
developer75bd10c2023-06-27 11:34:08 +080015067 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15068 if (os_snprintf_error(sizeof(config_file), res)) {
15069 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15070 return RETURN_ERR;
15071 }
developera3511852023-06-14 14:12:59 +080015072 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080015073
developera3511852023-06-14 14:12:59 +080015074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015075}
15076
15077INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
15078{
developera3511852023-06-14 14:12:59 +080015079 char buf[32] = {0};
15080 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080015081 int res;
developer72fb0bb2023-01-11 09:46:29 +080015082
developer75bd10c2023-06-27 11:34:08 +080015083 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15084 if (os_snprintf_error(sizeof(config_file), res)) {
15085 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15086 return RETURN_ERR;
15087 }
developera3511852023-06-14 14:12:59 +080015088 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
15089 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080015090
developera3511852023-06-14 14:12:59 +080015091 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015092}
15093#undef HAL_NETLINK_IMPL
15094#ifdef HAL_NETLINK_IMPL
15095static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080015096 struct nlattr *tb[NL80211_ATTR_MAX + 1];
15097 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
15098 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
15099 char dev[20];
15100 int freq =0 ;
15101 static int i=0;
developer72fb0bb2023-01-11 09:46:29 +080015102
developera3511852023-06-14 14:12:59 +080015103 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
developer72fb0bb2023-01-11 09:46:29 +080015104
developera3511852023-06-14 14:12:59 +080015105 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
15106 };
developer72fb0bb2023-01-11 09:46:29 +080015107
developera3511852023-06-14 14:12:59 +080015108 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080015109
developera3511852023-06-14 14:12:59 +080015110 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080015111
developera3511852023-06-14 14:12:59 +080015112 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
15113 fprintf(stderr, "survey data missing!\n");
15114 return NL_SKIP;
15115 }
developer72fb0bb2023-01-11 09:46:29 +080015116
developera3511852023-06-14 14:12:59 +080015117 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
15118 {
15119 fprintf(stderr, "failed to parse nested attributes!\n");
15120 return NL_SKIP;
15121 }
developer72fb0bb2023-01-11 09:46:29 +080015122
15123
developera3511852023-06-14 14:12:59 +080015124 if(out[0].array_size == 1 )
15125 {
15126 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
15127 {
15128 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
15129 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
15130 out[0].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080015131
developera3511852023-06-14 14:12:59 +080015132 if (sinfo[NL80211_SURVEY_INFO_NOISE])
15133 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
15134 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
15135 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
15136 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
15137 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
15138 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
15139 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
15140 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
15141 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
15142 if (sinfo[NL80211_SURVEY_INFO_TIME])
15143 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
15144 return NL_STOP;
15145 }
15146 } else {
15147 if ( i <= out[0].array_size ) {
15148 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
15149 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
15150 out[i].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080015151
developera3511852023-06-14 14:12:59 +080015152 if (sinfo[NL80211_SURVEY_INFO_NOISE])
15153 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
15154 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
15155 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
15156 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
15157 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
15158 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
15159 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
15160 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
15161 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
15162 if (sinfo[NL80211_SURVEY_INFO_TIME])
15163 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
15164 }
15165 }
developer72fb0bb2023-01-11 09:46:29 +080015166
developera3511852023-06-14 14:12:59 +080015167 i++;
15168 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080015169}
15170#endif
15171
15172static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
15173{
developera3511852023-06-14 14:12:59 +080015174 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
15175 FILE *fp;
developere40952c2023-06-15 18:46:43 +080015176 int res;
developer72fb0bb2023-01-11 09:46:29 +080015177
developera3511852023-06-14 14:12:59 +080015178 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
15179 {
15180 printf("Creating Frequency-Channel Map\n");
15181 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
15182 }
developere40952c2023-06-15 18:46:43 +080015183 res = snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
15184 if (os_snprintf_error(sizeof(command), res)) {
15185 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15186 return RETURN_ERR;
15187 }
15188
developera3511852023-06-14 14:12:59 +080015189 if((fp = popen(command, "r")))
15190 {
15191 fgets(output, sizeof(output), fp);
15192 *freqMHz = atoi(output);
15193 pclose(fp);
15194 }
developer72fb0bb2023-01-11 09:46:29 +080015195
developera3511852023-06-14 14:12:59 +080015196 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015197}
15198
developer2f79c922023-06-02 17:33:42 +080015199static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
developer72fb0bb2023-01-11 09:46:29 +080015200{
developera3511852023-06-14 14:12:59 +080015201 int freqMHz = -1;
15202 char cmd[MAX_CMD_SIZE] = {'\0'};
15203 char interface_name[16] = {0};
developer32f2a182023-06-27 19:50:41 +080015204 int res;
developer72fb0bb2023-01-11 09:46:29 +080015205
developera3511852023-06-14 14:12:59 +080015206 ieee80211_channel_to_frequency(channel, &freqMHz);
15207 if (freqMHz == -1) {
15208 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
15209 return -1;
15210 }
developer72fb0bb2023-01-11 09:46:29 +080015211
developer86035662023-06-28 19:21:12 +080015212 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
15213 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
15214 }
developer32f2a182023-06-27 19:50:41 +080015215 res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz);
15216 if (os_snprintf_error(sizeof(cmd), res)) {
15217 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15218 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080015219 }
developer72fb0bb2023-01-11 09:46:29 +080015220
developera3511852023-06-14 14:12:59 +080015221 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
15222 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
15223 return -1;
15224 }
developer72fb0bb2023-01-11 09:46:29 +080015225
developera3511852023-06-14 14:12:59 +080015226 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015227}
15228
15229static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
15230{
developera3511852023-06-14 14:12:59 +080015231 const char *ptr = buf;
15232 char *key = NULL;
15233 char *val = NULL;
15234 char line[256] = { '\0' };
developer72fb0bb2023-01-11 09:46:29 +080015235
developera3511852023-06-14 14:12:59 +080015236 while ((ptr = get_line_from_str_buf(ptr, line))) {
15237 if (strstr(line, "Frequency")) continue;
developer72fb0bb2023-01-11 09:46:29 +080015238
developera3511852023-06-14 14:12:59 +080015239 key = strtok(line, ":");
15240 val = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080015241 if (val == NULL)
15242 continue;
developera3511852023-06-14 14:12:59 +080015243 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
developer72fb0bb2023-01-11 09:46:29 +080015244
developera3511852023-06-14 14:12:59 +080015245 if (!strcmp(key, "noise")) {
developer37646972023-06-29 10:58:43 +080015246 if (sscanf(val, "%d", &stats->ch_noise) == EOF)
15247 continue;
developera3511852023-06-14 14:12:59 +080015248 if (stats->ch_noise == 0) {
15249 // Workaround for missing noise information.
15250 // Assume -95 for 2.4G and -103 for 5G
15251 if (radioIndex == 0) stats->ch_noise = -95;
15252 if (radioIndex == 1) stats->ch_noise = -103;
15253 }
15254 }
15255 else if (!strcmp(key, "channel active time")) {
developer37646972023-06-29 10:58:43 +080015256 if (sscanf(val, "%llu", &stats->ch_utilization_total) == EOF)
15257 continue;
developera3511852023-06-14 14:12:59 +080015258 }
15259 else if (!strcmp(key, "channel busy time")) {
developer37646972023-06-29 10:58:43 +080015260 if (sscanf(val, "%llu", &stats->ch_utilization_busy) == EOF)
15261 continue;
developera3511852023-06-14 14:12:59 +080015262 }
15263 else if (!strcmp(key, "channel receive time")) {
developer37646972023-06-29 10:58:43 +080015264 if (sscanf(val, "%llu", &stats->ch_utilization_busy_rx) == EOF)
15265 continue;
developera3511852023-06-14 14:12:59 +080015266 }
15267 else if (!strcmp(key, "channel transmit time")) {
developer37646972023-06-29 10:58:43 +080015268 if (sscanf(val, "%llu", &stats->ch_utilization_busy_tx) == EOF)
15269 continue;
developera3511852023-06-14 14:12:59 +080015270 }
15271 };
developer72fb0bb2023-01-11 09:46:29 +080015272
developera3511852023-06-14 14:12:59 +080015273 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015274}
15275
15276INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
15277{
developera3511852023-06-14 14:12:59 +080015278 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015279#ifdef HAL_NETLINK_IMPL
developera3511852023-06-14 14:12:59 +080015280 Netlink nl;
15281 wifi_channelStats_t_loc local[array_size];
15282 char if_name[32];
developer72fb0bb2023-01-11 09:46:29 +080015283
developera3511852023-06-14 14:12:59 +080015284 local[0].array_size = array_size;
developer72fb0bb2023-01-11 09:46:29 +080015285
developera3511852023-06-14 14:12:59 +080015286 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
15287 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015288
developera3511852023-06-14 14:12:59 +080015289 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080015290
developera3511852023-06-14 14:12:59 +080015291 if (nl.id < 0) {
15292 fprintf(stderr, "Error initializing netlink \n");
15293 return -1;
15294 }
developer72fb0bb2023-01-11 09:46:29 +080015295
developera3511852023-06-14 14:12:59 +080015296 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080015297
developera3511852023-06-14 14:12:59 +080015298 if (!msg) {
15299 fprintf(stderr, "Failed to allocate netlink message.\n");
15300 nlfree(&nl);
15301 return -2;
15302 }
developer72fb0bb2023-01-11 09:46:29 +080015303
developera3511852023-06-14 14:12:59 +080015304 genlmsg_put(msg,
15305 NL_AUTO_PID,
15306 NL_AUTO_SEQ,
15307 nl.id,
15308 0,
15309 NLM_F_DUMP,
15310 NL80211_CMD_GET_SURVEY,
15311 0);
developer72fb0bb2023-01-11 09:46:29 +080015312
developera3511852023-06-14 14:12:59 +080015313 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
15314 nl_send_auto_complete(nl.socket, msg);
15315 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
15316 nl_recvmsgs(nl.socket, nl.cb);
15317 nlmsg_free(msg);
15318 nlfree(&nl);
15319 //Copying the Values
15320 for(int i=0;i<array_size;i++)
15321 {
15322 input_output_channelStats_array[i].ch_number = local[i].ch_number;
15323 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
15324 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
15325 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
15326 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
15327 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
15328 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
15329 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
15330 }
developer72fb0bb2023-01-11 09:46:29 +080015331#else
developera3511852023-06-14 14:12:59 +080015332 ULONG channel = 0;
15333 int i;
15334 int number_of_channels = array_size;
15335 char buf[512];
developer72fb0bb2023-01-11 09:46:29 +080015336
developera3511852023-06-14 14:12:59 +080015337 if (number_of_channels == 0) {
15338 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
15339 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
15340 return RETURN_ERR;
15341 }
15342 number_of_channels = 1;
15343 input_output_channelStats_array[0].ch_number = channel;
15344 }
developer72fb0bb2023-01-11 09:46:29 +080015345
developera3511852023-06-14 14:12:59 +080015346 for (i = 0; i < number_of_channels; i++) {
developer72fb0bb2023-01-11 09:46:29 +080015347
developera3511852023-06-14 14:12:59 +080015348 input_output_channelStats_array[i].ch_noise = 0;
15349 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
15350 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
15351 input_output_channelStats_array[i].ch_utilization_busy = 0;
15352 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
15353 input_output_channelStats_array[i].ch_utilization_total = 0;
developer72fb0bb2023-01-11 09:46:29 +080015354
developera3511852023-06-14 14:12:59 +080015355 memset(buf, 0, sizeof(buf));
15356 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
15357 return RETURN_ERR;
15358 }
15359 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
15360 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
15361 return RETURN_ERR;
15362 }
developer72fb0bb2023-01-11 09:46:29 +080015363
developera3511852023-06-14 14:12:59 +080015364 // XXX: fake missing 'self' counter which is not available in iw survey output
15365 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
15366 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 +080015367
developera3511852023-06-14 14:12:59 +080015368 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
15369 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
15370 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
15371 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
15372 input_output_channelStats_array[i].ch_utilization_total *= 1000;
developer72fb0bb2023-01-11 09:46:29 +080015373
developera3511852023-06-14 14:12:59 +080015374 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",
15375 __func__,
15376 input_output_channelStats_array[i].ch_number,
15377 input_output_channelStats_array[i].ch_noise,
15378 input_output_channelStats_array[i].ch_utilization_total,
15379 input_output_channelStats_array[i].ch_utilization_busy,
15380 input_output_channelStats_array[i].ch_utilization_busy_rx,
15381 input_output_channelStats_array[i].ch_utilization_busy_tx,
15382 input_output_channelStats_array[i].ch_utilization_busy_self,
15383 input_output_channelStats_array[i].ch_utilization_busy_ext);
15384 }
developer72fb0bb2023-01-11 09:46:29 +080015385#endif
developera3511852023-06-14 14:12:59 +080015386 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15387 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015388}
15389#define HAL_NETLINK_IMPL
15390
15391/* Hostapd events */
15392
15393#ifndef container_of
15394#define offset_of(st, m) ((size_t)&(((st *)0)->m))
15395#define container_of(ptr, type, member) \
developera3511852023-06-14 14:12:59 +080015396 ((type *)((char *)ptr - offset_of(type, member)))
developer72fb0bb2023-01-11 09:46:29 +080015397#endif /* container_of */
15398
15399struct ctrl {
developera3511852023-06-14 14:12:59 +080015400 char sockpath[128];
15401 char sockdir[128];
15402 char bss[IFNAMSIZ];
15403 char reply[4096];
15404 int ssid_index;
15405 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
15406 void (*overrun)(struct ctrl *ctrl);
15407 struct wpa_ctrl *wpa;
15408 unsigned int ovfl;
15409 size_t reply_len;
15410 int initialized;
15411 ev_timer retry;
15412 ev_timer watchdog;
15413 ev_stat stat;
15414 ev_io io;
developer72fb0bb2023-01-11 09:46:29 +080015415};
15416static wifi_newApAssociatedDevice_callback clients_connect_cb;
15417static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
15418static struct ctrl wpa_ctrl[MAX_APS];
15419static int initialized;
15420
15421static unsigned int ctrl_get_drops(struct ctrl *ctrl)
15422{
developera3511852023-06-14 14:12:59 +080015423 char cbuf[256] = {};
15424 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
15425 struct cmsghdr *cmsg;
15426 unsigned int ovfl = ctrl->ovfl;
developer86035662023-06-28 19:21:12 +080015427 unsigned int drop = 0;
developer72fb0bb2023-01-11 09:46:29 +080015428
developer86035662023-06-28 19:21:12 +080015429 if (recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT) < 0)
15430 return drop;
developera3511852023-06-14 14:12:59 +080015431 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
15432 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
15433 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
developer72fb0bb2023-01-11 09:46:29 +080015434
developera3511852023-06-14 14:12:59 +080015435 drop = ovfl - ctrl->ovfl;
15436 ctrl->ovfl = ovfl;
developer72fb0bb2023-01-11 09:46:29 +080015437
developera3511852023-06-14 14:12:59 +080015438 return drop;
developer72fb0bb2023-01-11 09:46:29 +080015439}
15440
15441static void ctrl_close(struct ctrl *ctrl)
15442{
developera3511852023-06-14 14:12:59 +080015443 if (ctrl->io.cb)
15444 ev_io_stop(EV_DEFAULT_ &ctrl->io);
15445 if (ctrl->retry.cb)
15446 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
15447 if (!ctrl->wpa)
15448 return;
developer72fb0bb2023-01-11 09:46:29 +080015449
developera3511852023-06-14 14:12:59 +080015450 wpa_ctrl_detach(ctrl->wpa);
15451 wpa_ctrl_close(ctrl->wpa);
15452 ctrl->wpa = NULL;
15453 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
developer72fb0bb2023-01-11 09:46:29 +080015454}
15455
15456static void ctrl_process(struct ctrl *ctrl)
15457{
developera3511852023-06-14 14:12:59 +080015458 const char *str;
15459 int drops;
15460 int level;
developer72fb0bb2023-01-11 09:46:29 +080015461
developera3511852023-06-14 14:12:59 +080015462 /* Example events:
15463 *
15464 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
15465 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
15466 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
15467 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
15468 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
15469 */
15470 if (!(str = index(ctrl->reply, '>')))
15471 return;
15472 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
15473 return;
developer72fb0bb2023-01-11 09:46:29 +080015474
developera3511852023-06-14 14:12:59 +080015475 str++;
developer72fb0bb2023-01-11 09:46:29 +080015476
developera3511852023-06-14 14:12:59 +080015477 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
15478 if (!(str = index(ctrl->reply, ' ')))
15479 return;
15480 wifi_associated_dev_t sta;
15481 memset(&sta, 0, sizeof(sta));
developer72fb0bb2023-01-11 09:46:29 +080015482
developera3511852023-06-14 14:12:59 +080015483 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
15484 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
15485 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
developer72fb0bb2023-01-11 09:46:29 +080015486
developera3511852023-06-14 14:12:59 +080015487 sta.cli_Active=true;
developer72fb0bb2023-01-11 09:46:29 +080015488
developera3511852023-06-14 14:12:59 +080015489 (clients_connect_cb)(ctrl->ssid_index, &sta);
15490 goto handled;
15491 }
developer72fb0bb2023-01-11 09:46:29 +080015492
developera3511852023-06-14 14:12:59 +080015493 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
15494 if (!(str = index(ctrl->reply, ' ')))
15495 return;
developer72fb0bb2023-01-11 09:46:29 +080015496
developera3511852023-06-14 14:12:59 +080015497 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
15498 goto handled;
15499 }
developer72fb0bb2023-01-11 09:46:29 +080015500
developera3511852023-06-14 14:12:59 +080015501 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
15502 printf("CTRL_WPA: handle TERMINATING event\n");
15503 goto retry;
15504 }
developer72fb0bb2023-01-11 09:46:29 +080015505
developera3511852023-06-14 14:12:59 +080015506 if (strncmp("AP-DISABLED", str, 11) == 0) {
15507 printf("CTRL_WPA: handle AP-DISABLED\n");
15508 goto retry;
15509 }
developer72fb0bb2023-01-11 09:46:29 +080015510
developera3511852023-06-14 14:12:59 +080015511 printf("Event not supported!!\n");
developer72fb0bb2023-01-11 09:46:29 +080015512
15513handled:
15514
developera3511852023-06-14 14:12:59 +080015515 if ((drops = ctrl_get_drops(ctrl))) {
15516 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
15517 if (ctrl->overrun)
15518 ctrl->overrun(ctrl);
15519 }
developer72fb0bb2023-01-11 09:46:29 +080015520
developera3511852023-06-14 14:12:59 +080015521 return;
developer72fb0bb2023-01-11 09:46:29 +080015522
15523retry:
developera3511852023-06-14 14:12:59 +080015524 printf("WPA_CTRL: closing\n");
15525 ctrl_close(ctrl);
15526 printf("WPA_CTRL: retrying from ctrl prcoess\n");
15527 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
developer72fb0bb2023-01-11 09:46:29 +080015528}
15529
15530static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
15531{
developera3511852023-06-14 14:12:59 +080015532 struct ctrl *ctrl = container_of(io, struct ctrl, io);
15533 int err;
developer72fb0bb2023-01-11 09:46:29 +080015534
developera3511852023-06-14 14:12:59 +080015535 memset(ctrl->reply, 0, sizeof(ctrl->reply));
15536 ctrl->reply_len = sizeof(ctrl->reply) - 1;
15537 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
15538 ctrl->reply[ctrl->reply_len] = 0;
15539 if (err < 0) {
15540 if (errno == EAGAIN || errno == EWOULDBLOCK)
15541 return;
15542 ctrl_close(ctrl);
15543 ev_timer_again(EV_A_ &ctrl->retry);
15544 return;
15545 }
developer72fb0bb2023-01-11 09:46:29 +080015546
developera3511852023-06-14 14:12:59 +080015547 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015548}
15549
15550static int ctrl_open(struct ctrl *ctrl)
15551{
developera3511852023-06-14 14:12:59 +080015552 int fd;
developer72fb0bb2023-01-11 09:46:29 +080015553
developera3511852023-06-14 14:12:59 +080015554 if (ctrl->wpa)
15555 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015556
developera3511852023-06-14 14:12:59 +080015557 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
15558 if (!ctrl->wpa)
15559 goto err;
developer72fb0bb2023-01-11 09:46:29 +080015560
developera3511852023-06-14 14:12:59 +080015561 if (wpa_ctrl_attach(ctrl->wpa) < 0)
15562 goto err_close;
developer72fb0bb2023-01-11 09:46:29 +080015563
developera3511852023-06-14 14:12:59 +080015564 fd = wpa_ctrl_get_fd(ctrl->wpa);
15565 if (fd < 0)
15566 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080015567
developera3511852023-06-14 14:12:59 +080015568 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
15569 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080015570
developera3511852023-06-14 14:12:59 +080015571 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
15572 ev_io_start(EV_DEFAULT_ &ctrl->io);
developer72fb0bb2023-01-11 09:46:29 +080015573
developera3511852023-06-14 14:12:59 +080015574 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015575
15576err_detach:
developera3511852023-06-14 14:12:59 +080015577 wpa_ctrl_detach(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080015578err_close:
developera3511852023-06-14 14:12:59 +080015579 wpa_ctrl_close(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080015580err:
developera3511852023-06-14 14:12:59 +080015581 ctrl->wpa = NULL;
15582 return -1;
developer72fb0bb2023-01-11 09:46:29 +080015583}
15584
15585static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
15586{
developera3511852023-06-14 14:12:59 +080015587 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
developer72fb0bb2023-01-11 09:46:29 +080015588
developera3511852023-06-14 14:12:59 +080015589 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
15590 ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015591}
15592
15593static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
15594{
developera3511852023-06-14 14:12:59 +080015595 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
developer72fb0bb2023-01-11 09:46:29 +080015596
developera3511852023-06-14 14:12:59 +080015597 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
15598 if (ctrl_open(ctrl) == 0) {
15599 printf("WPA_CTRL: retry successful\n");
15600 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
15601 }
developer72fb0bb2023-01-11 09:46:29 +080015602}
15603
15604int ctrl_enable(struct ctrl *ctrl)
15605{
developera3511852023-06-14 14:12:59 +080015606 if (ctrl->wpa)
15607 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015608
developera3511852023-06-14 14:12:59 +080015609 if (!ctrl->stat.cb) {
15610 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
15611 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
15612 }
developer72fb0bb2023-01-11 09:46:29 +080015613
developera3511852023-06-14 14:12:59 +080015614 if (!ctrl->retry.cb) {
15615 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
15616 }
developer72fb0bb2023-01-11 09:46:29 +080015617
developera3511852023-06-14 14:12:59 +080015618 return ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015619}
15620
15621static void
15622ctrl_msg_cb(char *buf, size_t len)
15623{
developera3511852023-06-14 14:12:59 +080015624 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
developer72fb0bb2023-01-11 09:46:29 +080015625
developera3511852023-06-14 14:12:59 +080015626 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
15627 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080015628}
15629
15630static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
15631{
developera3511852023-06-14 14:12:59 +080015632 int err;
developer72fb0bb2023-01-11 09:46:29 +080015633
developera3511852023-06-14 14:12:59 +080015634 if (!ctrl->wpa)
15635 return -1;
15636 if (*reply_len < 2)
15637 return -1;
developer72fb0bb2023-01-11 09:46:29 +080015638
developera3511852023-06-14 14:12:59 +080015639 (*reply_len)--;
15640 ctrl->reply_len = sizeof(ctrl->reply);
15641 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
15642 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
15643 if (err < 0)
15644 return err;
developer72fb0bb2023-01-11 09:46:29 +080015645
developera3511852023-06-14 14:12:59 +080015646 if (ctrl->reply_len > *reply_len)
15647 ctrl->reply_len = *reply_len;
developer72fb0bb2023-01-11 09:46:29 +080015648
developera3511852023-06-14 14:12:59 +080015649 *reply_len = ctrl->reply_len;
15650 memcpy(reply, ctrl->reply, *reply_len);
15651 reply[*reply_len - 1] = 0;
15652 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
15653 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015654}
15655
15656static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
15657{
developera3511852023-06-14 14:12:59 +080015658 const char *pong = "PONG";
15659 const char *ping = "PING";
15660 char reply[1024];
15661 size_t len = sizeof(reply);
15662 int err;
15663 ULONG s, snum;
15664 INT ret;
15665 BOOL status;
developer72fb0bb2023-01-11 09:46:29 +080015666
developera3511852023-06-14 14:12:59 +080015667 printf("WPA_CTRL: watchdog cb\n");
developer72fb0bb2023-01-11 09:46:29 +080015668
developera3511852023-06-14 14:12:59 +080015669 ret = wifi_getSSIDNumberOfEntries(&snum);
15670 if (ret != RETURN_OK) {
15671 printf("%s: failed to get SSID count", __func__);
15672 return;
15673 }
developer72fb0bb2023-01-11 09:46:29 +080015674
developera3511852023-06-14 14:12:59 +080015675 if (snum > MAX_APS) {
15676 printf("more ssid than supported! %lu\n", snum);
15677 return;
15678 }
developer72fb0bb2023-01-11 09:46:29 +080015679
developera3511852023-06-14 14:12:59 +080015680 for (s = 0; s < snum; s++) {
15681 if (wifi_getApEnable(s, &status) != RETURN_OK) {
15682 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
15683 continue;
15684 }
15685 if (status == false) continue;
developer72fb0bb2023-01-11 09:46:29 +080015686
developera3511852023-06-14 14:12:59 +080015687 memset(reply, 0, sizeof(reply));
15688 len = sizeof(reply);
15689 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
15690 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
15691 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
15692 continue;
developer72fb0bb2023-01-11 09:46:29 +080015693
developera3511852023-06-14 14:12:59 +080015694 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
15695 ctrl_close(&wpa_ctrl[s]);
15696 printf("WPA_CTRL: ev_timer_again %lu\n", s);
15697 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
15698 }
developer72fb0bb2023-01-11 09:46:29 +080015699}
15700
15701static int init_wpa()
15702{
developer9ce44382023-06-28 11:09:37 +080015703 int ret = 0;
developera3511852023-06-14 14:12:59 +080015704 ULONG s, snum;
developer72fb0bb2023-01-11 09:46:29 +080015705
developera3511852023-06-14 14:12:59 +080015706 ret = wifi_getSSIDNumberOfEntries(&snum);
15707 if (ret != RETURN_OK) {
15708 printf("%s: failed to get SSID count", __func__);
15709 return RETURN_ERR;
15710 }
developer72fb0bb2023-01-11 09:46:29 +080015711
developera3511852023-06-14 14:12:59 +080015712 if (snum > MAX_APS) {
15713 printf("more ssid than supported! %lu\n", snum);
15714 return RETURN_ERR;
15715 }
developer72fb0bb2023-01-11 09:46:29 +080015716
developera3511852023-06-14 14:12:59 +080015717 for (s = 0; s < snum; s++) {
15718 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
developer32f2a182023-06-27 19:50:41 +080015719 ret = snprintf(wpa_ctrl[s].sockpath, sizeof(wpa_ctrl[s].sockpath), "%s%lu", SOCK_PREFIX, s);
15720 if (os_snprintf_error(sizeof(wpa_ctrl[s].sockpath), ret)) {
15721 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15722 return RETURN_ERR;
15723 }
developera3511852023-06-14 14:12:59 +080015724 wpa_ctrl[s].ssid_index = s;
15725 ctrl_enable(&wpa_ctrl[s]);
15726 }
developer72fb0bb2023-01-11 09:46:29 +080015727
developera3511852023-06-14 14:12:59 +080015728 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
15729 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
developer72fb0bb2023-01-11 09:46:29 +080015730
developera3511852023-06-14 14:12:59 +080015731 initialized = 1;
15732 printf("WPA_CTRL: initialized\n");
developer72fb0bb2023-01-11 09:46:29 +080015733
developera3511852023-06-14 14:12:59 +080015734 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015735}
15736
15737void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
15738{
developera3511852023-06-14 14:12:59 +080015739 clients_connect_cb = callback_proc;
15740 if (!initialized)
15741 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080015742}
15743
15744void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
15745{
developera3511852023-06-14 14:12:59 +080015746 clients_disconnect_cb = callback_proc;
15747 if (!initialized)
15748 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080015749}
15750
15751INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
15752{
developera3511852023-06-14 14:12:59 +080015753 // TODO Implement me!
15754 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015755}
15756
15757INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
15758{
developera3511852023-06-14 14:12:59 +080015759 // TODO Implement me!
15760 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015761}
15762
15763INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
15764{
developera3511852023-06-14 14:12:59 +080015765 int i;
15766 int phyId = -1;
15767 char cmd[256] = {0};
15768 char channel_numbers_buf[256] = {0};
15769 char dfs_state_buf[256] = {0};
15770 char line[256] = {0};
15771 const char *ptr;
15772 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +080015773 int res;
developer72fb0bb2023-01-11 09:46:29 +080015774
developera3511852023-06-14 14:12:59 +080015775 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080015776
developera3511852023-06-14 14:12:59 +080015777 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
15778 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080015779
developere40952c2023-06-15 18:46:43 +080015780 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\\|");
15781 if (os_snprintf_error(sizeof(cmd), res)) {
15782 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15783 return RETURN_ERR;
15784 }
developer72fb0bb2023-01-11 09:46:29 +080015785
developera3511852023-06-14 14:12:59 +080015786 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
15787 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
15788 return RETURN_ERR;
15789 }
developer72fb0bb2023-01-11 09:46:29 +080015790
developera3511852023-06-14 14:12:59 +080015791 ptr = channel_numbers_buf;
15792 i = 0;
15793 while ((ptr = get_line_from_str_buf(ptr, line))) {
15794 if (i >= outputMapSize) {
15795 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
15796 return RETURN_ERR;
15797 }
developerd14dff12023-06-28 22:47:44 +080015798 if (sscanf(line, "%d", &outputMap[i].ch_number) != 1) {
15799 wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
15800 return RETURN_ERR;
15801 }
developerd1824452023-05-18 12:30:04 +080015802
developera3511852023-06-14 14:12:59 +080015803 memset(cmd, 0, sizeof(cmd));
15804 // Below command should fetch string for DFS state (usable, available or unavailable)
15805 // Example line: "DFS state: usable (for 78930 sec)"
15806 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) {
15807 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
15808 return RETURN_ERR;
15809 }
developer72fb0bb2023-01-11 09:46:29 +080015810
developera3511852023-06-14 14:12:59 +080015811 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
15812 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
15813 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
15814 return RETURN_ERR;
15815 }
developer72fb0bb2023-01-11 09:46:29 +080015816
developera3511852023-06-14 14:12:59 +080015817 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080015818
developera3511852023-06-14 14:12:59 +080015819 if (!strcmp(dfs_state_buf, "usable")) {
15820 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
15821 } else if (!strcmp(dfs_state_buf, "available")) {
15822 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
15823 } else if (!strcmp(dfs_state_buf, "unavailable")) {
15824 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
15825 } else {
15826 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
15827 }
15828 i++;
15829 }
developer40ba1762023-05-13 11:03:49 +080015830
developera3511852023-06-14 14:12:59 +080015831 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +080015832
developera3511852023-06-14 14:12:59 +080015833 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
15834 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015835}
15836
15837INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
15838{
developera3511852023-06-14 14:12:59 +080015839 // TODO Implement me!
15840 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015841}
15842
15843INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
15844{
developer0155a502023-06-19 20:33:57 +080015845 int ret = -1;
15846 char inf_name[IF_NAME_SIZE] = {0};
15847 int if_idx = 0;
15848 struct unl unl_ins;
15849 struct nl_msg *msg = NULL;
15850 struct nlattr * msg_data = NULL;
15851 struct mtk_nl80211_param param;
15852 struct mtk_nl80211_cb_data cb_data;
15853 wdev_ap_metric ap_metric;
15854
15855 /*init mtk nl80211 vendor cmd*/
15856
15857 if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
15858 return RETURN_ERR;
15859 if_idx = if_nametoindex(inf_name);
15860 if (!if_idx) {
15861 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
15862 return RETURN_ERR;
15863 }
15864
15865 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STATISTIC;
15866 param.if_type = NL80211_ATTR_IFINDEX;
15867 param.if_idx = if_idx;
15868
15869 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
15870 if (ret) {
15871 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
15872 return RETURN_ERR;
15873 }
15874
15875 /*add mtk vendor cmd data*/
15876
15877 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS, sizeof(wdev_ap_metric), (char *)&ap_metric)) {
15878 wifi_debug(DEBUG_ERROR, "Nla put GET_AP_METRICS attribute error\n");
15879 nlmsg_free(msg);
15880 goto err;
15881 }
15882
15883 /*send mtk nl80211 vendor msg*/
15884 cb_data.out_buf = (char *)output_percentage;
15885 cb_data.out_len = sizeof(wdev_ap_metric);
15886 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_metrics, &cb_data);
15887 if (ret) {
15888 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
15889 goto err;
15890 }
15891
15892 /*deinit mtk nl80211 vendor msg*/
15893 mtk_nl80211_deint(&unl_ins);
15894 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
15895 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15896
developera3511852023-06-14 14:12:59 +080015897 return RETURN_OK;
developer0155a502023-06-19 20:33:57 +080015898err:
15899 mtk_nl80211_deint(&unl_ins);
15900 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
15901 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015902}
15903
developer0155a502023-06-19 20:33:57 +080015904
developer72fb0bb2023-01-11 09:46:29 +080015905INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
15906{
developera3511852023-06-14 14:12:59 +080015907 // TODO Implement me!
15908 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015909}
15910
15911INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
15912{
developera3511852023-06-14 14:12:59 +080015913 // TODO API refrence Implementaion is present on RPI hal
15914 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015915}
15916
15917INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
15918{
developera3511852023-06-14 14:12:59 +080015919 ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080015920
developera3511852023-06-14 14:12:59 +080015921 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15922 if(txpwr_pcntg == NULL)
developerdaf24792023-06-06 11:40:04 +080015923 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015924
developera1255e42023-05-13 17:45:02 +080015925 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
15926 *txpwr_pcntg = pwr_percentage;
developera3511852023-06-14 14:12:59 +080015927 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15928 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015929}
15930
15931INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
15932{
developera3511852023-06-14 14:12:59 +080015933 // TODO precac feature.
15934 struct params params[2] = {0};
15935 char config_file[128] = {0};
15936 BOOL dfs_enable = false;
15937 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080015938 int res;
developer72fb0bb2023-01-11 09:46:29 +080015939
developera3511852023-06-14 14:12:59 +080015940 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15941 band = wifi_index_to_band(radioIndex);
15942 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080015943
developera3511852023-06-14 14:12:59 +080015944 if (dfs_enable == false) {
15945 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
15946 return RETURN_ERR;
15947 }
15948 params[0].name = "DfsZeroWaitDefault";
15949 params[0].value = enable?"1":"0";
15950 params[1].name = "DfsDedicatedZeroWait";
15951 params[1].value = enable?"1":"0";
developere40952c2023-06-15 18:46:43 +080015952 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15953 if (os_snprintf_error(sizeof(config_file), res)) {
15954 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15955 return RETURN_ERR;
15956 }
developera3511852023-06-14 14:12:59 +080015957 wifi_datfileWrite(config_file, params, 2);
15958 wifi_reloadAp(radioIndex);
15959 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080015960
developera3511852023-06-14 14:12:59 +080015961 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15962 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015963}
15964
15965INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
15966{
developera3511852023-06-14 14:12:59 +080015967 char config_file[128] = {0};
15968 char buf1[32] = {0};
15969 char buf2[32] = {0};
15970 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080015971 int res;
developer72fb0bb2023-01-11 09:46:29 +080015972
developera3511852023-06-14 14:12:59 +080015973 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15974 if (NULL == enable || NULL == precac)
15975 return RETURN_ERR;
15976 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080015977 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
15978 if (os_snprintf_error(sizeof(config_file), res)) {
15979 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15980 return RETURN_ERR;
15981 }
developera3511852023-06-14 14:12:59 +080015982 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
15983 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
15984 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
15985 *enable = true;
15986 else
15987 *enable = false;
developer72fb0bb2023-01-11 09:46:29 +080015988
developera3511852023-06-14 14:12:59 +080015989 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080015990
developera3511852023-06-14 14:12:59 +080015991 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15992 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015993}
15994
15995INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
15996{
developera3511852023-06-14 14:12:59 +080015997 *supported = TRUE;
15998 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015999}
16000
16001INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
16002{
developer863a4a62023-06-06 16:55:59 +080016003 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016004 wifi_band band = band_invalid;
16005 char ofdmabuf[32] = {'\0'};
16006 char mimobuf[32] = {'\0'};
16007 char new_ofdmabuf[32] = {'\0'};
16008 char new_mimobuf[32] = {'\0'};
16009 struct params params[2];
developera1255e42023-05-13 17:45:02 +080016010 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
16011 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
16012 UCHAR bss_cnt = 0;
16013 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080016014 int res;
developer72fb0bb2023-01-11 09:46:29 +080016015
developera3511852023-06-14 14:12:59 +080016016 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +080016017 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
16018 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
16019 printf("%s:mu_type input Error", __func__);
16020 return RETURN_ERR;
16021 }
developera3511852023-06-14 14:12:59 +080016022 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080016023 if (band == band_invalid) {
16024 printf("%s:Band Error\n", __func__);
16025 return RETURN_ERR;
16026 }
developere40952c2023-06-15 18:46:43 +080016027 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16028 if (os_snprintf_error(sizeof(dat_file), res)) {
16029 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16030 return RETURN_ERR;
16031 }
16032
developera1255e42023-05-13 17:45:02 +080016033 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080016034 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
16035 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080016036 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
16037 get_bssnum_byindex(radio_index, &bss_cnt);
16038 val_cnt = 2*bss_cnt - 1;
16039 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
16040 if ((val_cnt >= sizeof(new_ofdmabuf))
16041 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080016042 printf("%s:bss cnt Error", __func__);
developera1255e42023-05-13 17:45:02 +080016043 return RETURN_ERR;
16044 }
16045 /*translate set value*/
16046 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
16047 strncpy(new_ofdmabuf, str_zero, val_cnt);
16048 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016049 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080016050 strncpy(new_ofdmabuf, str_one, val_cnt);
16051 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016052 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080016053 strncpy(new_ofdmabuf, str_zero, val_cnt);
16054 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080016055 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
developera1255e42023-05-13 17:45:02 +080016056 strncpy(new_ofdmabuf, str_one, val_cnt);
16057 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080016058 }
developera1255e42023-05-13 17:45:02 +080016059 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
16060 /*same value, not operation*/
16061 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
16062 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
16063 printf("%s:Reduntant value\n", __func__);
16064 return RETURN_OK;
16065 }
16066 /*modify dat file to new file*/
16067 params[0].name="MuOfdmaDlEnable";
16068 params[0].value=new_ofdmabuf;
16069 params[1].name="MuMimoDlEnable";
16070 params[1].value=new_mimobuf;
16071 wifi_datfileWrite(dat_file, params, 2);
16072 /*hostapd control restarp ap to take effect on these new value*/
16073 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080016074 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16075 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016076}
16077
16078INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
16079{
developer5a333cf2023-06-06 18:18:50 +080016080 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016081 wifi_band band = band_invalid;
16082 char ofdmabuf[32] = {'\0'};
16083 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080016084 char *token = NULL;
16085 UCHAR ofdma = 0;
16086 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080016087 int res;
developer72fb0bb2023-01-11 09:46:29 +080016088
developera3511852023-06-14 14:12:59 +080016089 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016090
developera3511852023-06-14 14:12:59 +080016091 if (mu_type == NULL)
16092 return RETURN_ERR;
16093 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080016094 if (band == band_invalid) {
16095 printf("%s:Band Error\n", __func__);
16096 return RETURN_ERR;
16097 }
developere40952c2023-06-15 18:46:43 +080016098 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16099 if (os_snprintf_error(sizeof(dat_file), res)) {
16100 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16101 return RETURN_ERR;
16102 }
developera1255e42023-05-13 17:45:02 +080016103 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080016104 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
16105 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080016106
developera1255e42023-05-13 17:45:02 +080016107 token = strtok(ofdmabuf, ";");
developerd14dff12023-06-28 22:47:44 +080016108 if (token == NULL) {
16109 wifi_debug(DEBUG_ERROR, "strtok fail\n");
16110 return RETURN_ERR;
16111 }
developera1255e42023-05-13 17:45:02 +080016112 ofdma = strtol(token, NULL, 10);
developerd14dff12023-06-28 22:47:44 +080016113 if (ofdma == 0 && token[0] != '0') {
16114 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
16115 return RETURN_ERR;
16116 }
developera1255e42023-05-13 17:45:02 +080016117 token = strtok(mimobuf, ";");
developer37646972023-06-29 10:58:43 +080016118 if (token == NULL) {
16119 wifi_debug(DEBUG_ERROR, "Unexpected strtok fail\n");
16120 return RETURN_ERR;
16121 }
developera1255e42023-05-13 17:45:02 +080016122 mimo = strtol(token, NULL, 10);
developer37646972023-06-29 10:58:43 +080016123 if ((token[0] != '\0') && (mimo == 0)) {
16124 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
16125 return RETURN_ERR;
16126 }
developera1255e42023-05-13 17:45:02 +080016127 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
16128 if ((ofdma == 1) && (mimo == 1))
16129 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
16130 else if ((ofdma == 0) && (mimo == 1))
16131 *mu_type = WIFI_DL_MU_TYPE_MIMO;
16132 else if ((ofdma == 1) && (mimo == 0))
16133 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
16134 else
16135 *mu_type = WIFI_DL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080016136 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16137 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016138}
16139
16140INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
16141{
developera3511852023-06-14 14:12:59 +080016142 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developer863a4a62023-06-06 16:55:59 +080016143 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016144 wifi_band band = band_invalid;
16145 char ofdmabuf[32] = {'\0'};
16146 char mimobuf[32] = {'\0'};
16147 char new_ofdmabuf[32] = {'\0'};
16148 char new_mimobuf[32] = {'\0'};
16149 struct params params[2];
developera1255e42023-05-13 17:45:02 +080016150 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
16151 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
16152 UCHAR bss_cnt = 0;
16153 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080016154 int res;
developer72fb0bb2023-01-11 09:46:29 +080016155
developera3511852023-06-14 14:12:59 +080016156 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16157 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080016158 if (band == band_invalid) {
16159 printf("%s:Band Error\n", __func__);
16160 return RETURN_ERR;
16161 }
16162 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
16163 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
16164 printf("%s:mu_type input Error\n", __func__);
16165 return RETURN_ERR;
16166 }
developere40952c2023-06-15 18:46:43 +080016167 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16168 if (os_snprintf_error(sizeof(dat_file), res)) {
16169 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16170 return RETURN_ERR;
16171 }
developera1255e42023-05-13 17:45:02 +080016172 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080016173 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
16174 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080016175 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
16176 get_bssnum_byindex(radio_index, &bss_cnt);
16177 val_cnt = 2*bss_cnt - 1;
16178 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
16179 if ((val_cnt >= sizeof(new_ofdmabuf))
16180 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080016181 printf("%s:bss cnt Error\n", __func__);
developera1255e42023-05-13 17:45:02 +080016182 return RETURN_ERR;
16183 }
16184 /*translate set value*/
16185 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
16186 strncpy(new_ofdmabuf, str_zero, val_cnt);
16187 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016188 }
developera1255e42023-05-13 17:45:02 +080016189 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
16190 strncpy(new_ofdmabuf, str_one, val_cnt);
16191 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080016192 }
developera1255e42023-05-13 17:45:02 +080016193 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
16194 /*same value, not operation*/
16195 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
16196 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
16197 printf("%s:Reduntant value\n", __func__);
16198 return RETURN_OK;
16199 }
16200 /*modify dat file to new file*/
16201 params[0].name="MuOfdmaUlEnable";
16202 params[0].value=new_ofdmabuf;
16203 params[1].name="MuMimoUlEnable";
16204 params[1].value=new_mimobuf;
16205 wifi_datfileWrite(dat_file, params, 2);
16206 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080016207 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16208 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016209}
16210
16211INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
16212{
developer863a4a62023-06-06 16:55:59 +080016213 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080016214 wifi_band band = band_invalid;
16215 char ofdmabuf[32] = {'\0'};
16216 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080016217 char *token = NULL;
16218 UCHAR ofdma = 0;
16219 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080016220 int res;
developer72fb0bb2023-01-11 09:46:29 +080016221
developera3511852023-06-14 14:12:59 +080016222 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016223
developera3511852023-06-14 14:12:59 +080016224 if (mu_type == NULL)
16225 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080016226 band = wifi_index_to_band(radio_index);
16227 if (band == band_invalid) {
16228 printf("%s:Band Error", __func__);
16229 return RETURN_ERR;
16230 }
developere40952c2023-06-15 18:46:43 +080016231 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16232 if (os_snprintf_error(sizeof(dat_file), res)) {
16233 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16234 return RETURN_ERR;
16235 }
developera1255e42023-05-13 17:45:02 +080016236 /*get current value in dat file*/
16237 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
16238 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080016239
developera1255e42023-05-13 17:45:02 +080016240 token = strtok(ofdmabuf, ";");
developerd14dff12023-06-28 22:47:44 +080016241 if (token == NULL) {
16242 wifi_debug(DEBUG_ERROR, "strtok fail\n");
16243 return RETURN_ERR;
16244 }
developera1255e42023-05-13 17:45:02 +080016245 ofdma = strtol(token, NULL, 10);
developerd14dff12023-06-28 22:47:44 +080016246 if (ofdma == 0 && token[0] != '0') {
16247 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
16248 return RETURN_ERR;
16249 }
developera1255e42023-05-13 17:45:02 +080016250 token = strtok(mimobuf, ";");
developer37646972023-06-29 10:58:43 +080016251 if (token == NULL) {
16252 wifi_debug(DEBUG_ERROR, "strtok fail\n");
16253 return RETURN_ERR;
16254 }
developera1255e42023-05-13 17:45:02 +080016255 mimo = strtol(token, NULL, 10);
developer37646972023-06-29 10:58:43 +080016256 if ((token[0] != '\0') && (mimo == 0)) {
16257 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
16258 return RETURN_ERR;
16259 }
developera1255e42023-05-13 17:45:02 +080016260 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
16261 if ((ofdma == 1) && (mimo == 0))
16262 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
16263 else
16264 *mu_type = WIFI_UL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080016265 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16266 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016267}
16268
16269
16270INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
16271{
developera3511852023-06-14 14:12:59 +080016272 char cmd[128] = {0};
16273 char buf[256] = {0};
16274 char config_file[64] = {0};
16275 char GI[8] = {0};
16276 UINT mode_map = 0;
16277 FILE *f = NULL;
16278 wifi_band band = band_invalid;
16279 char dat_file[64] = {'\0'};
16280 struct params params[3];
developere40952c2023-06-15 18:46:43 +080016281 int res;
developer72fb0bb2023-01-11 09:46:29 +080016282
developera3511852023-06-14 14:12:59 +080016283 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016284
developera3511852023-06-14 14:12:59 +080016285 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
16286 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
16287 return RETURN_ERR;
16288 }
developera1255e42023-05-13 17:45:02 +080016289 /*sanity check*/
16290 if (((guard_interval == wifi_guard_interval_1600)
16291 || (guard_interval == wifi_guard_interval_3200))
developerdaf24792023-06-06 11:40:04 +080016292 && ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
developera3511852023-06-14 14:12:59 +080016293 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
16294 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080016295 }
developere40952c2023-06-15 18:46:43 +080016296 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16297 if (os_snprintf_error(sizeof(config_file), res)) {
16298 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16299 return RETURN_ERR;
16300 }
developera3511852023-06-14 14:12:59 +080016301 band = wifi_index_to_band(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080016302
developera3511852023-06-14 14:12:59 +080016303 // Hostapd are not supported HE mode GI 1600, 3200 ns.
16304 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
developere40952c2023-06-15 18:46:43 +080016305 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
16306 if (os_snprintf_error(sizeof(cmd), res)) {
16307 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16308 return RETURN_ERR;
16309 }
developera3511852023-06-14 14:12:59 +080016310 _syscmd(cmd, buf, sizeof(buf));
16311 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
16312 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
16313 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080016314 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
16315 if (os_snprintf_error(sizeof(cmd), res)) {
16316 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16317 return RETURN_ERR;
16318 }
developera3511852023-06-14 14:12:59 +080016319 _syscmd(cmd, buf, sizeof(buf));
16320 }
16321 if (band == band_5) {
16322 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
16323 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080016324 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
16325 if (os_snprintf_error(sizeof(cmd), res)) {
16326 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16327 return RETURN_ERR;
16328 }
developera3511852023-06-14 14:12:59 +080016329 _syscmd(cmd, buf, sizeof(buf));
16330 }
16331 }
16332 }
16333 /*wifi_reloadAp(radio_index);
developera1255e42023-05-13 17:45:02 +080016334 caller "wifi_setRadioOperatingParameters" have done this step.
16335 */
developere40952c2023-06-15 18:46:43 +080016336 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
16337 if (os_snprintf_error(sizeof(dat_file), res)) {
16338 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16339 return RETURN_ERR;
16340 }
developera3511852023-06-14 14:12:59 +080016341 if (guard_interval == wifi_guard_interval_400) {
developera1255e42023-05-13 17:45:02 +080016342 params[0].name = "HT_GI";
16343 params[0].value = "1";
16344 params[1].name = "VHT_SGI";
16345 params[1].value = "1";
16346 wifi_datfileWrite(dat_file, params, 2);
developer32f2a182023-06-27 19:50:41 +080016347 memcpy(GI, "0.4", 3);
developera1255e42023-05-13 17:45:02 +080016348 } else {
16349 params[0].name = "HT_GI";
16350 params[0].value = "0";
16351 params[1].name = "VHT_SGI";
16352 params[1].value = "0";
16353 /*should enable FIXED_HE_GI_SUPPORT in driver*/
16354 params[2].name = "FgiFltf";
16355 if (guard_interval == wifi_guard_interval_800) {
16356 params[2].value = "800";
developer32f2a182023-06-27 19:50:41 +080016357 memcpy(GI, "0.8", 3);
developera1255e42023-05-13 17:45:02 +080016358 } else if (guard_interval == wifi_guard_interval_1600) {
16359 params[2].value = "1600";
developer32f2a182023-06-27 19:50:41 +080016360 memcpy(GI, "1.6", 3);
developera1255e42023-05-13 17:45:02 +080016361 } else if (guard_interval == wifi_guard_interval_3200) {
16362 params[2].value = "3200";
developer32f2a182023-06-27 19:50:41 +080016363 memcpy(GI, "3.2", 3);
developera1255e42023-05-13 17:45:02 +080016364 } else if (guard_interval == wifi_guard_interval_auto) {
16365 params[2].value = "0";
developer32f2a182023-06-27 19:50:41 +080016366 memcpy(GI, "auto", 4);
developera1255e42023-05-13 17:45:02 +080016367 }
16368 wifi_datfileWrite(dat_file, params, 3);
16369 }
developera3511852023-06-14 14:12:59 +080016370 // Record GI for get GI function
developere40952c2023-06-15 18:46:43 +080016371 res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
16372 if (os_snprintf_error(sizeof(buf), res)) {
16373 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16374 return RETURN_ERR;
16375 }
developera3511852023-06-14 14:12:59 +080016376 f = fopen(buf, "w");
16377 if (f == NULL)
16378 return RETURN_ERR;
16379 fprintf(f, "%s", GI);
16380 fclose(f);
16381 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16382 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016383}
16384
16385INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
16386{
developera3511852023-06-14 14:12:59 +080016387 char buf[32] = {0};
16388 char cmd[64] = {0};
developere40952c2023-06-15 18:46:43 +080016389 int res;
developer72fb0bb2023-01-11 09:46:29 +080016390
developera3511852023-06-14 14:12:59 +080016391 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016392
developera3511852023-06-14 14:12:59 +080016393 if (guard_interval == NULL)
16394 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016395
developere40952c2023-06-15 18:46:43 +080016396 res = snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
16397 if (os_snprintf_error(sizeof(cmd), res)) {
16398 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16399 return RETURN_ERR;
16400 }
developera3511852023-06-14 14:12:59 +080016401 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080016402
developera3511852023-06-14 14:12:59 +080016403 if (strncmp(buf, "0.4", 3) == 0)
16404 *guard_interval = wifi_guard_interval_400;
16405 else if (strncmp(buf, "0.8", 3) == 0)
16406 *guard_interval = wifi_guard_interval_800;
16407 else if (strncmp(buf, "1.6", 3) == 0)
16408 *guard_interval = wifi_guard_interval_1600;
16409 else if (strncmp(buf, "3.2", 3) == 0)
16410 *guard_interval = wifi_guard_interval_3200;
16411 else
16412 *guard_interval = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +080016413
developera3511852023-06-14 14:12:59 +080016414 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16415 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016416}
16417
16418INT wifi_setBSSColor(INT radio_index, UCHAR color)
16419{
developera3511852023-06-14 14:12:59 +080016420 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16421 struct params params = {0};
16422 char config_file[128] = {0};
16423 char bss_color[4] ={0};
developere40952c2023-06-15 18:46:43 +080016424 int res;
developer72fb0bb2023-01-11 09:46:29 +080016425
developera1255e42023-05-13 17:45:02 +080016426 if (color < 1 || color > 63) {
16427 wifi_dbg_printf("color value is err:%d.\n", color);
16428 return RETURN_ERR;
16429 }
developera3511852023-06-14 14:12:59 +080016430 params.name = "he_bss_color";
developere40952c2023-06-15 18:46:43 +080016431 res = snprintf(bss_color, sizeof(bss_color), "%hhu", color);
16432 if (os_snprintf_error(sizeof(bss_color), res)) {
16433 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16434 return RETURN_ERR;
16435 }
developera3511852023-06-14 14:12:59 +080016436 params.value = bss_color;
developer75bd10c2023-06-27 11:34:08 +080016437
16438 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16439 if (os_snprintf_error(sizeof(config_file), res)) {
16440 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16441 return RETURN_ERR;
16442 }
developera3511852023-06-14 14:12:59 +080016443 wifi_hostapdWrite(config_file, &params, 1);
16444 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
developera1255e42023-05-13 17:45:02 +080016445 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080016446
developera3511852023-06-14 14:12:59 +080016447 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16448 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016449}
16450
16451INT wifi_getBSSColor(INT radio_index, UCHAR *color)
16452{
developera3511852023-06-14 14:12:59 +080016453 char config_file[128] = {0};
16454 char buf[64] = {0};
16455 char temp_output[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +080016456 int res;
developer72fb0bb2023-01-11 09:46:29 +080016457
developera3511852023-06-14 14:12:59 +080016458 wifi_dbg_printf("\nFunc=%s\n", __func__);
16459 if (NULL == color)
16460 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016461
developer75bd10c2023-06-27 11:34:08 +080016462 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
16463 if (os_snprintf_error(sizeof(config_file), res)) {
16464 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16465 return RETURN_ERR;
16466 }
developera3511852023-06-14 14:12:59 +080016467 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080016468
developera3511852023-06-14 14:12:59 +080016469 if(strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +080016470 res = snprintf(temp_output, sizeof(temp_output), "%s", buf);
developera3511852023-06-14 14:12:59 +080016471 } else {
developere40952c2023-06-15 18:46:43 +080016472 res = snprintf(temp_output, sizeof(temp_output), "1"); // default value
16473 }
16474 if (os_snprintf_error(sizeof(temp_output), res)) {
16475 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16476 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080016477 }
developer72fb0bb2023-01-11 09:46:29 +080016478
developera3511852023-06-14 14:12:59 +080016479 *color = (UCHAR)strtoul(temp_output, NULL, 10);
developerd14dff12023-06-28 22:47:44 +080016480 if (*color == 0 && temp_output[0] != '0') {
16481 wifi_debug(DEBUG_ERROR, "Unexpected strtol fail\n");
16482 return RETURN_ERR;
16483 }
developera3511852023-06-14 14:12:59 +080016484 wifi_dbg_printf("\noutput_string=%s\n", color);
developer72fb0bb2023-01-11 09:46:29 +080016485
developera3511852023-06-14 14:12:59 +080016486 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016487}
16488
16489/* multi-psk support */
16490INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
16491{
developera3511852023-06-14 14:12:59 +080016492 char cmd[256];
16493 char interface_name[16] = {0};
developer75bd10c2023-06-27 11:34:08 +080016494 int res;
developer72fb0bb2023-01-11 09:46:29 +080016495
developera3511852023-06-14 14:12:59 +080016496 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16497 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016498
developer75bd10c2023-06-27 11:34:08 +080016499 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 +080016500 interface_name,
16501 mac[0],
16502 mac[1],
16503 mac[2],
16504 mac[3],
16505 mac[4],
16506 mac[5]
16507 );
developer75bd10c2023-06-27 11:34:08 +080016508 if (os_snprintf_error(sizeof(cmd), res)) {
16509 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16510 return RETURN_ERR;
16511 }
developera3511852023-06-14 14:12:59 +080016512 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
16513 _syscmd(cmd, key->wifi_keyId, 64);
developer72fb0bb2023-01-11 09:46:29 +080016514
16515
developera3511852023-06-14 14:12:59 +080016516 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016517}
16518
16519INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
16520{
developera3511852023-06-14 14:12:59 +080016521 char interface_name[16] = {0};
16522 FILE *fd = NULL;
16523 char fname[100];
16524 char cmd[128] = {0};
16525 char out[64] = {0};
16526 wifi_key_multi_psk_t * key = NULL;
developer75bd10c2023-06-27 11:34:08 +080016527 int res, ret;
developere40952c2023-06-15 18:46:43 +080016528
developera3511852023-06-14 14:12:59 +080016529 if(keysNumber < 0)
16530 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016531
developere40952c2023-06-15 18:46:43 +080016532 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
16533 if (os_snprintf_error(sizeof(fname), res)) {
16534 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16535 return RETURN_ERR;
16536 }
developera3511852023-06-14 14:12:59 +080016537 fd = fopen(fname, "w");
16538 if (!fd) {
16539 return RETURN_ERR;
16540 }
16541 key= (wifi_key_multi_psk_t *) keys;
16542 for(int i=0; i<keysNumber; ++i, key++) {
developer75bd10c2023-06-27 11:34:08 +080016543 ret = fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
16544 if (ret < 0)
16545 wifi_debug(DEBUG_ERROR, "fprintf fail\n");
developera3511852023-06-14 14:12:59 +080016546 }
developerd14dff12023-06-28 22:47:44 +080016547 if (fclose(fd) != 0) {
16548 wifi_debug(DEBUG_ERROR, "fclose fail\n");
16549 return RETURN_ERR;
16550 }
developer72fb0bb2023-01-11 09:46:29 +080016551
developera3511852023-06-14 14:12:59 +080016552 //reload file
16553 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16554 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080016555 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
16556
16557 if (os_snprintf_error(sizeof(cmd), res)) {
16558 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16559 return RETURN_ERR;
16560 }
developera3511852023-06-14 14:12:59 +080016561 _syscmd(cmd, out, 64);
16562 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016563}
16564
16565INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
16566{
developera3511852023-06-14 14:12:59 +080016567 FILE *fd = NULL;
16568 char fname[100];
16569 char * line = NULL;
16570 char * pos = NULL;
16571 size_t len = 0;
16572 ssize_t read = 0;
16573 INT ret = RETURN_OK;
16574 wifi_key_multi_psk_t *keys_it = NULL;
developere40952c2023-06-15 18:46:43 +080016575 int res;
developer72fb0bb2023-01-11 09:46:29 +080016576
developera3511852023-06-14 14:12:59 +080016577 if (keysNumber < 1) {
16578 return RETURN_ERR;
16579 }
developer72fb0bb2023-01-11 09:46:29 +080016580
developere40952c2023-06-15 18:46:43 +080016581 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
16582 if (os_snprintf_error(sizeof(fname), res)) {
16583 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16584 return RETURN_ERR;
16585 }
developera3511852023-06-14 14:12:59 +080016586 fd = fopen(fname, "r");
16587 if (!fd) {
16588 return RETURN_ERR;
16589 }
developer72fb0bb2023-01-11 09:46:29 +080016590
developera3511852023-06-14 14:12:59 +080016591 if (keys == NULL) {
16592 ret = RETURN_ERR;
16593 goto close;
16594 }
developer72fb0bb2023-01-11 09:46:29 +080016595
developera3511852023-06-14 14:12:59 +080016596 keys_it = keys;
16597 while ((read = getline(&line, &len, fd)) != -1) {
16598 //Strip trailing new line if present
16599 if (read > 0 && line[read-1] == '\n') {
16600 line[read-1] = '\0';
16601 }
developer72fb0bb2023-01-11 09:46:29 +080016602
developera3511852023-06-14 14:12:59 +080016603 if(strcmp(line,"keyid=")) {
developer37646972023-06-29 10:58:43 +080016604 if (sscanf(line, "keyid=%63s", keys_it->wifi_keyId) == EOF)
16605 continue;
developera3511852023-06-14 14:12:59 +080016606 if (!(pos = index(line, ' '))) {
16607 ret = RETURN_ERR;
16608 goto close;
16609 }
16610 pos++;
16611 //Here should be 00:00:00:00:00:00
16612 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
16613 printf("Not supported MAC: %s\n", pos);
16614 }
16615 if (!(pos = index(pos, ' '))) {
16616 ret = RETURN_ERR;
16617 goto close;
16618 }
16619 pos++;
developer72fb0bb2023-01-11 09:46:29 +080016620
developera3511852023-06-14 14:12:59 +080016621 //The rest is PSK
developere40952c2023-06-15 18:46:43 +080016622 res = snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
16623 if (os_snprintf_error(sizeof(keys_it->wifi_psk), res)) {
16624 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developer9ce44382023-06-28 11:09:37 +080016625 fclose(fd);
developere40952c2023-06-15 18:46:43 +080016626 return RETURN_ERR;
16627 }
16628
developera3511852023-06-14 14:12:59 +080016629 keys_it++;
developer72fb0bb2023-01-11 09:46:29 +080016630
developera3511852023-06-14 14:12:59 +080016631 if(--keysNumber <= 0)
developer72fb0bb2023-01-11 09:46:29 +080016632 break;
developera3511852023-06-14 14:12:59 +080016633 }
16634 }
developer72fb0bb2023-01-11 09:46:29 +080016635
16636close:
developera3511852023-06-14 14:12:59 +080016637 free(line);
developer37646972023-06-29 10:58:43 +080016638 if (fclose(fd) == EOF)
16639 wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
developera3511852023-06-14 14:12:59 +080016640 return ret;
developer72fb0bb2023-01-11 09:46:29 +080016641}
16642/* end of multi-psk support */
16643
16644INT wifi_setNeighborReports(UINT apIndex,
developera3511852023-06-14 14:12:59 +080016645 UINT numNeighborReports,
16646 wifi_NeighborReport_t *neighborReports)
developer72fb0bb2023-01-11 09:46:29 +080016647{
developera3511852023-06-14 14:12:59 +080016648 char cmd[256] = { 0 };
16649 char hex_bssid[13] = { 0 };
16650 char bssid[18] = { 0 };
16651 char nr[100] = { 0 };
16652 char ssid[32];
16653 char hex_ssid[32];
16654 char interface_name[16] = {0};
16655 INT ret;
developere40952c2023-06-15 18:46:43 +080016656 int res;
developerd14dff12023-06-28 22:47:44 +080016657 unsigned char hex_ssid_len;
developer72fb0bb2023-01-11 09:46:29 +080016658
developera3511852023-06-14 14:12:59 +080016659 /*rmeove all neighbors*/
16660 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
16661 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
16662 return RETURN_ERR;
developer32f2a182023-06-27 19:50:41 +080016663 res = snprintf(cmd, sizeof(cmd),
16664 "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
16665 interface_name, interface_name);
16666
developer75bd10c2023-06-27 11:34:08 +080016667 if (os_snprintf_error(sizeof(cmd), res)) {
16668 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16669 return RETURN_ERR;
16670 }
developera3511852023-06-14 14:12:59 +080016671 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080016672
developera3511852023-06-14 14:12:59 +080016673 for(unsigned int i = 0; i < numNeighborReports; i++)
16674 {
16675 memset(ssid, 0, sizeof(ssid));
16676 ret = wifi_getSSIDName(apIndex, ssid);
16677 if (ret != RETURN_OK)
16678 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016679
developera3511852023-06-14 14:12:59 +080016680 memset(hex_ssid, 0, sizeof(hex_ssid));
developerd14dff12023-06-28 22:47:44 +080016681 hex_ssid_len = sizeof(hex_ssid);
16682 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 ) {
16683 res = snprintf(hex_ssid + k, hex_ssid_len, "%02x", ssid[j]);
16684
16685 if (os_snprintf_error(hex_ssid_len, res)) {
16686 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16687 return RETURN_ERR;
16688 }
16689 hex_ssid_len = sizeof(hex_ssid) - strlen(hex_ssid);
16690 }
developer72fb0bb2023-01-11 09:46:29 +080016691
developere40952c2023-06-15 18:46:43 +080016692 res = snprintf(hex_bssid, sizeof(hex_bssid),
developera3511852023-06-14 14:12:59 +080016693 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
16694 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 +080016695 if (os_snprintf_error(sizeof(hex_bssid), res)) {
16696 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16697 return RETURN_ERR;
16698 }
16699 res = snprintf(bssid, sizeof(bssid),
developera3511852023-06-14 14:12:59 +080016700 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
16701 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 +080016702 if (os_snprintf_error(sizeof(bssid), res)) {
16703 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16704 return RETURN_ERR;
16705 }
developer72fb0bb2023-01-11 09:46:29 +080016706
developere40952c2023-06-15 18:46:43 +080016707 res = snprintf(nr, sizeof(nr),
developera3511852023-06-14 14:12:59 +080016708 "%s" // bssid
16709 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
16710 "%02hhx" // operclass
16711 "%02hhx" // channel
16712 "%02hhx", // phy_mode
16713 hex_bssid,
16714 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
16715 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
16716 neighborReports[i].opClass,
16717 neighborReports[i].channel,
16718 neighborReports[i].phyTable);
developere40952c2023-06-15 18:46:43 +080016719 if (os_snprintf_error(sizeof(nr), res)) {
16720 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16721 return RETURN_ERR;
16722 }
developer72fb0bb2023-01-11 09:46:29 +080016723
developere40952c2023-06-15 18:46:43 +080016724 res = snprintf(cmd, sizeof(cmd),
developera3511852023-06-14 14:12:59 +080016725 "hostapd_cli set_neighbor "
16726 "%s " // bssid
16727 "ssid=%s " // ssid
16728 "nr=%s " // nr
16729 "-i %s",
16730 bssid,hex_ssid,nr, interface_name);
developere40952c2023-06-15 18:46:43 +080016731 if (os_snprintf_error(sizeof(cmd), res)) {
16732 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16733 return RETURN_ERR;
16734 }
developer72fb0bb2023-01-11 09:46:29 +080016735
developera3511852023-06-14 14:12:59 +080016736 if (WEXITSTATUS(system(cmd)) != 0)
16737 {
16738 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
16739 }
16740 }
developer72fb0bb2023-01-11 09:46:29 +080016741
developera3511852023-06-14 14:12:59 +080016742 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016743}
16744
16745INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
16746{
developera3511852023-06-14 14:12:59 +080016747 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016748}
16749
16750#ifdef _WIFI_HAL_TEST_
16751int main(int argc,char **argv)
16752{
developera3511852023-06-14 14:12:59 +080016753 int index;
16754 INT ret=0;
16755 char buf[1024]="";
developer72fb0bb2023-01-11 09:46:29 +080016756
developera3511852023-06-14 14:12:59 +080016757 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16758 if(argc<3)
16759 {
16760 if(argc==2)
16761 {
16762 if(!strcmp(argv[1], "init"))
16763 return wifi_init();
16764 if(!strcmp(argv[1], "reset"))
16765 return wifi_reset();
16766 if(!strcmp(argv[1], "wifi_getHalVersion"))
16767 {
16768 char buffer[64];
16769 if(wifi_getHalVersion(buffer)==RETURN_OK)
16770 printf("Version: %s\n", buffer);
16771 else
16772 printf("Error in wifi_getHalVersion\n");
16773 return RETURN_OK;
16774 }
16775 }
16776 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
16777 exit(-1);
16778 }
developer72fb0bb2023-01-11 09:46:29 +080016779
developera3511852023-06-14 14:12:59 +080016780 index = atoi(argv[2]);
16781 if(strstr(argv[1], "wifi_getApName")!=NULL)
16782 {
16783 wifi_getApName(index,buf);
16784 printf("Ap name is %s \n",buf);
16785 return 0;
16786 }
developerfead3972023-05-25 20:15:02 +080016787 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080016788 {
developerfead3972023-05-25 20:15:02 +080016789 UINT pureMode = atoi(argv[3]);
16790
developera3511852023-06-14 14:12:59 +080016791 wifi_setRadioMode(index, NULL, pureMode);
16792 printf("Ap SET Radio mode 0x%x\n", pureMode);
16793 return 0;
16794 }
16795 if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
16796 unsigned char enable = atoi(argv[3]);
16797 if (enable)
16798 wifi_setRadioAutoBlockAckEnable(index, TRUE);
16799 else
16800 wifi_setRadioAutoBlockAckEnable(index, FALSE);
16801 printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
16802 }
developera39cfb22023-06-20 16:28:17 +080016803 if(strstr(argv[1], "wifi_setRadioTrafficStatsRadioStatisticsEnable")!=NULL)
16804 {
16805 wifi_setRadioTrafficStatsRadioStatisticsEnable(index, TRUE);
16806 printf("Ap SET wifi_setRadioTrafficStatsRadioStatisticsEnable\n");
16807 return 0;
16808 }
16809 if(strstr(argv[1], "wifi_setRadioTrafficStatsMeasure")!=NULL)
16810 {
16811 wifi_radioTrafficStatsMeasure_t input = {30, 200};
16812
16813 wifi_setRadioTrafficStatsMeasure(index, &input);
16814 printf("Ap SET wifi_setRadioTrafficStatsMeasure\n");
16815 return 0;
16816 }
developerfead3972023-05-25 20:15:02 +080016817 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
developera3511852023-06-14 14:12:59 +080016818 {
developerfead3972023-05-25 20:15:02 +080016819 ULONG TransmitPower = atoi(argv[3]);
16820
developera3511852023-06-14 14:12:59 +080016821 wifi_setRadioTransmitPower(index, TransmitPower);
16822 printf("Ap SET TransmitPower %lu\n", TransmitPower);
16823 return 0;
16824 }
developerfead3972023-05-25 20:15:02 +080016825 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
developera3511852023-06-14 14:12:59 +080016826 {
developerfead3972023-05-25 20:15:02 +080016827 INT TransmitPower = atoi(argv[3]);
16828
developera3511852023-06-14 14:12:59 +080016829 wifi_setApManagementFramePowerControl(index, TransmitPower);
16830 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
16831 return 0;
16832 }
developerfead3972023-05-25 20:15:02 +080016833 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
developera3511852023-06-14 14:12:59 +080016834 {
developerfead3972023-05-25 20:15:02 +080016835 CHAR *bandwith = argv[3];
16836
developera3511852023-06-14 14:12:59 +080016837 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
16838 printf("Ap SET bw %s\n", bandwith);
16839 return 0;
16840 }
developerfead3972023-05-25 20:15:02 +080016841 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
developera3511852023-06-14 14:12:59 +080016842 {
16843 wifi_factoryResetRadio(index);
16844 printf("wifi_factoryResetRadio ok!\n");
16845 return 0;
16846 }
developerfead3972023-05-25 20:15:02 +080016847 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
developera3511852023-06-14 14:12:59 +080016848 {
16849 ULONG rst_cnt;
16850 wifi_getRadioResetCount(index, &rst_cnt);
16851 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
16852 return 0;
16853 }
developer2edaf012023-05-24 14:24:53 +080016854 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080016855 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016856 {
16857 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16858 exit(-1);
16859 }
developer49b17232023-05-19 16:35:19 +080016860 wifi_addApAclDevice(index, argv[3]);
16861 return 0;
16862 }
developer2edaf012023-05-24 14:24:53 +080016863 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
16864 wifi_getApAclDevices(index, buf, 1024);
16865 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080016866 return 0;
16867 }
developer2edaf012023-05-24 14:24:53 +080016868 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
16869 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016870 {
16871 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16872 exit(-1);
16873 }
developer2edaf012023-05-24 14:24:53 +080016874 wifi_delApAclDevice(index, argv[3]);
16875 return 0;
16876 }
16877 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
16878 wifi_delApAclDevices(index);
16879 return 0;
16880 }
16881 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
developer863a4a62023-06-06 16:55:59 +080016882 UINT acl_num = 0;
developer2edaf012023-05-24 14:24:53 +080016883 wifi_getApAclDeviceNum(index, &acl_num);
16884 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
16885 return 0;
16886 }
16887 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
16888 wifi_getApDenyAclDevices(index, buf, 1024);
16889 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
16890 return 0;
16891 }
16892 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
16893 int filter_mode = 0;
16894 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016895 {
16896 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16897 exit(-1);
16898 }
developer2edaf012023-05-24 14:24:53 +080016899 filter_mode = atoi(argv[3]);
16900 wifi_setApMacAddressControlMode(index,filter_mode);
16901 return 0;
16902 }
developer5cd4c862023-05-26 09:34:42 +080016903 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
16904 BOOL output_bool = 0;
16905 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
16906 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
16907 return 0;
16908 }
16909 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
16910 BOOL output_bool = 0;
16911 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
16912 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
16913 return 0;
16914 }
16915
16916 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
16917 int filter_mode = 0;
16918 wifi_getApMacAddressControlMode(index, &filter_mode);
16919 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
16920 return 0;
16921 }
16922 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
16923 int enable = 0;
16924 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080016925 {
16926 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16927 exit(-1);
16928 }
developer5cd4c862023-05-26 09:34:42 +080016929 enable = (BOOL)atoi(argv[3]);
16930 wifi_setRadioIGMPSnoopingEnable(index, enable);
16931 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
16932 return 0;
16933 }
developer326d4232023-06-15 16:45:30 +080016934 if (strncmp(argv[1], "wifi_setRadioDCSEnable(", strlen(argv[1])) == 0) {
16935 int enable = 0;
16936 if(argc <= 3 )
16937 {
16938 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16939 exit(-1);
16940 }
16941 enable = (BOOL)atoi(argv[3]);
16942 wifi_setRadioDCSEnable(index, enable);
16943 wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
16944 return 0;
16945 }
16946 if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod(", strlen(argv[1])) == 0) {
16947 ULONG period = 0;
developer5cd4c862023-05-26 09:34:42 +080016948
developer326d4232023-06-15 16:45:30 +080016949 wifi_getRadioAutoChannelRefreshPeriod(index, &period);
16950 wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
16951 return 0;
16952 }
16953 if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod(", strlen(argv[1])) == 0) {
16954 ULONG period = 0;
16955
16956 period = (ULONG)atoi(argv[3]);
16957 wifi_setRadioDfsRefreshPeriod(index, period);
16958 wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
16959 return 0;
16960 }
16961 if (strncmp(argv[1], "wifi_setRadioDCSChannelPool(", strlen(argv[1])) == 0) {
16962 char pool[256] = {'\0'};
16963
16964 strcpy(pool, argv[3]);
16965 wifi_setRadioDCSChannelPool(index, pool);
16966 wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
16967 return 0;
16968 }
16969 if (strncmp(argv[1], "wifi_getRadioDCSChannelPool(", strlen(argv[1])) == 0) {
16970 char pool[256] = {'\0'};
16971
16972 wifi_getRadioDCSChannelPool(index, pool);
16973 wifi_debug(DEBUG_NOTICE, "Get DCSChannelPool: %s\n", pool);
16974 return 0;
16975 }
developer5cd4c862023-05-26 09:34:42 +080016976 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
16977 BOOL out_status = 0;
16978 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
16979 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
16980 return 0;
16981 }
developer121a8e72023-05-22 09:19:39 +080016982
developer95c045d2023-05-24 19:26:28 +080016983 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
16984 int enable = 0;
16985 if(argc <= 3)
16986 {
16987 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16988 exit(-1);
16989 }
16990 enable = atoi(argv[3]);
16991 wifi_setApWmmEnable(index,enable);
16992 return 0;
16993 }
developerc1aa6532023-06-09 09:37:01 +080016994 if (strncmp(argv[1], "wifi_pushSsidAdvertisementEnable", strlen(argv[1])) == 0) {
16995 int enable = 0;
16996 if(argc <= 3)
16997 {
16998 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
16999 exit(-1);
17000 }
17001 enable = atoi(argv[3]);
17002 wifi_pushSsidAdvertisementEnable(index,enable);
17003 return 0;
17004 }
developer56fbedb2023-05-30 16:47:05 +080017005 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
17006 wifi_down();
17007 return 0;
17008 }
developer95c045d2023-05-24 19:26:28 +080017009
developer56fbedb2023-05-30 16:47:05 +080017010 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
17011 BOOL enable = 0;
17012
17013 wifi_getRadioStatus(index, &enable);
17014 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
17015 return 0;
17016 }
developer333c1eb2023-05-31 14:59:39 +080017017
developer95c045d2023-05-24 19:26:28 +080017018 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
17019 BOOL enable = 0;
17020
17021 wifi_getApWMMCapability(index, &enable);
17022 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
17023 return 0;
17024 }
17025
17026 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
17027 BOOL enable = 0;
17028
17029 wifi_getApWmmEnable(index, &enable);
17030 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
17031 return 0;
17032 }
17033
developer2edaf012023-05-24 14:24:53 +080017034 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
17035 int filter_mode = 0;
17036 wifi_getApMacAddressControlMode(index, &filter_mode);
17037 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
17038 return 0;
17039 }
developer0f10c772023-05-16 21:43:39 +080017040 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080017041 {
developer863a4a62023-06-06 16:55:59 +080017042 UINT mode = 0;
developer0f10c772023-05-16 21:43:39 +080017043
developera3511852023-06-14 14:12:59 +080017044 wifi_getRadioMode(index, buf, &mode);
17045 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
17046 return 0;
17047 }
17048 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
17049 {
17050 BOOL b = FALSE;
17051 BOOL *output_bool = &b;
17052 wifi_getRadioAutoChannelEnable(index,output_bool);
17053 printf("Channel enabled = %d \n",b);
17054 return 0;
17055 }
17056 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
17057 {
17058 wifi_getApWpaEncryptionMode(index,buf);
17059 printf("encryption enabled = %s\n",buf);
17060 return 0;
17061 }
17062 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
17063 {
17064 BOOL b = FALSE;
17065 BOOL *output_bool = &b;
17066 wifi_getApSsidAdvertisementEnable(index,output_bool);
17067 printf("advertisment enabled = %d\n",b);
17068 return 0;
17069 }
17070 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
17071 {
17072 if(argc <= 3 )
17073 {
17074 printf("Insufficient arguments \n");
17075 exit(-1);
17076 }
developer72fb0bb2023-01-11 09:46:29 +080017077
developera3511852023-06-14 14:12:59 +080017078 char sta[20] = {'\0'};
17079 ULLONG handle= 0;
17080 strcpy(sta,argv[3]);
17081 mac_address_t st;
developer72fb0bb2023-01-11 09:46:29 +080017082 mac_addr_aton(st,sta);
17083
developera3511852023-06-14 14:12:59 +080017084 wifi_associated_dev_tid_stats_t tid_stats;
17085 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
17086 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
17087 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);
17088 }
developer72fb0bb2023-01-11 09:46:29 +080017089
developera3511852023-06-14 14:12:59 +080017090 if(strstr(argv[1], "getApEnable")!=NULL) {
17091 BOOL enable;
17092 ret=wifi_getApEnable(index, &enable);
17093 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
17094 }
17095 else if(strstr(argv[1], "setApEnable")!=NULL) {
17096 BOOL enable = atoi(argv[3]);
17097 ret=wifi_setApEnable(index, enable);
17098 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
17099 }
17100 else if(strstr(argv[1], "getApStatus")!=NULL) {
17101 char status[64];
17102 ret=wifi_getApStatus(index, status);
17103 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
17104 }
17105 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
17106 {
17107 wifi_getSSIDNameStatus(index,buf);
17108 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
17109 return 0;
17110 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
17111 wifi_resetApVlanCfg(index);
17112 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
17113 return 0;
17114 }
17115 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
17116 wifi_ssidTrafficStats2_t stats={0};
17117 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
17118 printf("%s %d: returns %d\n", argv[1], index, ret);
17119 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
17120 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
17121 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
17122 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
17123 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
17124 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
17125 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
17126 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
17127 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
17128 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
17129 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
17130 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
17131 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
17132 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
17133 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
17134 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
17135 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
17136 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
17137 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
17138 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
17139 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
17140 }
17141 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
17142 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
17143 UINT array_size=0;
17144 UINT i=0;
17145 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
17146 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
17147 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
17148 printf(" neighbor %d:\n", i);
17149 printf(" ap_SSID =%s\n", pt->ap_SSID);
17150 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
17151 printf(" ap_Mode =%s\n", pt->ap_Mode);
17152 printf(" ap_Channel =%d\n", pt->ap_Channel);
17153 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
17154 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
17155 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
17156 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
17157 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
17158 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
17159 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
17160 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
17161 printf(" ap_Noise =%d\n", pt->ap_Noise);
17162 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
17163 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
17164 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
17165 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
17166 }
17167 if(neighbor_ap_array)
17168 free(neighbor_ap_array); //make sure to free the list
17169 }
17170 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
17171 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
17172 UINT array_size=0;
17173 UINT i=0;
17174 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
17175 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
17176 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
17177 printf(" associated_dev %d:\n", i);
17178 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
17179 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
17180 printf(" cli_SNR =%d\n", pt->cli_SNR);
17181 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
17182 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
17183 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
17184 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
17185 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
17186 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
17187 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
17188 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
17189 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
17190 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
17191 }
17192 if(associated_dev_array)
17193 free(associated_dev_array); //make sure to free the list
17194 }
developer72fb0bb2023-01-11 09:46:29 +080017195
developera3511852023-06-14 14:12:59 +080017196 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
17197 {
developer72fb0bb2023-01-11 09:46:29 +080017198#define MAX_ARRAY_SIZE 64
developera3511852023-06-14 14:12:59 +080017199 int i, array_size;
17200 char *p, *ch_str;
17201 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
developer72fb0bb2023-01-11 09:46:29 +080017202
developera3511852023-06-14 14:12:59 +080017203 if(argc != 5)
17204 {
17205 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
17206 exit(-1);
17207 }
17208 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
developer72fb0bb2023-01-11 09:46:29 +080017209
developera3511852023-06-14 14:12:59 +080017210 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
17211 {
17212 strtok_r(ch_str, ",", &p);
17213 input_output_channelStats_array[i].ch_number = atoi(ch_str);
17214 }
17215 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
17216 if(!array_size)
17217 array_size=1;//Need to print current channel statistics
17218 for(i=0; i<array_size; i++)
17219 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
17220 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
17221 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
17222 input_output_channelStats_array[i].ch_number,\
17223 input_output_channelStats_array[i].ch_noise,\
17224 input_output_channelStats_array[i].ch_utilization_busy_rx,\
17225 input_output_channelStats_array[i].ch_utilization_busy_tx,\
17226 input_output_channelStats_array[i].ch_utilization_busy,\
17227 input_output_channelStats_array[i].ch_utilization_busy_ext,\
17228 input_output_channelStats_array[i].ch_utilization_total);
17229 }
developer72fb0bb2023-01-11 09:46:29 +080017230
developera3511852023-06-14 14:12:59 +080017231 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
17232 {
17233 if(argc <= 3 )
17234 {
17235 printf("Insufficient arguments \n");
17236 exit(-1);
17237 }
17238 char mac_addr[20] = {'\0'};
17239 wifi_device_t output_struct;
17240 int dev_index = atoi(argv[3]);
developer72fb0bb2023-01-11 09:46:29 +080017241
developera3511852023-06-14 14:12:59 +080017242 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
17243 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
17244 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);
17245 }
developer72fb0bb2023-01-11 09:46:29 +080017246
developera3511852023-06-14 14:12:59 +080017247 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
17248 {
17249 if (argc <= 3)
17250 {
17251 printf("Insufficient arguments\n");
17252 exit(-1);
17253 }
17254 char args[256];
17255 wifi_NeighborReport_t *neighborReports;
developer72fb0bb2023-01-11 09:46:29 +080017256
developera3511852023-06-14 14:12:59 +080017257 neighborReports = calloc(argc - 2, sizeof(neighborReports));
17258 if (!neighborReports)
17259 {
17260 printf("Failed to allocate memory");
17261 exit(-1);
17262 }
developer72fb0bb2023-01-11 09:46:29 +080017263
developera3511852023-06-14 14:12:59 +080017264 for (int i = 3; i < argc; ++i)
17265 {
17266 char *val;
17267 int j = 0;
17268 memset(args, 0, sizeof(args));
17269 strncpy(args, argv[i], sizeof(args));
17270 val = strtok(args, ";");
17271 while (val != NULL)
17272 {
17273 if (j == 0)
17274 {
17275 mac_addr_aton(neighborReports[i - 3].bssid, val);
17276 } else if (j == 1)
17277 {
17278 neighborReports[i - 3].info = strtol(val, NULL, 16);
17279 } else if (j == 2)
17280 {
17281 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
17282 } else if (j == 3)
17283 {
17284 neighborReports[i - 3].channel = strtol(val, NULL, 16);
17285 } else if (j == 4)
17286 {
17287 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
17288 } else {
17289 printf("Insufficient arguments]n\n");
17290 exit(-1);
17291 }
17292 val = strtok(NULL, ";");
17293 j++;
17294 }
17295 }
developer72fb0bb2023-01-11 09:46:29 +080017296
developera3511852023-06-14 14:12:59 +080017297 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
17298 if (ret != RETURN_OK)
17299 {
17300 printf("wifi_setNeighborReports ret = %d", ret);
17301 exit(-1);
17302 }
17303 }
17304 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
17305 {
17306 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
17307 printf("%s.\n", buf);
17308 else
17309 printf("Error returned\n");
17310 }
17311 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
17312 {
17313 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
17314 printf("%s.\n", buf);
17315 else
17316 printf("Error returned\n");
17317 }
17318 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
17319 {
17320 if (argc <= 2)
17321 {
17322 printf("Insufficient arguments\n");
17323 exit(-1);
17324 }
17325 char buf[64]= {'\0'};
17326 wifi_getRadioOperatingChannelBandwidth(index,buf);
17327 printf("Current bandwidth is %s \n",buf);
17328 return 0;
17329 }
17330 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
17331 {
17332 if (argc <= 5)
17333 {
17334 printf("Insufficient arguments\n");
17335 exit(-1);
17336 }
17337 UINT channel = atoi(argv[3]);
17338 UINT width = atoi(argv[4]);
17339 UINT beacon = atoi(argv[5]);
17340 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
17341 printf("Result = %d", ret);
17342 }
developercc5cbfb2023-06-13 18:29:52 +080017343 if(strstr(argv[1],"wifi_getApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080017344 {
developercc5cbfb2023-06-13 18:29:52 +080017345 char br_name[64], ip[64], subset[64] = {0};
17346 wifi_getApBridgeInfo(0, br_name, ip, subset);
17347 printf("wifi_getApBridgeInfo br_name = %s, ip = %s, subset = %s\n", br_name, ip, subset);
developera3511852023-06-14 14:12:59 +080017348 }
developercc5cbfb2023-06-13 18:29:52 +080017349 if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
developera3511852023-06-14 14:12:59 +080017350 {
developercc5cbfb2023-06-13 18:29:52 +080017351 int enable = atoi(argv[3]);
17352 wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
17353 printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
developera3511852023-06-14 14:12:59 +080017354 }
developercc5cbfb2023-06-13 18:29:52 +080017355 if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080017356 {
developercc5cbfb2023-06-13 18:29:52 +080017357 wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
17358 printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
developera3511852023-06-14 14:12:59 +080017359 }
developer72fb0bb2023-01-11 09:46:29 +080017360
developer6e578302023-06-21 10:11:16 +080017361 if(strstr(argv[1], "wifi_getATMCapable")!=NULL)
17362 {
17363 BOOL b = FALSE;
17364 BOOL *output_bool = &b;
17365 wifi_getATMCapable(output_bool);
17366 printf("ATM capable = %d \n",b);
17367 return 0;
17368 }
17369 if (strncmp(argv[1], "wifi_setATMEnable", strlen(argv[1])) == 0) {
17370 int enable = 0;
17371 if(argc <= 3)
17372 {
17373 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17374 exit(-1);
17375 }
17376 enable = atoi(argv[3]);
17377 wifi_setATMEnable(enable);
17378 return 0;
17379 }
17380 if (strncmp(argv[1], "wifi_getATMEnable", strlen(argv[1])) == 0) {
17381 BOOL b = FALSE;
17382 BOOL *output_bool = &b;
17383 wifi_getATMEnable(output_bool);
17384 printf("ATM enable = %d \n", b);
17385 return 0;
17386 }
17387 if (strncmp(argv[1], "wifi_setApATMAirTimePercent", strlen(argv[1])) == 0) {
17388 unsigned int percent = 0;
17389 if(argc <= 3)
17390 {
17391 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
17392 exit(-1);
17393 }
17394 percent = atoi(argv[3]);
17395 wifi_setApATMAirTimePercent(index, percent);
17396 return 0;
17397 }
17398 if (strncmp(argv[1], "wifi_getApATMAirTimePercent", strlen(argv[1])) == 0) {
17399 unsigned int percent = 0;
17400 unsigned int *output = &percent;
17401
17402 wifi_getApATMAirTimePercent(index, output);
17403 printf("ATM percent = %d \n", percent);
17404 return 0;
17405 }
developer82533be2023-06-28 17:21:01 +080017406 if (strstr(argv[1],"setGF")!=NULL)
17407 {
17408 BOOL enable = atoi(argv[3]);
17409 if((ret=wifi_setRadio11nGreenfieldEnable(index, enable))==RETURN_OK)
17410 printf("wifi_setRadio11nGreenfieldEnable success\n");
17411 else
17412 printf("wifi_setRadio11nGreenfieldEnable Error\n");
17413 }
17414 if (strstr(argv[1],"setVID")!=NULL)
17415 {
17416 INT vid = atoi(argv[3]);
17417 if((ret=wifi_setApVlanID(index, vid))==RETURN_OK)
17418 printf("wifi_setApVlanID success.\n");
17419 else
17420 printf("wifi_setApVlanID Error\n");
developerd14dff12023-06-28 22:47:44 +080017421 }
17422 if (strncmp(argv[1], "wifi_getApATMSta", strlen(argv[1])) == 0) {
17423 UCHAR outbuf[256]={0};
17424
17425 wifi_getApATMSta(index, outbuf, sizeof(outbuf));
17426 printf("sta air time percent is %s \n", outbuf);
17427 return 0;
17428 }
developera3511852023-06-14 14:12:59 +080017429 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17430 return 0;
developer72fb0bb2023-01-11 09:46:29 +080017431}
17432
17433#endif
17434
17435#ifdef WIFI_HAL_VERSION_3
17436
developer32f2a182023-06-27 19:50:41 +080017437INT BitMapToTransmitRates(UINT bitMap, char *BasicRate, unsigned long size)
developer72fb0bb2023-01-11 09:46:29 +080017438{
developera3511852023-06-14 14:12:59 +080017439 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer32f2a182023-06-27 19:50:41 +080017440 if (bitMap & WIFI_BITRATE_1MBPS) {
17441 if ((size - strlen(BasicRate)) <= 2)
17442 return RETURN_ERR;
17443 strncat(BasicRate, "1,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17444 }
17445 if (bitMap & WIFI_BITRATE_2MBPS) {
17446 if ((size - strlen(BasicRate)) <= 2)
17447 return RETURN_ERR;
17448 strncat(BasicRate, "2,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17449 }
17450 if (bitMap & WIFI_BITRATE_5_5MBPS) {
17451 if ((size - strlen(BasicRate)) <= 4)
17452 return RETURN_ERR;
17453 strncat(BasicRate, "5.5,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17454 }
17455 if (bitMap & WIFI_BITRATE_6MBPS) {
17456 if ((size - strlen(BasicRate)) <= 2)
17457 return RETURN_ERR;
17458 strncat(BasicRate, "6,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17459 }
17460 if (bitMap & WIFI_BITRATE_9MBPS) {
17461 if ((size - strlen(BasicRate)) <= 2)
17462 return RETURN_ERR;
17463 strncat(BasicRate, "9,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17464 }
17465 if (bitMap & WIFI_BITRATE_11MBPS) {
17466 if ((size - strlen(BasicRate)) <= 3)
17467 return RETURN_ERR;
17468 strncat(BasicRate, "11,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17469 }
17470 if (bitMap & WIFI_BITRATE_12MBPS) {
17471 if ((size - strlen(BasicRate)) <= 3)
17472 return RETURN_ERR;
17473 strncat(BasicRate, "12,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17474 }
17475 if (bitMap & WIFI_BITRATE_18MBPS) {
17476 if ((size - strlen(BasicRate)) <= 3)
17477 return RETURN_ERR;
17478 strncat(BasicRate, "18,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17479 }
17480 if (bitMap & WIFI_BITRATE_24MBPS) {
17481 if ((size - strlen(BasicRate)) <= 3)
17482 return RETURN_ERR;
17483 strncat(BasicRate, "24,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17484 }
17485 if (bitMap & WIFI_BITRATE_36MBPS) {
17486 if ((size - strlen(BasicRate)) <= 3)
17487 return RETURN_ERR;
17488 strncat(BasicRate, "36,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17489 }
17490 if (bitMap & WIFI_BITRATE_48MBPS) {
17491 if ((size - strlen(BasicRate)) <= 3)
17492 return RETURN_ERR;
17493 strncat(BasicRate, "48,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17494 }
17495 if (bitMap & WIFI_BITRATE_54MBPS) {
17496 if ((size - strlen(BasicRate)) <= 3)
17497 return RETURN_ERR;
17498 strncat(BasicRate, "54,", sizeof(BasicRate) - strlen(BasicRate) - 1);
17499 }
developera3511852023-06-14 14:12:59 +080017500 if (strlen(BasicRate) != 0) // remove last comma
17501 BasicRate[strlen(BasicRate) - 1] = '\0';
17502 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17503 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017504}
17505
17506INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
17507{
developera3511852023-06-14 14:12:59 +080017508 UINT BitMap = 0;
17509 char *rate;
developer72fb0bb2023-01-11 09:46:29 +080017510
developera3511852023-06-14 14:12:59 +080017511 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17512 rate = strtok(BasicRatesList, ",");
17513 while(rate != NULL)
17514 {
17515 if (strcmp(rate, "1") == 0)
17516 BitMap |= WIFI_BITRATE_1MBPS;
17517 else if (strcmp(rate, "2") == 0)
17518 BitMap |= WIFI_BITRATE_2MBPS;
17519 else if (strcmp(rate, "5.5") == 0)
17520 BitMap |= WIFI_BITRATE_5_5MBPS;
17521 else if (strcmp(rate, "6") == 0)
17522 BitMap |= WIFI_BITRATE_6MBPS;
17523 else if (strcmp(rate, "9") == 0)
17524 BitMap |= WIFI_BITRATE_9MBPS;
17525 else if (strcmp(rate, "11") == 0)
17526 BitMap |= WIFI_BITRATE_11MBPS;
17527 else if (strcmp(rate, "12") == 0)
17528 BitMap |= WIFI_BITRATE_12MBPS;
17529 else if (strcmp(rate, "18") == 0)
17530 BitMap |= WIFI_BITRATE_18MBPS;
17531 else if (strcmp(rate, "24") == 0)
17532 BitMap |= WIFI_BITRATE_24MBPS;
17533 else if (strcmp(rate, "36") == 0)
17534 BitMap |= WIFI_BITRATE_36MBPS;
17535 else if (strcmp(rate, "48") == 0)
17536 BitMap |= WIFI_BITRATE_48MBPS;
17537 else if (strcmp(rate, "54") == 0)
17538 BitMap |= WIFI_BITRATE_54MBPS;
17539 rate = strtok(NULL, ",");
17540 }
17541 *basicRateBitMap = BitMap;
17542 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17543 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017544}
17545
17546// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
17547INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
17548{
developera3511852023-06-14 14:12:59 +080017549 char buf[128] = {0};
17550 int bandwidth = 20;
17551 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080017552 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developera3511852023-06-14 14:12:59 +080017553 wifi_radio_operationParam_t current_param;
developer72fb0bb2023-01-11 09:46:29 +080017554
developera3511852023-06-14 14:12:59 +080017555 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017556
developera3511852023-06-14 14:12:59 +080017557 multiple_set = TRUE;
17558 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017559 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingParameters return error.\n");
developera3511852023-06-14 14:12:59 +080017560 return RETURN_ERR;
17561 }
17562 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
17563 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017564 wifi_debug(DEBUG_ERROR, "wifi_setRadioAutoChannelEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017565 return RETURN_ERR;
17566 }
17567 drv_dat_change = TRUE;
17568 }
17569 if (current_param.channelWidth != operationParam->channelWidth ||
17570 current_param.channel != operationParam->channel ||
17571 current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
17572 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
17573 bandwidth = 20;
17574 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
17575 bandwidth = 40;
17576 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
17577 bandwidth = 80;
17578 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
17579 bandwidth = 160;
developer72fb0bb2023-01-11 09:46:29 +080017580
developera3511852023-06-14 14:12:59 +080017581 if (operationParam->autoChannelEnabled) {
17582 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017583 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developera3511852023-06-14 14:12:59 +080017584 return RETURN_ERR;
17585 }
17586 } else {
17587 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017588 wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
developera3511852023-06-14 14:12:59 +080017589 return RETURN_ERR;
17590 }
17591 }
developer56fbedb2023-05-30 16:47:05 +080017592 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017593 }
17594 if (current_param.variant != operationParam->variant) {
17595 // Two different definition bit map, so need to check every bit.
17596 if (operationParam->variant & WIFI_80211_VARIANT_A)
17597 set_mode |= WIFI_MODE_A;
17598 if (operationParam->variant & WIFI_80211_VARIANT_B)
17599 set_mode |= WIFI_MODE_B;
17600 if (operationParam->variant & WIFI_80211_VARIANT_G)
17601 set_mode |= WIFI_MODE_G;
17602 if (operationParam->variant & WIFI_80211_VARIANT_N)
17603 set_mode |= WIFI_MODE_N;
17604 if (operationParam->variant & WIFI_80211_VARIANT_AC)
17605 set_mode |= WIFI_MODE_AC;
17606 if (operationParam->variant & WIFI_80211_VARIANT_AX)
17607 set_mode |= WIFI_MODE_AX;
17608 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
17609 memset(buf, 0, sizeof(buf));
17610 drv_dat_change = TRUE;
17611 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017612 wifi_debug(DEBUG_ERROR, "wifi_setRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080017613 return RETURN_ERR;
17614 }
17615 }
17616 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer56fbedb2023-05-30 16:47:05 +080017617 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017618 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017619 wifi_debug(DEBUG_ERROR, "wifi_setApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017620 return RETURN_ERR;
17621 }
17622 }
17623 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer56fbedb2023-05-30 16:47:05 +080017624 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017625 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017626 wifi_debug(DEBUG_ERROR, "wifi_setRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080017627 return RETURN_ERR;
17628 }
17629 }
17630 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer56fbedb2023-05-30 16:47:05 +080017631 hapd_conf_change = TRUE;
developer32f2a182023-06-27 19:50:41 +080017632 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080017633 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017634 wifi_debug(DEBUG_ERROR, "wifi_setRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017635 return RETURN_ERR;
17636 }
17637 }
17638 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer56fbedb2023-05-30 16:47:05 +080017639 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017640 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017641 wifi_debug(DEBUG_ERROR, "wifi_setRadioFragmentationThreshold return error.\n");
developera3511852023-06-14 14:12:59 +080017642 return RETURN_ERR;
17643 }
17644 }
17645 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080017646 hapd_conf_change = TRUE;
17647 drv_dat_change = TRUE;
17648 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017649 wifi_debug(DEBUG_ERROR, "wifi_setGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017650 return RETURN_ERR;
17651 }
17652 }
17653 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080017654 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017655 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017656 wifi_debug(DEBUG_ERROR, "wifi_setRadioTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080017657 return RETURN_ERR;
17658 }
17659 }
17660 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
developer56fbedb2023-05-30 16:47:05 +080017661 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017662 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017663 wifi_debug(DEBUG_ERROR, "wifi_setApRtsThreshold return error.\n");
developera3511852023-06-14 14:12:59 +080017664 return RETURN_ERR;
17665 }
17666 }
17667 if (current_param.obssCoex != operationParam->obssCoex) {
developer56fbedb2023-05-30 16:47:05 +080017668 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080017669 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017670 wifi_debug(DEBUG_ERROR, "wifi_setRadioObssCoexistenceEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017671 return RETURN_ERR;
17672 }
17673 }
17674 if (current_param.stbcEnable != operationParam->stbcEnable) {
developer56fbedb2023-05-30 16:47:05 +080017675 hapd_conf_change = TRUE;
17676 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080017677 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017678 wifi_debug(DEBUG_ERROR, "wifi_setRadioSTBCEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017679 return RETURN_ERR;
17680 }
17681 }
17682 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
17683 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017684 wifi_debug(DEBUG_ERROR, "wifi_setRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017685 return RETURN_ERR;
17686 }
17687 }
developer72fb0bb2023-01-11 09:46:29 +080017688
developera3511852023-06-14 14:12:59 +080017689 /* only down/up interface when dat file has been changed,
17690 * if enable is true, then restart the radio.
17691 */
17692 if (drv_dat_change == TRUE) {
17693 wifi_setRadioEnable(index, FALSE);
developer56fbedb2023-05-30 16:47:05 +080017694 if (operationParam->enable == TRUE)
developera3511852023-06-14 14:12:59 +080017695 wifi_setRadioEnable(index, TRUE);
17696 } else if (hapd_conf_change == TRUE) {
17697 hostapd_raw_remove_bss(index);
17698 if (operationParam->enable == TRUE)
17699 hostapd_raw_add_bss(index);
17700 }
developer56fbedb2023-05-30 16:47:05 +080017701
developera3511852023-06-14 14:12:59 +080017702 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080017703
developera3511852023-06-14 14:12:59 +080017704 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017705}
17706
17707INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
17708{
developera3511852023-06-14 14:12:59 +080017709 char band[64] = {0};
17710 char buf[256] = {0};
17711 char config_file[64] = {0};
17712 char cmd[128] = {0};
17713 UINT mode = 0;
17714 BOOL enabled = FALSE;
developer863a4a62023-06-06 16:55:59 +080017715 int dtimPeriod;
developer2f79c922023-06-02 17:33:42 +080017716 UINT beaconInterval;
17717 UINT basicDataTransmitRates;
17718 UINT operationalDataTransmitRates;
17719 wifi_guard_interval_t guardInterval;
17720 UINT transmitPower;
developere40952c2023-06-15 18:46:43 +080017721 int res;
developer72fb0bb2023-01-11 09:46:29 +080017722
developera3511852023-06-14 14:12:59 +080017723 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
17724 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080017725
developera3511852023-06-14 14:12:59 +080017726 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
developere40952c2023-06-15 18:46:43 +080017727 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
17728 if (os_snprintf_error(sizeof(config_file), res)) {
17729 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17730 return RETURN_ERR;
17731 }
developera3511852023-06-14 14:12:59 +080017732 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
17733 {
developer75bd10c2023-06-27 11:34:08 +080017734 wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017735 return RETURN_ERR;
17736 }
17737 operationParam->enable = enabled;
developer72fb0bb2023-01-11 09:46:29 +080017738
developera3511852023-06-14 14:12:59 +080017739 memset(band, 0, sizeof(band));
17740 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
17741 {
developer75bd10c2023-06-27 11:34:08 +080017742 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingFrequencyBand return error.\n");
developera3511852023-06-14 14:12:59 +080017743 return RETURN_ERR;
17744 }
developer72fb0bb2023-01-11 09:46:29 +080017745
developera3511852023-06-14 14:12:59 +080017746 if (!strcmp(band, "2.4GHz"))
17747 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
17748 else if (!strcmp(band, "5GHz"))
17749 operationParam->band = WIFI_FREQUENCY_5_BAND;
17750 else if (!strcmp(band, "6GHz"))
17751 operationParam->band = WIFI_FREQUENCY_6_BAND;
17752 else
17753 {
developer75bd10c2023-06-27 11:34:08 +080017754 wifi_debug(DEBUG_ERROR, "cannot decode band for radio index %d ('%s')\n", index, band);
developera3511852023-06-14 14:12:59 +080017755 }
developer72fb0bb2023-01-11 09:46:29 +080017756
developera3511852023-06-14 14:12:59 +080017757 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
17758 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
17759 operationParam->channel = 0;
17760 operationParam->autoChannelEnabled = TRUE;
17761 } else {
17762 operationParam->channel = strtol(buf, NULL, 10);
17763 operationParam->autoChannelEnabled = FALSE;
17764 }
developer72fb0bb2023-01-11 09:46:29 +080017765
developera3511852023-06-14 14:12:59 +080017766 memset(buf, 0, sizeof(buf));
17767 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017768 wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
developera3511852023-06-14 14:12:59 +080017769 return RETURN_ERR;
17770 }
17771 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
17772 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
17773 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
17774 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
17775 else
17776 {
developer75bd10c2023-06-27 11:34:08 +080017777 wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", buf);
developera3511852023-06-14 14:12:59 +080017778 return false;
17779 }
developer72fb0bb2023-01-11 09:46:29 +080017780
developera3511852023-06-14 14:12:59 +080017781 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017782 wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
developera3511852023-06-14 14:12:59 +080017783 return RETURN_ERR;
17784 }
17785 // Two different definition bit map, so need to check every bit.
17786 if (mode & WIFI_MODE_A)
17787 operationParam->variant |= WIFI_80211_VARIANT_A;
17788 if (mode & WIFI_MODE_B)
17789 operationParam->variant |= WIFI_80211_VARIANT_B;
17790 if (mode & WIFI_MODE_G)
17791 operationParam->variant |= WIFI_80211_VARIANT_G;
17792 if (mode & WIFI_MODE_N)
17793 operationParam->variant |= WIFI_80211_VARIANT_N;
17794 if (mode & WIFI_MODE_AC)
17795 operationParam->variant |= WIFI_80211_VARIANT_AC;
17796 if (mode & WIFI_MODE_AX)
17797 operationParam->variant |= WIFI_80211_VARIANT_AX;
17798 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017799 wifi_debug(DEBUG_ERROR, "wifi_getRadioDCSEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017800 return RETURN_ERR;
17801 }
17802 if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017803 wifi_debug(DEBUG_ERROR, "wifi_getApDTIMInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017804 return RETURN_ERR;
17805 }
developer2f79c922023-06-02 17:33:42 +080017806 operationParam->dtimPeriod = dtimPeriod;
developera3511852023-06-14 14:12:59 +080017807 if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017808 wifi_debug(DEBUG_ERROR, "wifi_getRadioBeaconPeriod return error.\n");
developera3511852023-06-14 14:12:59 +080017809 return RETURN_ERR;
17810 }
developer2f79c922023-06-02 17:33:42 +080017811 operationParam->beaconInterval = beaconInterval;
developer72fb0bb2023-01-11 09:46:29 +080017812
developera3511852023-06-14 14:12:59 +080017813 memset(buf, 0, sizeof(buf));
17814 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017815 wifi_debug(DEBUG_ERROR, "wifi_getRadioSupportedDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017816 return RETURN_ERR;
17817 }
17818 TransmitRatesToBitMap(buf, &basicDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080017819 operationParam->basicDataTransmitRates = basicDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080017820
developera3511852023-06-14 14:12:59 +080017821 memset(buf, 0, sizeof(buf));
17822 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017823 wifi_debug(DEBUG_ERROR, "wifi_getRadioBasicDataTransmitRates return error.\n");
developera3511852023-06-14 14:12:59 +080017824 return RETURN_ERR;
17825 }
17826 TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080017827 operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080017828
developera3511852023-06-14 14:12:59 +080017829 memset(buf, 0, sizeof(buf));
17830 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
17831 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080017832
developera3511852023-06-14 14:12:59 +080017833 if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017834 wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
developera3511852023-06-14 14:12:59 +080017835 return RETURN_ERR;
17836 }
developer2f79c922023-06-02 17:33:42 +080017837 operationParam->guardInterval = guardInterval;
17838
developera3511852023-06-14 14:12:59 +080017839 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017840 wifi_debug(DEBUG_ERROR, "wifi_getRadioPercentageTransmitPower return error.\n");
developera3511852023-06-14 14:12:59 +080017841 return RETURN_ERR;
17842 }
developer2f79c922023-06-02 17:33:42 +080017843 operationParam->transmitPower = transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080017844
developera3511852023-06-14 14:12:59 +080017845 memset(buf, 0, sizeof(buf));
17846 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
17847 if (strcmp(buf, "-1") == 0) {
17848 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
17849 operationParam->ctsProtection = FALSE;
17850 } else {
17851 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
17852 operationParam->ctsProtection = TRUE;
17853 }
developer72fb0bb2023-01-11 09:46:29 +080017854
developera3511852023-06-14 14:12:59 +080017855 memset(buf, 0, sizeof(buf));
17856 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
17857 if (strcmp(buf, "0") == 0)
17858 operationParam->obssCoex = FALSE;
17859 else
17860 operationParam->obssCoex = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080017861
developere40952c2023-06-15 18:46:43 +080017862 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
17863 if (os_snprintf_error(sizeof(cmd), res)) {
17864 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
17865 return RETURN_ERR;
17866 }
developera3511852023-06-14 14:12:59 +080017867 _syscmd(cmd, buf, sizeof(buf));
17868 if (strlen(buf) != 0)
17869 operationParam->stbcEnable = TRUE;
17870 else
17871 operationParam->stbcEnable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080017872
developera3511852023-06-14 14:12:59 +080017873 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
developer75bd10c2023-06-27 11:34:08 +080017874 wifi_debug(DEBUG_ERROR, "wifi_getRadio11nGreenfieldEnable return error.\n");
developera3511852023-06-14 14:12:59 +080017875 return RETURN_ERR;
17876 }
developer72fb0bb2023-01-11 09:46:29 +080017877
developera3511852023-06-14 14:12:59 +080017878 // Below value is hardcoded
developer72fb0bb2023-01-11 09:46:29 +080017879
developera3511852023-06-14 14:12:59 +080017880 operationParam->numSecondaryChannels = 0;
17881 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
17882 operationParam->channelSecondary[i] = 0;
17883 }
17884 operationParam->csa_beacon_count = 15;
17885 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
developer72fb0bb2023-01-11 09:46:29 +080017886
developera3511852023-06-14 14:12:59 +080017887 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
17888 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017889}
17890
17891static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
17892{
developera3511852023-06-14 14:12:59 +080017893 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +080017894
developera3511852023-06-14 14:12:59 +080017895 wifi_getMaxRadioNumber(&max_radio_num);
17896 if (radioIndex >= max_radio_num) {
developer75bd10c2023-06-27 11:34:08 +080017897 wifi_debug(DEBUG_ERROR, "Wrong radio index (%d)\n", radioIndex);
developera3511852023-06-14 14:12:59 +080017898 return RETURN_ERR;
17899 }
developer72fb0bb2023-01-11 09:46:29 +080017900
developera3511852023-06-14 14:12:59 +080017901 return (arrayIndex * max_radio_num) + radioIndex;
developer72fb0bb2023-01-11 09:46:29 +080017902}
17903
developer96b38512023-02-22 11:17:45 +080017904static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
17905{
developera3511852023-06-14 14:12:59 +080017906 int max_radio_num = 0;
developer96b38512023-02-22 11:17:45 +080017907
developera3511852023-06-14 14:12:59 +080017908 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
developer96b38512023-02-22 11:17:45 +080017909 return -1;
17910
developera3511852023-06-14 14:12:59 +080017911 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080017912 if(max_radio_num == 0){
17913 return RETURN_ERR;
17914 }
developera3511852023-06-14 14:12:59 +080017915 (*radioIndex) = vapIndex % max_radio_num;
17916 (*arrayIndex) = vapIndex / max_radio_num;
developer96b38512023-02-22 11:17:45 +080017917
developera3511852023-06-14 14:12:59 +080017918 return 0;
developer96b38512023-02-22 11:17:45 +080017919}
17920
17921
developer72fb0bb2023-01-11 09:46:29 +080017922wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
developera3511852023-06-14 14:12:59 +080017923 if (strncmp(beaconRate, "1Mbps", 5) == 0)
17924 return WIFI_BITRATE_1MBPS;
17925 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
17926 return WIFI_BITRATE_2MBPS;
17927 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
17928 return WIFI_BITRATE_5_5MBPS;
17929 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
17930 return WIFI_BITRATE_6MBPS;
17931 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
17932 return WIFI_BITRATE_9MBPS;
17933 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
17934 return WIFI_BITRATE_11MBPS;
17935 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
17936 return WIFI_BITRATE_12MBPS;
17937 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
17938 return WIFI_BITRATE_18MBPS;
17939 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
17940 return WIFI_BITRATE_24MBPS;
17941 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
17942 return WIFI_BITRATE_36MBPS;
17943 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
17944 return WIFI_BITRATE_48MBPS;
17945 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
17946 return WIFI_BITRATE_54MBPS;
17947 return WIFI_BITRATE_DEFAULT;
developer72fb0bb2023-01-11 09:46:29 +080017948}
17949
developer32f2a182023-06-27 19:50:41 +080017950struct beacon_rate_2_string {
17951 wifi_bitrate_t beacon;
17952 char beacon_str[8];
17953};
17954
17955struct beacon_rate_2_string br2str[12] = {
17956 {WIFI_BITRATE_1MBPS, "1Mbps"},
17957 {WIFI_BITRATE_2MBPS, "2Mbps"},
17958 {WIFI_BITRATE_5_5MBPS, "5.5Mbps"},
17959 {WIFI_BITRATE_6MBPS, "6Mbps"},
17960 {WIFI_BITRATE_9MBPS, "9Mbps"},
17961 {WIFI_BITRATE_11MBPS, "11Mbps"},
17962 {WIFI_BITRATE_12MBPS, "12Mbps"},
17963 {WIFI_BITRATE_18MBPS, "18Mbps"},
17964 {WIFI_BITRATE_24MBPS, "24Mbps"},
17965 {WIFI_BITRATE_36MBPS, "36Mbps"},
17966 {WIFI_BITRATE_48MBPS, "48Mbps"},
17967 {WIFI_BITRATE_54MBPS, "54Mbps"}
17968};
17969
17970INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str, unsigned long str_size)
developer72fb0bb2023-01-11 09:46:29 +080017971{
developer32f2a182023-06-27 19:50:41 +080017972 int i;
17973 unsigned long len;
17974
17975 for (i = 0; i < (sizeof(br2str)/sizeof(br2str[0])); i++) {
17976 if (beacon == br2str[i].beacon) {
17977 len = strlen(br2str[i].beacon_str);
17978 if (len >= str_size)
17979 return RETURN_ERR;
17980 memcpy(beacon_str, br2str[i].beacon_str, len);
17981 beacon_str[len] = '\0';
17982 break;
17983 }
17984 }
developera3511852023-06-14 14:12:59 +080017985 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080017986}
17987
17988INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
17989{
developera3511852023-06-14 14:12:59 +080017990 INT mode = 0;
17991 INT ret = -1;
17992 UINT output = 0;
17993 int i = 0;
17994 int vap_index = 0;
17995 BOOL enabled = FALSE;
17996 char buf[32] = {0};
17997 wifi_vap_security_t security = {0};
developere40952c2023-06-15 18:46:43 +080017998 int res;
developer72fb0bb2023-01-11 09:46:29 +080017999
developera3511852023-06-14 14:12:59 +080018000 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
18001 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080018002
developera3511852023-06-14 14:12:59 +080018003 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
18004 if (ret != 0) {
developer75bd10c2023-06-27 11:34:08 +080018005 wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
developera3511852023-06-14 14:12:59 +080018006 return RETURN_ERR;
18007 }
developerfde01262023-05-22 15:15:24 +080018008
developera3511852023-06-14 14:12:59 +080018009 map->num_vaps = atoi(buf);
18010 if (map->num_vaps <= 0) {
developer75bd10c2023-06-27 11:34:08 +080018011 wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
developera3511852023-06-14 14:12:59 +080018012 return RETURN_ERR;
18013 }
developerfde01262023-05-22 15:15:24 +080018014
developera3511852023-06-14 14:12:59 +080018015 for (i = 0; i < map->num_vaps; i++)
18016 {
18017 map->vap_array[i].radio_index = index;
developer72fb0bb2023-01-11 09:46:29 +080018018
developera3511852023-06-14 14:12:59 +080018019 vap_index = array_index_to_vap_index(index, i);
18020 if (vap_index < 0)
18021 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080018022
developer9ce44382023-06-28 11:09:37 +080018023 strncpy(map->vap_array[i].bridge_name, BRIDGE_NAME,sizeof(map->vap_array[i].bridge_name) - 1);
18024 map->vap_array[i].bridge_name[sizeof(map->vap_array[i].bridge_name) - 1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080018025
developera3511852023-06-14 14:12:59 +080018026 map->vap_array[i].vap_index = vap_index;
developer72fb0bb2023-01-11 09:46:29 +080018027
developera3511852023-06-14 14:12:59 +080018028 memset(buf, 0, sizeof(buf));
18029 ret = wifi_getApName(vap_index, buf);
18030 if (ret != RETURN_OK) {
18031 printf("%s: wifi_getApName return error\n", __func__);
18032 return RETURN_ERR;
18033 }
developere40952c2023-06-15 18:46:43 +080018034 res = snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
18035 if (os_snprintf_error(sizeof(map->vap_array[i].vap_name), res)) {
18036 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18037 return RETURN_ERR;
18038 }
developer72fb0bb2023-01-11 09:46:29 +080018039
developera3511852023-06-14 14:12:59 +080018040 memset(buf, 0, sizeof(buf));
18041 ret = wifi_getSSIDName(vap_index, buf);
18042 if (ret != RETURN_OK) {
18043 printf("%s: wifi_getSSIDName return error\n", __func__);
18044 return RETURN_ERR;
18045 }
developere40952c2023-06-15 18:46:43 +080018046 res = snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
18047 if (os_snprintf_error(sizeof(map->vap_array[i].u.bss_info.ssid), res)) {
18048 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18049 return RETURN_ERR;
18050 }
developer72fb0bb2023-01-11 09:46:29 +080018051
developera3511852023-06-14 14:12:59 +080018052 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080018053
developera3511852023-06-14 14:12:59 +080018054 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
18055 if (ret != RETURN_OK) {
18056 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
18057 return RETURN_ERR;
18058 }
18059 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080018060
developera3511852023-06-14 14:12:59 +080018061 ret = wifi_getApIsolationEnable(vap_index, &enabled);
18062 if (ret != RETURN_OK) {
18063 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
18064 return RETURN_ERR;
18065 }
18066 map->vap_array[i].u.bss_info.isolation = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018067
developera3511852023-06-14 14:12:59 +080018068 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
18069 if (ret != RETURN_OK) {
18070 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
18071 return RETURN_ERR;
18072 }
18073 map->vap_array[i].u.bss_info.bssMaxSta = output;
developer72fb0bb2023-01-11 09:46:29 +080018074
developera3511852023-06-14 14:12:59 +080018075 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
18076 if (ret != RETURN_OK) {
18077 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
18078 return RETURN_ERR;
18079 }
18080 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018081
developera3511852023-06-14 14:12:59 +080018082 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
18083 if (ret != RETURN_OK) {
18084 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
18085 return RETURN_ERR;
18086 }
18087 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018088
developera3511852023-06-14 14:12:59 +080018089 ret = wifi_getApSecurity(vap_index, &security);
18090 if (ret != RETURN_OK) {
18091 printf("%s: wifi_getApSecurity return error\n", __func__);
18092 return RETURN_ERR;
18093 }
18094 map->vap_array[i].u.bss_info.security = security;
developer72fb0bb2023-01-11 09:46:29 +080018095
developera3511852023-06-14 14:12:59 +080018096 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
18097 if (ret != RETURN_OK) {
18098 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
18099 return RETURN_ERR;
18100 }
18101 if (mode == 0)
18102 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
18103 else
18104 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
18105 if (mode == 1)
18106 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
18107 else if (mode == 2)
18108 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
developer72fb0bb2023-01-11 09:46:29 +080018109
developera3511852023-06-14 14:12:59 +080018110 ret = wifi_getApWmmEnable(vap_index, &enabled);
18111 if (ret != RETURN_OK) {
18112 printf("%s: wifi_getApWmmEnable return error\n", __func__);
18113 return RETURN_ERR;
18114 }
18115 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018116
developera3511852023-06-14 14:12:59 +080018117 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
18118 if (ret != RETURN_OK) {
18119 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
18120 return RETURN_ERR;
18121 }
18122 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018123
developera3511852023-06-14 14:12:59 +080018124 memset(buf, 0, sizeof(buf));
18125 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
18126 if (ret != RETURN_OK) {
18127 printf("%s: wifi_getApBeaconRate return error\n", __func__);
18128 return RETURN_ERR;
18129 }
18130 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
developer72fb0bb2023-01-11 09:46:29 +080018131
developera3511852023-06-14 14:12:59 +080018132 memset(buf, 0, sizeof(buf));
18133 ret = wifi_getBaseBSSID(vap_index, buf);
18134 if (ret != RETURN_OK) {
18135 printf("%s: wifi_getBaseBSSID return error\n", __func__);
18136 return RETURN_ERR;
18137 }
developer5b2f10c2023-05-25 17:02:21 +080018138 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
18139 printf("%s: hwaddr_aton2 fail\n", __func__);
developera3511852023-06-14 14:12:59 +080018140 return RETURN_ERR;
developer5b2f10c2023-05-25 17:02:21 +080018141 }
developer72fb0bb2023-01-11 09:46:29 +080018142
developera3511852023-06-14 14:12:59 +080018143 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
18144 if (ret != RETURN_OK) {
18145 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
18146 return RETURN_ERR;
18147 }
18148 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
developer72fb0bb2023-01-11 09:46:29 +080018149
developera3511852023-06-14 14:12:59 +080018150 // TODO: wps, noack
18151 }
18152 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18153 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018154}
18155
developer47cc27a2023-05-17 23:09:58 +080018156void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080018157{
developera3511852023-06-14 14:12:59 +080018158 char if_name[16] = {0};
18159 char cmd[128] = {0};
18160 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080018161 int res;
developer72fb0bb2023-01-11 09:46:29 +080018162
developera3511852023-06-14 14:12:59 +080018163 *enable = FALSE;
18164 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
18165 return;
developer72fb0bb2023-01-11 09:46:29 +080018166
developere40952c2023-06-15 18:46:43 +080018167 res = snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
18168 if (os_snprintf_error(sizeof(cmd), res)) {
18169 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18170 return;
18171 }
developera3511852023-06-14 14:12:59 +080018172 _syscmd(cmd, buf, sizeof(buf));
18173 if (strlen(buf) > 0)
18174 *enable = TRUE;
18175 return;
developer72fb0bb2023-01-11 09:46:29 +080018176}
18177
developer56fbedb2023-05-30 16:47:05 +080018178int hostapd_manage_bss(INT apIndex, BOOL enable)
18179{
18180 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080018181 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer56fbedb2023-05-30 16:47:05 +080018182 char cmd[MAX_CMD_SIZE] = {0};
18183 char buf[MAX_BUF_SIZE] = {0};
18184 BOOL status = FALSE;
18185 int max_radio_num = 0;
18186 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080018187 int res;
developer56fbedb2023-05-30 16:47:05 +080018188
18189 wifi_getApEnable(apIndex, &status);
18190
18191 wifi_getMaxRadioNumber(&max_radio_num);
18192 if (enable == status)
18193 return RETURN_OK;
18194
18195 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
18196 return RETURN_ERR;
18197
18198 if (enable == TRUE) {
18199 int radioIndex = apIndex % max_radio_num;
18200 phyId = radio_index_to_phy(radioIndex);
18201 fprintf(stderr, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080018202 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
18203 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18204 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18205 return RETURN_ERR;
18206 }
18207 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
18208 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18209 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18210 return RETURN_ERR;
18211 }
developer56fbedb2023-05-30 16:47:05 +080018212 _syscmd(cmd, buf, sizeof(buf));
18213 } else {
18214 fprintf(stderr, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080018215 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
18216 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18217 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18218 return RETURN_ERR;
18219 }
developer56fbedb2023-05-30 16:47:05 +080018220 _syscmd(cmd, buf, sizeof(buf));
18221 }
developere40952c2023-06-15 18:46:43 +080018222 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer56fbedb2023-05-30 16:47:05 +080018223 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +080018224 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
18225 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18226 return RETURN_ERR;
18227 }
developer56fbedb2023-05-30 16:47:05 +080018228 _syscmd(cmd, buf, sizeof(buf));
18229 //Wait for wifi up/down to apply
18230 return RETURN_OK;
18231}
18232
18233int hostapd_raw_add_bss(int apIndex)
18234{
18235 return hostapd_manage_bss(apIndex, TRUE);
18236}
18237
18238int hostapd_raw_remove_bss(int apIndex)
18239{
18240 return hostapd_manage_bss(apIndex, FALSE);
18241}
18242
18243int hostapd_raw_restart_bss(int apIndex)
developer333c1eb2023-05-31 14:59:39 +080018244{
developerdaf24792023-06-06 11:40:04 +080018245 int ret = 0;
18246
18247 ret = hostapd_raw_remove_bss(apIndex);
18248 if(ret != RETURN_OK)
18249 return RETURN_ERR;
18250
18251 ret = hostapd_raw_add_bss(apIndex);
18252 if(ret != RETURN_OK)
18253 return RETURN_ERR;
18254
18255 return RETURN_OK;
developer56fbedb2023-05-30 16:47:05 +080018256}
18257
developer72fb0bb2023-01-11 09:46:29 +080018258INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
18259{
developera3511852023-06-14 14:12:59 +080018260 unsigned int i;
18261 wifi_vap_info_t *vap_info = NULL;
18262 int acl_mode;
18263 int ret = 0;
18264 char buf[256] = {0};
18265 char cmd[128] = {0};
18266 char config_file[64] = {0};
18267 char psk_file[64] = {0};
18268 BOOL enable = FALSE;
18269 int band_idx;
developere40952c2023-06-15 18:46:43 +080018270 int res;
developere740c2a2023-05-23 18:34:32 +080018271
developer72fb0bb2023-01-11 09:46:29 +080018272
developera3511852023-06-14 14:12:59 +080018273 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
18274 printf("Entering %s index = %d\n", __func__, (int)index);
18275 for (i = 0; i < map->num_vaps; i++)
18276 {
18277 multiple_set = TRUE;
18278 vap_info = &map->vap_array[i];
developer72fb0bb2023-01-11 09:46:29 +080018279
developera3511852023-06-14 14:12:59 +080018280 // Check vap status file to enable multiple ap if the system boot.
18281 checkVapStatus(vap_info->vap_index, &enable);
18282 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
18283 continue;
developer72fb0bb2023-01-11 09:46:29 +080018284
developer75bd10c2023-06-27 11:34:08 +080018285 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 +080018286
developera3511852023-06-14 14:12:59 +080018287 band_idx = radio_index_to_band(index);
developere40952c2023-06-15 18:46:43 +080018288 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
18289 if (os_snprintf_error(sizeof(config_file), res)) {
18290 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18291 return RETURN_ERR;
18292 }
developer9ce44382023-06-28 11:09:37 +080018293 if(band_idx >= 0 && band_idx < sizeof(wifi_band_str)/sizeof(wifi_band_str[0])){
18294 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
18295 } else{
18296 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18297 return RETURN_ERR;
18298 }
developere40952c2023-06-15 18:46:43 +080018299 if (os_snprintf_error(sizeof(cmd), res)) {
18300 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18301 return RETURN_ERR;
18302 }
developera3511852023-06-14 14:12:59 +080018303 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080018304
developera3511852023-06-14 14:12:59 +080018305 struct params params[3];
18306 params[0].name = "interface";
18307 params[0].value = vap_info->vap_name;
developere40952c2023-06-15 18:46:43 +080018308 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
18309 if (os_snprintf_error(sizeof(psk_file), res)) {
18310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18311 return RETURN_ERR;
18312 }
developera3511852023-06-14 14:12:59 +080018313 params[1].name = "wpa_psk_file";
18314 params[1].value = psk_file;
18315 params[2].name = "ssid";
18316 params[2].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080018317
developer37646972023-06-29 10:58:43 +080018318 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
18319 if (os_snprintf_error(sizeof(config_file), res)) {
18320 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18321 return RETURN_ERR;
18322 }
developera3511852023-06-14 14:12:59 +080018323 wifi_hostapdWrite(config_file, params, 3);
developer72fb0bb2023-01-11 09:46:29 +080018324
developere40952c2023-06-15 18:46:43 +080018325 res = snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
18326 if (os_snprintf_error(sizeof(cmd), res)) {
18327 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18328 return RETURN_ERR;
18329 }
developera3511852023-06-14 14:12:59 +080018330 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080018331
developera3511852023-06-14 14:12:59 +080018332 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
18333 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018334 wifi_debug(DEBUG_ERROR,"wifi_setSSIDName return error\n");
developera3511852023-06-14 14:12:59 +080018335 return RETURN_ERR;
18336 }
developer72fb0bb2023-01-11 09:46:29 +080018337
developera3511852023-06-14 14:12:59 +080018338 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
18339 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018340 wifi_debug(DEBUG_ERROR, "wifi_setApSsidAdvertisementEnable return error\n");
developera3511852023-06-14 14:12:59 +080018341 return RETURN_ERR;
18342 }
developer72fb0bb2023-01-11 09:46:29 +080018343
developera3511852023-06-14 14:12:59 +080018344 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
18345 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018346 wifi_debug(DEBUG_ERROR, "wifi_setApIsolationEnable return error\n");
developera3511852023-06-14 14:12:59 +080018347 return RETURN_ERR;
18348 }
developer72fb0bb2023-01-11 09:46:29 +080018349
developera3511852023-06-14 14:12:59 +080018350 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
18351 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018352 wifi_debug(DEBUG_ERROR, "wifi_setApMaxAssociatedDevices return error\n");
developera3511852023-06-14 14:12:59 +080018353 return RETURN_ERR;
18354 }
developer72fb0bb2023-01-11 09:46:29 +080018355
developera3511852023-06-14 14:12:59 +080018356 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
18357 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018358 wifi_debug(DEBUG_ERROR, "wifi_setBSSTransitionActivation return error\n");
developera3511852023-06-14 14:12:59 +080018359 return RETURN_ERR;
18360 }
developer72fb0bb2023-01-11 09:46:29 +080018361
developera3511852023-06-14 14:12:59 +080018362 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
18363 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018364 wifi_debug(DEBUG_ERROR, "wifi_setNeighborReportActivation return error\n");
developera3511852023-06-14 14:12:59 +080018365 return RETURN_ERR;
18366 }
developer72fb0bb2023-01-11 09:46:29 +080018367
developera3511852023-06-14 14:12:59 +080018368 if (vap_info->u.bss_info.mac_filter_enable == false){
18369 acl_mode = 0;
18370 }else {
18371 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
18372 acl_mode = 2;
developere40952c2023-06-15 18:46:43 +080018373 res = snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
18374 if (os_snprintf_error(sizeof(cmd), res)) {
18375 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18376 return RETURN_ERR;
18377 }
developera3511852023-06-14 14:12:59 +080018378 _syscmd(cmd, buf, sizeof(buf));
18379 }else{
18380 acl_mode = 1;
18381 }
18382 }
developer72fb0bb2023-01-11 09:46:29 +080018383
developera3511852023-06-14 14:12:59 +080018384 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
18385 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018386 wifi_debug(DEBUG_ERROR, "wifi_setApWmmEnable return error\n");
developera3511852023-06-14 14:12:59 +080018387 return RETURN_ERR;
18388 }
developer72fb0bb2023-01-11 09:46:29 +080018389
developera3511852023-06-14 14:12:59 +080018390 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
18391 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018392 wifi_debug(DEBUG_ERROR, "wifi_setApWmmUapsdEnable return error\n");
developera3511852023-06-14 14:12:59 +080018393 return RETURN_ERR;
18394 }
developer72fb0bb2023-01-11 09:46:29 +080018395
developera3511852023-06-14 14:12:59 +080018396 memset(buf, 0, sizeof(buf));
developer32f2a182023-06-27 19:50:41 +080018397 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +080018398 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
18399 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018400 wifi_debug(DEBUG_ERROR, "wifi_setApBeaconRate return error\n");
developera3511852023-06-14 14:12:59 +080018401 return RETURN_ERR;
18402 }
developer72fb0bb2023-01-11 09:46:29 +080018403
developera3511852023-06-14 14:12:59 +080018404 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
18405 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018406 wifi_debug(DEBUG_ERROR, "wifi_setRadioIGMPSnoopingEnable\n");
developera3511852023-06-14 14:12:59 +080018407 return RETURN_ERR;
18408 }
developer72fb0bb2023-01-11 09:46:29 +080018409
developera3511852023-06-14 14:12:59 +080018410 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
18411 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018412 wifi_debug(DEBUG_ERROR, "wifi_setApSecurity return error\n");
developera3511852023-06-14 14:12:59 +080018413 return RETURN_ERR;
18414 }
developer333c1eb2023-05-31 14:59:39 +080018415
developer56fbedb2023-05-30 16:47:05 +080018416 hostapd_raw_restart_bss(vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080018417
developera3511852023-06-14 14:12:59 +080018418 multiple_set = FALSE;
developer23e71282023-01-18 10:25:19 +080018419
developera3511852023-06-14 14:12:59 +080018420 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
18421 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
18422 if (ret != RETURN_OK) {
developer86035662023-06-28 19:21:12 +080018423 wifi_debug(DEBUG_ERROR, "wifi_setApMacAddressControlMode return error\n");
developera3511852023-06-14 14:12:59 +080018424 return RETURN_ERR;
18425 }
developer72fb0bb2023-01-11 09:46:29 +080018426
developera3511852023-06-14 14:12:59 +080018427 // TODO mgmtPowerControl, interworking, wps
18428 }
18429 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18430 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018431}
18432
18433int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
18434{
developera3511852023-06-14 14:12:59 +080018435 char *token, *next;
18436 const char s[2] = ",";
18437 int count =0;
developer72fb0bb2023-01-11 09:46:29 +080018438
developera3511852023-06-14 14:12:59 +080018439 /* get the first token */
18440 token = strtok_r(pchannels, s, &next);
developer72fb0bb2023-01-11 09:46:29 +080018441
developera3511852023-06-14 14:12:59 +080018442 /* walk through other tokens */
18443 while( token != NULL && count < MAX_CHANNELS) {
18444 chlistptr->channels_list[count++] = atoi(token);
18445 token = strtok_r(NULL, s, &next);
18446 }
developer72fb0bb2023-01-11 09:46:29 +080018447
developera3511852023-06-14 14:12:59 +080018448 return count;
developer72fb0bb2023-01-11 09:46:29 +080018449}
18450
18451static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
18452{
developera3511852023-06-14 14:12:59 +080018453 INT status;
18454 wifi_channels_list_t *chlistp;
18455 CHAR output_string[64];
18456 CHAR pchannels[128];
18457 CHAR interface_name[16] = {0};
18458 wifi_band band;
developere40952c2023-06-15 18:46:43 +080018459 int res;
developer72fb0bb2023-01-11 09:46:29 +080018460
developera3511852023-06-14 14:12:59 +080018461 if(rcap == NULL)
18462 {
18463 return RETURN_ERR;
18464 }
developer72fb0bb2023-01-11 09:46:29 +080018465
developera3511852023-06-14 14:12:59 +080018466 rcap->numSupportedFreqBand = 1;
18467 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080018468
developera3511852023-06-14 14:12:59 +080018469 if (band == band_2_4)
18470 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
18471 else if (band == band_5)
18472 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
18473 else if (band == band_6)
18474 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
developer72fb0bb2023-01-11 09:46:29 +080018475
developera3511852023-06-14 14:12:59 +080018476 chlistp = &(rcap->channel_list[0]);
18477 memset(pchannels, 0, sizeof(pchannels));
developer72fb0bb2023-01-11 09:46:29 +080018478
developera3511852023-06-14 14:12:59 +080018479 /* possible number of radio channels */
18480 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
18481 {
18482 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
18483 }
18484 /* Number of channels and list*/
18485 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
developer72fb0bb2023-01-11 09:46:29 +080018486
developera3511852023-06-14 14:12:59 +080018487 /* autoChannelSupported */
18488 /* always ON with wifi_getRadioAutoChannelSupported */
18489 rcap->autoChannelSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018490
developera3511852023-06-14 14:12:59 +080018491 /* DCSSupported */
18492 /* always ON with wifi_getRadioDCSSupported */
18493 rcap->DCSSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018494
developera3511852023-06-14 14:12:59 +080018495 /* zeroDFSSupported - TBD */
18496 rcap->zeroDFSSupported = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018497
developera3511852023-06-14 14:12:59 +080018498 /* Supported Country List*/
18499 memset(output_string, 0, sizeof(output_string));
18500 status = wifi_getRadioCountryCode(radioIndex, output_string);
18501 if( status != 0 ) {
18502 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
18503 return RETURN_ERR;
18504 } else {
18505 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
18506 }
18507 if(!strcmp(output_string,"US")){
18508 rcap->countrySupported[0] = wifi_countrycode_US;
18509 rcap->countrySupported[1] = wifi_countrycode_CA;
18510 } else if (!strcmp(output_string,"CA")) {
18511 rcap->countrySupported[0] = wifi_countrycode_CA;
18512 rcap->countrySupported[1] = wifi_countrycode_US;
18513 } else {
18514 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
18515 }
developer72fb0bb2023-01-11 09:46:29 +080018516
developera3511852023-06-14 14:12:59 +080018517 rcap->numcountrySupported = 2;
developer72fb0bb2023-01-11 09:46:29 +080018518
developera3511852023-06-14 14:12:59 +080018519 /* csi */
18520 rcap->csi.maxDevices = 8;
18521 rcap->csi.soudingFrameSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080018522
developer86035662023-06-28 19:21:12 +080018523 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) {
18524 wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
18525 }
developere40952c2023-06-15 18:46:43 +080018526 res = snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
18527 if (os_snprintf_error(sizeof(interface_name), res)) {
18528 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18529 return RETURN_ERR;
18530 }
developer72fb0bb2023-01-11 09:46:29 +080018531
developera3511852023-06-14 14:12:59 +080018532 /* channelWidth - all supported bandwidths */
18533 int i=0;
18534 rcap->channelWidth[i] = 0;
18535 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
18536 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
18537 WIFI_CHANNELBANDWIDTH_40MHZ);
developer72fb0bb2023-01-11 09:46:29 +080018538
developera3511852023-06-14 14:12:59 +080018539 }
18540 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
18541 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
18542 WIFI_CHANNELBANDWIDTH_40MHZ |
18543 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
18544 }
developer72fb0bb2023-01-11 09:46:29 +080018545
18546
developera3511852023-06-14 14:12:59 +080018547 /* mode - all supported variants */
18548 // rcap->mode[i] = WIFI_80211_VARIANT_H;
18549 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
18550 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
18551 }
18552 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
18553 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
18554 }
18555 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
18556 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
18557 }
18558 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
18559 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
developer72fb0bb2023-01-11 09:46:29 +080018560
developera3511852023-06-14 14:12:59 +080018561 /* supportedBitRate - all supported bitrates */
18562 rcap->supportedBitRate[i] = 0;
18563 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
18564 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
18565 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
18566 }
18567 else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
18568 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
18569 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
18570 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
18571 }
developer72fb0bb2023-01-11 09:46:29 +080018572
18573
developera3511852023-06-14 14:12:59 +080018574 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
18575 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
18576 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
18577 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
18578 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
18579 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
18580 rcap->cipherSupported = 0;
18581 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
18582 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
developer72fb0bb2023-01-11 09:46:29 +080018583
developera3511852023-06-14 14:12:59 +080018584 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018585}
18586
18587INT wifi_getHalCapability(wifi_hal_capability_t *cap)
18588{
developera3511852023-06-14 14:12:59 +080018589 INT status = 0, radioIndex = 0;
18590 char output[MAX_BUF_SIZE] = {0};
18591 int iter = 0;
18592 unsigned int j = 0;
developer9ce44382023-06-28 11:09:37 +080018593 int max_num_radios = 0;
developera3511852023-06-14 14:12:59 +080018594 wifi_interface_name_idex_map_t *iface_info = NULL;
developer72fb0bb2023-01-11 09:46:29 +080018595
developera3511852023-06-14 14:12:59 +080018596 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018597
developera3511852023-06-14 14:12:59 +080018598 memset(cap, 0, sizeof(wifi_hal_capability_t));
developer72fb0bb2023-01-11 09:46:29 +080018599
developera3511852023-06-14 14:12:59 +080018600 /* version */
18601 cap->version.major = WIFI_HAL_MAJOR_VERSION;
18602 cap->version.minor = WIFI_HAL_MINOR_VERSION;
developer72fb0bb2023-01-11 09:46:29 +080018603
developera3511852023-06-14 14:12:59 +080018604 /* number of radios platform property */
18605 wifi_getMaxRadioNumber(&max_num_radios);
18606 cap->wifi_prop.numRadios = max_num_radios;
developer72fb0bb2023-01-11 09:46:29 +080018607
developera3511852023-06-14 14:12:59 +080018608 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
18609 {
18610 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
18611 if (status != 0) {
18612 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
18613 return RETURN_ERR;
18614 }
developer72fb0bb2023-01-11 09:46:29 +080018615
developera3511852023-06-14 14:12:59 +080018616 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
18617 {
18618 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
18619 {
18620 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
18621 return RETURN_ERR;
18622 }
18623 iface_info = &cap->wifi_prop.interface_map[iter];
18624 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
18625 iface_info->rdk_radio_index = radioIndex;
18626 memset(output, 0, sizeof(output));
18627 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
18628 {
18629 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
18630 }
18631 // TODO: bridge name
18632 // TODO: vlan id
18633 // TODO: primary
18634 iface_info->index = array_index_to_vap_index(radioIndex, j);
18635 memset(output, 0, sizeof(output));
18636 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
18637 {
18638 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
18639 }
18640 iter++;
18641 }
18642 }
developer72fb0bb2023-01-11 09:46:29 +080018643
developera3511852023-06-14 14:12:59 +080018644 cap->BandSteeringSupported = FALSE;
18645 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
18646 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018647}
18648
18649INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
18650{
developera3511852023-06-14 14:12:59 +080018651 struct params h_config={0};
18652 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018653 int res;
developer72fb0bb2023-01-11 09:46:29 +080018654
developera3511852023-06-14 14:12:59 +080018655 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018656
developera3511852023-06-14 14:12:59 +080018657 h_config.name = "okc";
18658 h_config.value = okc_enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018659
developere40952c2023-06-15 18:46:43 +080018660 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18661 if (os_snprintf_error(sizeof(config_file), res)) {
18662 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18663 return RETURN_ERR;
18664 }
developera3511852023-06-14 14:12:59 +080018665 wifi_hostapdWrite(config_file, &h_config, 1);
18666 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018667
developera3511852023-06-14 14:12:59 +080018668 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18669 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018670}
18671
18672INT wifi_setSAEMFP(int ap_index, BOOL enable)
18673{
developera3511852023-06-14 14:12:59 +080018674 struct params h_config={0};
18675 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018676 int res;
developer72fb0bb2023-01-11 09:46:29 +080018677
developera3511852023-06-14 14:12:59 +080018678 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018679
developera3511852023-06-14 14:12:59 +080018680 h_config.name = "sae_require_mfp";
18681 h_config.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018682
developere40952c2023-06-15 18:46:43 +080018683 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18684 if (os_snprintf_error(sizeof(config_file), res)) {
18685 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18686 return RETURN_ERR;
18687 }
developera3511852023-06-14 14:12:59 +080018688 wifi_hostapdWrite(config_file, &h_config, 1);
18689 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018690
developera3511852023-06-14 14:12:59 +080018691 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18692 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018693}
18694
18695INT wifi_setSAEpwe(int ap_index, int sae_pwe)
18696{
developera3511852023-06-14 14:12:59 +080018697 struct params h_config={0};
18698 char config_file[64] = {0};
18699 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080018700 int res;
developer72fb0bb2023-01-11 09:46:29 +080018701
developera3511852023-06-14 14:12:59 +080018702 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018703
developera3511852023-06-14 14:12:59 +080018704 h_config.name = "sae_pwe";
developere40952c2023-06-15 18:46:43 +080018705 res = snprintf(buf, sizeof(buf), "%d", sae_pwe);
18706 if (os_snprintf_error(sizeof(buf), res)) {
18707 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18708 return RETURN_ERR;
18709 }
18710
developera3511852023-06-14 14:12:59 +080018711 h_config.value = buf;
developer72fb0bb2023-01-11 09:46:29 +080018712
developere40952c2023-06-15 18:46:43 +080018713 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18714 if (os_snprintf_error(sizeof(config_file), res)) {
18715 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18716 return RETURN_ERR;
18717 }
developera3511852023-06-14 14:12:59 +080018718 wifi_hostapdWrite(config_file, &h_config, 1);
18719 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018720
developera3511852023-06-14 14:12:59 +080018721 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18722 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018723}
18724
18725INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
18726{
developera3511852023-06-14 14:12:59 +080018727 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
18728 struct params h_config={0};
18729 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080018730 int res;
developer72fb0bb2023-01-11 09:46:29 +080018731
developera3511852023-06-14 14:12:59 +080018732 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018733
developera3511852023-06-14 14:12:59 +080018734 h_config.name = "wpa_disable_eapol_key_retries";
18735 h_config.value = disable_EAPOL_retries?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080018736
developere40952c2023-06-15 18:46:43 +080018737 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18738 if (os_snprintf_error(sizeof(config_file), res)) {
18739 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18740 return RETURN_ERR;
18741 }
developera3511852023-06-14 14:12:59 +080018742 wifi_hostapdWrite(config_file, &h_config, 1);
18743 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080018744
developera3511852023-06-14 14:12:59 +080018745 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
18746 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018747}
18748
18749INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
18750{
developera3511852023-06-14 14:12:59 +080018751 char buf[128] = {0};
18752 char config_file[128] = {0};
18753 char cmd[MAX_CMD_SIZE] = {0};
18754 char password[65] = {0};
18755 char mfp[32] = {0};
18756 char wpa_mode[32] = {0};
18757 BOOL okc_enable = FALSE;
18758 BOOL sae_MFP = FALSE;
18759 BOOL disable_EAPOL_retries = TRUE;
18760 int sae_pwe = 0;
18761 struct params params = {0};
18762 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080018763 int res;
developer72fb0bb2023-01-11 09:46:29 +080018764
developera3511852023-06-14 14:12:59 +080018765 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018766
developera3511852023-06-14 14:12:59 +080018767 multiple_set = TRUE;
developer37646972023-06-29 10:58:43 +080018768 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
18769 if (os_snprintf_error(sizeof(config_file), res)) {
18770 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18771 return RETURN_ERR;
18772 }
developera3511852023-06-14 14:12:59 +080018773 if (security->mode == wifi_security_mode_none) {
developer9ce44382023-06-28 11:09:37 +080018774 strncpy(wpa_mode, "None",sizeof(wpa_mode) - 1);
18775 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18776 } else if (security->mode == wifi_security_mode_wpa_personal) {
18777 strncpy(wpa_mode, "WPA-Personal",sizeof(wpa_mode) - 1);
18778 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18779 } else if (security->mode == wifi_security_mode_wpa2_personal){
18780 strncpy(wpa_mode, "WPA2-Personal",sizeof(wpa_mode) - 1);
18781 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18782 } else if (security->mode == wifi_security_mode_wpa_wpa2_personal){
18783 strncpy(wpa_mode, "WPA-WPA2-Personal",sizeof(wpa_mode) - 1);
18784 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18785 } else if (security->mode == wifi_security_mode_wpa_enterprise){
18786 strncpy(wpa_mode, "WPA-Enterprise",sizeof(wpa_mode) - 1);
18787 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18788 } else if (security->mode == wifi_security_mode_wpa2_enterprise){
18789 strncpy(wpa_mode, "WPA2-Enterprise",sizeof(wpa_mode) - 1);
18790 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18791 } else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise){
18792 strncpy(wpa_mode, "WPA-WAP2-Enterprise",sizeof(wpa_mode) - 1);
18793 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
18794 } else if (security->mode == wifi_security_mode_wpa3_personal) {
18795 strncpy(wpa_mode, "WPA3-Personal",sizeof(wpa_mode) - 1);
18796 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018797 okc_enable = TRUE;
18798 sae_MFP = TRUE;
18799 sae_pwe = 2;
18800 disable_EAPOL_retries = FALSE;
18801 } else if (security->mode == wifi_security_mode_wpa3_transition) {
developer9ce44382023-06-28 11:09:37 +080018802 strncpy(wpa_mode, "WPA3-Personal-Transition",sizeof(wpa_mode) - 1);
18803 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018804 okc_enable = TRUE;
18805 sae_MFP = TRUE;
18806 sae_pwe = 2;
18807 disable_EAPOL_retries = FALSE;
18808 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
developer9ce44382023-06-28 11:09:37 +080018809 strncpy(wpa_mode, "WPA3-Enterprise",sizeof(wpa_mode) - 1);
18810 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018811 sae_MFP = TRUE;
18812 sae_pwe = 2;
18813 disable_EAPOL_retries = FALSE;
18814 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer9ce44382023-06-28 11:09:37 +080018815 strncpy(wpa_mode, "OWE",sizeof(wpa_mode) - 1);
18816 wpa_mode[sizeof(wpa_mode) - 1] = '\0';
developera3511852023-06-14 14:12:59 +080018817 sae_MFP = TRUE;
18818 sae_pwe = 2;
18819 disable_EAPOL_retries = FALSE;
18820 }
developer72fb0bb2023-01-11 09:46:29 +080018821
developera3511852023-06-14 14:12:59 +080018822 band = wifi_index_to_band(ap_index);
18823 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
18824 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
18825 return RETURN_ERR;
18826 }
developer72fb0bb2023-01-11 09:46:29 +080018827
developera3511852023-06-14 14:12:59 +080018828 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
18829 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
18830 wifi_setSAEMFP(ap_index, sae_MFP);
18831 wifi_setSAEpwe(ap_index, sae_pwe);
18832 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
developer72fb0bb2023-01-11 09:46:29 +080018833
developera3511852023-06-14 14:12:59 +080018834 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
18835 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) {
18836 int key_len = strlen(security->u.key.key);
18837 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
18838 if (key_len == 64) { // set wpa_psk
18839 strncpy(password, security->u.key.key, 64); // 64 characters
18840 password[64] = '\0';
18841 wifi_setApSecurityPreSharedKey(ap_index, password);
developere40952c2023-06-15 18:46:43 +080018842 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
18843 if (os_snprintf_error(sizeof(cmd), res)) {
18844 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18845 return RETURN_ERR;
18846 }
developera3511852023-06-14 14:12:59 +080018847 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
18848 strncpy(password, security->u.key.key, 63);
18849 password[63] = '\0';
18850 wifi_setApSecurityKeyPassphrase(ap_index, password);
developere40952c2023-06-15 18:46:43 +080018851 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
developer9ce44382023-06-28 11:09:37 +080018852 if (os_snprintf_error(sizeof(cmd), res)) {
18853 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18854 return RETURN_ERR;
18855 }
developera3511852023-06-14 14:12:59 +080018856 } else
18857 return RETURN_ERR;
18858 _syscmd(cmd, buf, sizeof(buf));
18859 }
18860 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
18861 params.name = "sae_password";
18862 params.value = security->u.key.key;
18863 wifi_hostapdWrite(config_file, &params, 1);
18864 } else { // remove sae_password
developere40952c2023-06-15 18:46:43 +080018865 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
18866 if (os_snprintf_error(sizeof(cmd), res)) {
18867 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18868 return RETURN_ERR;
18869 }
developera3511852023-06-14 14:12:59 +080018870 _syscmd(cmd, buf, sizeof(buf));
18871 }
18872 }
developer72fb0bb2023-01-11 09:46:29 +080018873
developera3511852023-06-14 14:12:59 +080018874 if (security->mode != wifi_security_mode_none) {
18875 memset(&params, 0, sizeof(params));
18876 params.name = "wpa_pairwise";
18877 if (security->encr == wifi_encryption_tkip)
18878 params.value = "TKIP";
18879 else if (security->encr == wifi_encryption_aes)
18880 params.value = "CCMP";
18881 else if (security->encr == wifi_encryption_aes_tkip)
18882 params.value = "TKIP CCMP";
18883 wifi_hostapdWrite(config_file, &params, 1);
18884 }
developer72fb0bb2023-01-11 09:46:29 +080018885
developer9ce44382023-06-28 11:09:37 +080018886 if (security->mfp == wifi_mfp_cfg_disabled){
18887 strncpy(mfp,"Disabled",sizeof(mfp)-1);
18888 mfp[sizeof(mfp)-1] = '\0';
18889 } else if (security->mfp == wifi_mfp_cfg_optional){
18890 strncpy(mfp,"Optional",sizeof(mfp)-1);
18891 mfp[sizeof(mfp)-1] = '\0';
18892 } else if (security->mfp == wifi_mfp_cfg_required){
18893 strncpy(mfp,"Required",sizeof(mfp)-1);
18894 mfp[sizeof(mfp)-1] = '\0';
18895 }
developera3511852023-06-14 14:12:59 +080018896 wifi_setApSecurityMFPConfig(ap_index, mfp);
developer72fb0bb2023-01-11 09:46:29 +080018897
developera3511852023-06-14 14:12:59 +080018898 memset(&params, 0, sizeof(params));
18899 params.name = "transition_disable";
18900 if (security->wpa3_transition_disable == TRUE)
18901 params.value = "0x01";
18902 else
18903 params.value = "0x00";
18904 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018905
developera3511852023-06-14 14:12:59 +080018906 memset(&params, 0, sizeof(params));
18907 params.name = "wpa_group_rekey";
developere40952c2023-06-15 18:46:43 +080018908 res = snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
18909 if (os_snprintf_error(sizeof(buf), res)) {
18910 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18911 return RETURN_ERR;
18912 }
developera3511852023-06-14 14:12:59 +080018913 params.value = buf;
18914 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018915
developera3511852023-06-14 14:12:59 +080018916 memset(&params, 0, sizeof(params));
18917 params.name = "wpa_strict_rekey";
18918 params.value = security->strict_rekey?"1":"0";
18919 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018920
developera3511852023-06-14 14:12:59 +080018921 memset(&params, 0, sizeof(params));
18922 params.name = "wpa_pairwise_update_count";
18923 if (security->eapol_key_retries == 0)
18924 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developere40952c2023-06-15 18:46:43 +080018925 res = snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
18926 if (os_snprintf_error(sizeof(buf), res)) {
18927 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
18928 return RETURN_ERR;
18929 }
developera3511852023-06-14 14:12:59 +080018930 params.value = buf;
18931 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018932
developera3511852023-06-14 14:12:59 +080018933 memset(&params, 0, sizeof(params));
18934 params.name = "disable_pmksa_caching";
18935 params.value = security->disable_pmksa_caching?"1":"0";
18936 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080018937
developera3511852023-06-14 14:12:59 +080018938 if (multiple_set == FALSE) {
18939 wifi_setApEnable(ap_index, FALSE);
18940 wifi_setApEnable(ap_index, TRUE);
18941 }
developer72fb0bb2023-01-11 09:46:29 +080018942
developera3511852023-06-14 14:12:59 +080018943 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080018944
developera3511852023-06-14 14:12:59 +080018945 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080018946}
18947
18948INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
18949{
developera3511852023-06-14 14:12:59 +080018950 char buf[256] = {0};
18951 char config_file[128] = {0};
developer86035662023-06-28 19:21:12 +080018952 long int disable = 0;
18953 long int tmp;
developera3511852023-06-14 14:12:59 +080018954 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080018955
developera3511852023-06-14 14:12:59 +080018956 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer9ce44382023-06-28 11:09:37 +080018957 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
developera3511852023-06-14 14:12:59 +080018958 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
18959 security->mode = wifi_security_mode_none;
18960 if (strlen(buf) != 0) {
18961 if (!strcmp(buf, "WPA-Personal"))
18962 security->mode = wifi_security_mode_wpa_personal;
18963 else if (!strcmp(buf, "WPA2-Personal"))
18964 security->mode = wifi_security_mode_wpa2_personal;
18965 else if (!strcmp(buf, "WPA-WPA2-Personal"))
18966 security->mode = wifi_security_mode_wpa_wpa2_personal;
18967 else if (!strcmp(buf, "WPA-Enterprise"))
18968 security->mode = wifi_security_mode_wpa_enterprise;
18969 else if (!strcmp(buf, "WPA2-Enterprise"))
18970 security->mode = wifi_security_mode_wpa2_enterprise;
18971 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
18972 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
18973 else if (!strcmp(buf, "WPA3-Personal"))
18974 security->mode = wifi_security_mode_wpa3_personal;
18975 else if (!strcmp(buf, "WPA3-Personal-Transition"))
18976 security->mode = wifi_security_mode_wpa3_transition;
18977 else if (!strcmp(buf, "WPA3-Enterprise"))
18978 security->mode = wifi_security_mode_wpa3_enterprise;
18979 else if (!strcmp(buf, "OWE"))
18980 security->mode = wifi_security_mode_enhanced_open;
18981 }
developer72fb0bb2023-01-11 09:46:29 +080018982
developera3511852023-06-14 14:12:59 +080018983 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
18984 if (security->mode == wifi_security_mode_none)
18985 security->encr = wifi_encryption_none;
18986 else {
18987 if (strcmp(buf, "TKIP") == 0)
18988 security->encr = wifi_encryption_tkip;
18989 else if (strcmp(buf, "CCMP") == 0)
18990 security->encr = wifi_encryption_aes;
18991 else
18992 security->encr = wifi_encryption_aes_tkip;
18993 }
developer72fb0bb2023-01-11 09:46:29 +080018994
developera3511852023-06-14 14:12:59 +080018995 if (security->mode != wifi_security_mode_none) {
18996 memset(buf, 0, sizeof(buf));
18997 // wpa3 can use one or both configs as password, so we check sae_password first.
18998 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
18999 if (strlen(buf) != 0) {
19000 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
19001 security->u.key.type = wifi_security_key_type_sae;
19002 set_sae = TRUE;
19003 strncpy(security->u.key.key, buf, sizeof(buf));
19004 }
19005 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
19006 if (strlen(buf) != 0){
19007 if (set_sae == TRUE)
19008 security->u.key.type = wifi_security_key_type_psk_sae;
19009 else if (strlen(buf) == 64)
19010 security->u.key.type = wifi_security_key_type_psk;
19011 else
19012 security->u.key.type = wifi_security_key_type_pass;
19013 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
19014 }
19015 security->u.key.key[255] = '\0';
19016 }
developer72fb0bb2023-01-11 09:46:29 +080019017
developera3511852023-06-14 14:12:59 +080019018 memset(buf, 0, sizeof(buf));
19019 wifi_getApSecurityMFPConfig(ap_index, buf);
19020 if (strcmp(buf, "Disabled") == 0)
19021 security->mfp = wifi_mfp_cfg_disabled;
19022 else if (strcmp(buf, "Optional") == 0)
19023 security->mfp = wifi_mfp_cfg_optional;
19024 else if (strcmp(buf, "Required") == 0)
19025 security->mfp = wifi_mfp_cfg_required;
developer72fb0bb2023-01-11 09:46:29 +080019026
developera3511852023-06-14 14:12:59 +080019027 memset(buf, 0, sizeof(buf));
19028 security->wpa3_transition_disable = FALSE;
19029 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
developer86035662023-06-28 19:21:12 +080019030 if (hal_strtol(buf, 16, &disable) < 0) {
19031 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19032 return RETURN_ERR;
19033 }
developera3511852023-06-14 14:12:59 +080019034 if (disable != 0)
19035 security->wpa3_transition_disable = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080019036
developera3511852023-06-14 14:12:59 +080019037 memset(buf, 0, sizeof(buf));
19038 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
19039 if (strlen(buf) == 0)
19040 security->rekey_interval = 86400;
developer86035662023-06-28 19:21:12 +080019041 else {
19042 if (hal_strtol(buf, 10, &tmp) < 0) {
19043 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19044 return RETURN_ERR;
19045 }
19046 security->rekey_interval = tmp;
19047 }
developer72fb0bb2023-01-11 09:46:29 +080019048
developera3511852023-06-14 14:12:59 +080019049 memset(buf, 0, sizeof(buf));
19050 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
19051 if (strlen(buf) == 0)
19052 security->strict_rekey = 1;
developer86035662023-06-28 19:21:12 +080019053 else {
19054 if (hal_strtol(buf, 10, &tmp) < 0) {
19055 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19056 return RETURN_ERR;
19057 }
19058 security->strict_rekey = tmp;
19059 }
developer72fb0bb2023-01-11 09:46:29 +080019060
developera3511852023-06-14 14:12:59 +080019061 memset(buf, 0, sizeof(buf));
19062 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
19063 if (strlen(buf) == 0)
19064 security->eapol_key_retries = 4;
developer86035662023-06-28 19:21:12 +080019065 else {
19066 if (hal_strtol(buf, 10, &tmp) < 0) {
19067 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19068 return RETURN_ERR;
19069 }
19070 security->eapol_key_retries = tmp;
19071 }
developer72fb0bb2023-01-11 09:46:29 +080019072
developera3511852023-06-14 14:12:59 +080019073 memset(buf, 0, sizeof(buf));
19074 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
19075 if (strlen(buf) == 0)
19076 security->disable_pmksa_caching = FALSE;
developer86035662023-06-28 19:21:12 +080019077 else {
19078 if (hal_strtol(buf, 10, &(tmp)) < 0) {
19079 wifi_debug(DEBUG_ERROR, "strtol fail\n");
19080 return RETURN_ERR;
19081 }
19082 security->disable_pmksa_caching = tmp ? TRUE : FALSE;
19083 }
developera3511852023-06-14 14:12:59 +080019084 /* TODO
19085 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
19086 */
19087 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
19088 security->eap_identity_req_timeout = 0;
19089 security->eap_identity_req_retries = 0;
19090 security->eap_req_timeout = 0;
19091 security->eap_req_retries = 0;
19092 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
19093 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019094}
19095
19096#endif /* WIFI_HAL_VERSION_3 */
19097
19098#ifdef WIFI_HAL_VERSION_3_PHASE2
19099INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
19100{
developera3511852023-06-14 14:12:59 +080019101 char interface_name[16] = {0};
19102 char cmd[128] = {0};
19103 char buf[128] = {0};
19104 char *mac_addr = NULL;
19105 BOOL status = FALSE;
19106 size_t len = 0;
developer72fb0bb2023-01-11 09:46:29 +080019107
developera3511852023-06-14 14:12:59 +080019108 if(ap_index > MAX_APS)
19109 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080019110
developera3511852023-06-14 14:12:59 +080019111 *output_numDevices = 0;
19112 wifi_getApEnable(ap_index, &status);
19113 if (status == FALSE)
19114 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019115
developera3511852023-06-14 14:12:59 +080019116 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
19117 return RETURN_ERR;
19118 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
19119 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080019120
developera3511852023-06-14 14:12:59 +080019121 mac_addr = strtok(buf, "\n");
19122 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
19123 *output_numDevices = i + 1;
19124 fprintf(stderr, "mac_addr: %s\n", mac_addr);
19125 addr_ptr = output_deviceMacAddressArray[i];
19126 mac_addr_aton(addr_ptr, mac_addr);
19127 mac_addr = strtok(NULL, "\n");
19128 }
developer72fb0bb2023-01-11 09:46:29 +080019129
developera3511852023-06-14 14:12:59 +080019130 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019131}
19132#else
19133INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
19134{
developera3511852023-06-14 14:12:59 +080019135 char interface_name[16] = {0};
19136 char cmd[128];
19137 BOOL status = false;
developer75bd10c2023-06-27 11:34:08 +080019138 int res;
developer72fb0bb2023-01-11 09:46:29 +080019139
developera3511852023-06-14 14:12:59 +080019140 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
19141 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080019142
developera3511852023-06-14 14:12:59 +080019143 output_buf[0] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080019144
developera3511852023-06-14 14:12:59 +080019145 wifi_getApEnable(ap_index,&status);
19146 if (!status)
19147 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019148
developera3511852023-06-14 14:12:59 +080019149 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
19150 return RETURN_ERR;
developer75bd10c2023-06-27 11:34:08 +080019151 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
19152 if (os_snprintf_error(sizeof(cmd), res)) {
19153 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19154 return RETURN_ERR;
19155 }
19156
developera3511852023-06-14 14:12:59 +080019157 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080019158
developera3511852023-06-14 14:12:59 +080019159 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019160}
19161#endif
19162
19163INT wifi_getProxyArp(INT apIndex, BOOL *enable)
19164{
developera3511852023-06-14 14:12:59 +080019165 char output[16]={'\0'};
19166 char config_file[MAX_BUF_SIZE] = {0};
developer75bd10c2023-06-27 11:34:08 +080019167 int res;
developer72fb0bb2023-01-11 09:46:29 +080019168
developera3511852023-06-14 14:12:59 +080019169 if (!enable)
19170 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080019171
developer75bd10c2023-06-27 11:34:08 +080019172 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
19173 if (os_snprintf_error(sizeof(config_file), res)) {
19174 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19175 return RETURN_ERR;
19176 }
developera3511852023-06-14 14:12:59 +080019177 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080019178
developera3511852023-06-14 14:12:59 +080019179 if (strlen(output) == 0)
19180 *enable = FALSE;
19181 else if (strncmp(output, "1", 1) == 0)
19182 *enable = TRUE;
19183 else
19184 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080019185
developera3511852023-06-14 14:12:59 +080019186 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
19187 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019188}
19189
19190INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
19191{
developera3511852023-06-14 14:12:59 +080019192 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
19193 return RETURN_ERR;
19194 *output_enable=TRUE;
19195 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019196}
19197
19198INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
19199{
developera3511852023-06-14 14:12:59 +080019200 char cmd[128] = {0};
19201 char buf[128] = {0};
19202 char line[128] = {0};
19203 FILE *f = NULL;
19204 int index = 0;
19205 int exp = 0;
19206 int mantissa = 0;
19207 int duration = 0;
19208 int radio_index = 0;
19209 int max_radio_num = 0;
19210 uint twt_wake_interval = 0;
19211 int phyId = 0;
developer75bd10c2023-06-27 11:34:08 +080019212 int res;
19213
developera3511852023-06-14 14:12:59 +080019214 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080019215
developera3511852023-06-14 14:12:59 +080019216 wifi_getMaxRadioNumber(&max_radio_num);
developer9ce44382023-06-28 11:09:37 +080019217 if(max_radio_num == 0){
19218 return RETURN_ERR;
19219 }
developera3511852023-06-14 14:12:59 +080019220 radio_index = ap_index % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +080019221
developera3511852023-06-14 14:12:59 +080019222 phyId = radio_index_to_phy(radio_index);
developer75bd10c2023-06-27 11:34:08 +080019223
19224 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
19225 if (os_snprintf_error(sizeof(cmd), res)) {
19226 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19227 return RETURN_ERR;
19228 }
developera3511852023-06-14 14:12:59 +080019229 _syscmd(cmd, buf, sizeof(buf));
19230 *numSessionReturned = strtol(buf, NULL, 10) - 1;
19231 if (*numSessionReturned > maxNumberSessions)
19232 *numSessionReturned = maxNumberSessions;
19233 else if (*numSessionReturned < 1) {
19234 *numSessionReturned = 0;
19235 return RETURN_OK;
19236 }
developer72fb0bb2023-01-11 09:46:29 +080019237
developer75bd10c2023-06-27 11:34:08 +080019238 res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
19239 if (os_snprintf_error(sizeof(cmd), res)) {
19240 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
19241 return RETURN_ERR;
19242 }
developera3511852023-06-14 14:12:59 +080019243 if ((f = popen(cmd, "r")) == NULL) {
19244 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
19245 return RETURN_ERR;
19246 }
developer72fb0bb2023-01-11 09:46:29 +080019247
developera3511852023-06-14 14:12:59 +080019248 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
19249 while((fgets(line, sizeof(line), f)) != NULL) {
19250 char *tmp = NULL;
developer9ce44382023-06-28 11:09:37 +080019251 size_t len = strlen(line);
19252 strncpy(buf, line,len);
19253 buf[len] = '\0';
developera3511852023-06-14 14:12:59 +080019254 tmp = strtok(buf, " ");
developerd14dff12023-06-28 22:47:44 +080019255 if (tmp == NULL)
19256 break;
developera3511852023-06-14 14:12:59 +080019257 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
19258 tmp = strtok(NULL, " ");
developerd14dff12023-06-28 22:47:44 +080019259 if (tmp == NULL)
19260 break;
developera3511852023-06-14 14:12:59 +080019261 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
19262 tmp = strtok(NULL, " ");
19263 if (strstr(tmp, "t")) {
19264 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
19265 }
19266 if (strstr(tmp, "a")) {
19267 twtSessions[index].twtParameters.operation.announced = TRUE;
19268 }
19269 tmp = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080019270 if (tmp == NULL)
19271 continue;
developera3511852023-06-14 14:12:59 +080019272 exp = strtol(tmp, NULL, 10);
developer37646972023-06-29 10:58:43 +080019273 if ((tmp[0] != '\0') && (exp == 0))
19274 continue;
developera3511852023-06-14 14:12:59 +080019275 tmp = strtok(NULL, " ");
developer37646972023-06-29 10:58:43 +080019276 if (tmp == NULL)
19277 continue;
developera3511852023-06-14 14:12:59 +080019278 mantissa = strtol(tmp, NULL, 10);
developer37646972023-06-29 10:58:43 +080019279 if ((tmp[0] != '\0') && (mantissa == 0))
19280 continue;
developera3511852023-06-14 14:12:59 +080019281 tmp = strtok(NULL, " ");
19282 duration = strtol(tmp, NULL, 10);
developer37646972023-06-29 10:58:43 +080019283 if ((tmp[0] != '\0') && (duration == 0))
19284 continue;
developer72fb0bb2023-01-11 09:46:29 +080019285
developera3511852023-06-14 14:12:59 +080019286 // only implicit supported
19287 twtSessions[index].twtParameters.operation.implicit = TRUE;
19288 // only individual agreement supported
19289 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
developer72fb0bb2023-01-11 09:46:29 +080019290
developera3511852023-06-14 14:12:59 +080019291 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
19292 twt_wake_interval = mantissa * (1 << exp);
19293 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
19294 // Overflow handling
19295 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
19296 } else {
19297 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
19298 }
19299 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
19300 index++;
19301 }
developer72fb0bb2023-01-11 09:46:29 +080019302
developera3511852023-06-14 14:12:59 +080019303 pclose(f);
19304 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
19305 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080019306}
developercc5cbfb2023-06-13 18:29:52 +080019307
19308INT wifi_enableGreylistAccessControl(BOOL enable)
19309{
19310 char inf_name[IFNAMSIZ] = {0};
19311 int if_idx, ret = 0;
19312 struct nl_msg *msg = NULL;
19313 struct nlattr * msg_data = NULL;
19314 struct mtk_nl80211_param param;
19315 struct unl unl_ins;
19316 unsigned short apIndex = 0;
19317
19318 for (apIndex = 0; apIndex < MAX_APS; apIndex++) {
19319 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
19320 continue;
19321
19322 if_idx = if_nametoindex(inf_name);
19323 if (!if_idx) {
19324 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
19325 continue;
19326 }
19327
19328 /*init mtk nl80211 vendor cmd*/
19329 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
19330 param.if_type = NL80211_ATTR_IFINDEX;
19331 param.if_idx = if_idx;
19332 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
19333 if (ret) {
19334 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
19335 return RETURN_ERR;
19336 }
19337
19338 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, enable == FALSE ? 0 : 1)) {
19339 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
19340 nlmsg_free(msg);
19341 mtk_nl80211_deint(&unl_ins);
19342 continue;
19343 }
19344
19345 /*send mtk nl80211 vendor msg*/
19346 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
19347 if (ret) {
19348 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
19349 mtk_nl80211_deint(&unl_ins);
19350 continue;
19351 }
19352 /*deinit mtk nl80211 vendor msg*/
19353 mtk_nl80211_deint(&unl_ins);
19354 wifi_debug(DEBUG_NOTICE, " %s cmd success.\n", inf_name);
19355 }
19356
19357 return RETURN_OK;
19358}