blob: d5242c7f7a9ceb9fb77f76f8b9e87b60248ca632 [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>
73
developer72fb0bb2023-01-11 09:46:29 +080074#define MAC_ALEN 6
75
76#define MAX_BUF_SIZE 256
77#define MAX_CMD_SIZE 256
developerb149d9d2023-06-06 16:14:22 +080078#define MAX_SUB_CMD_SIZE 200
79
developer72fb0bb2023-01-11 09:46:29 +080080#define IF_NAME_SIZE 16
81#define CONFIG_PREFIX "/nvram/hostapd"
82#define ACL_PREFIX "/nvram/hostapd-acl"
83#define DENY_PREFIX "/nvram/hostapd-deny"
84//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
85#define SOCK_PREFIX "/var/run/hostapd/wifi"
86#define VAP_STATUS_FILE "/nvram/vap-status"
87#define ESSID_FILE "/tmp/essid"
88#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
89#define CHANNEL_STATS_FILE "/tmp/channel_stats"
90#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
91#define VLAN_FILE "/nvram/hostapd.vlan"
92#define PSK_FILE "/nvram/hostapd"
93#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080094#define POWER_PERCENTAGE "/tmp/POWER"
95#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
96/*LOGAN_DAT_FILE: may be different on customer's platform.*/
97#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +080098#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +080099
developer72fb0bb2023-01-11 09:46:29 +0800100#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +0800101#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +0800102
developer72fb0bb2023-01-11 09:46:29 +0800103#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +0800104#define BASE_PHY_INDEX 1
105#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +0800106
107/*
108 MAX_APS - Number of all AP available in system
109 2x Home AP
110 2x Backhaul AP
111 2x Guest AP
112 2x Secure Onboard AP
113 2x Service AP
114
115*/
116
117
118#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800119
120#define PREFIX_WIFI2G "ra"
121#define PREFIX_WIFI5G "rai"
122#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800123
developer47cc27a2023-05-17 23:09:58 +0800124#define PREFIX_SSID_2G "RDKB_2G"
125#define PREFIX_SSID_5G "RDKB_5G"
126#define PREFIX_SSID_6G "RDKB_6G"
127
developer72fb0bb2023-01-11 09:46:29 +0800128#ifndef RADIO_PREFIX
129#define RADIO_PREFIX "wlan"
130#endif
131
132#define MAX_ASSOCIATED_STA_NUM 2007
133
134//Uncomment to enable debug logs
135//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800136enum {
137 DEBUG_OFF = 0,
138 DEBUG_ERROR = 1,
139 DEBUG_WARN = 2,
140 DEBUG_NOTICE = 3,
141 DEBUG_INFO = 4
142};
143int wifi_debug_level = DEBUG_NOTICE;
144#define wifi_debug(level, fmt, args...) \
145{ \
146 if (level <= wifi_debug_level) \
147 { \
developer2edaf012023-05-24 14:24:53 +0800148 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800149 } \
150}
developer72fb0bb2023-01-11 09:46:29 +0800151
152#ifdef WIFI_DEBUG
153#define wifi_dbg_printf printf
154#define WIFI_ENTRY_EXIT_DEBUG printf
155#else
developer2f79c922023-06-02 17:33:42 +0800156#define wifi_dbg_printf(format, args...)
157#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
developer72fb0bb2023-01-11 09:46:29 +0800158#endif
159
160#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
161#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
162#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
163#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
164#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
165#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
166#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
167#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
168#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
169#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
170
171#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
172
173#define BW_FNAME "/nvram/bw_file.txt"
174
175#define PS_MAX_TID 16
176
developer96b38512023-02-22 11:17:45 +0800177#define MAX_CARD_INDEX 3
178
developer72fb0bb2023-01-11 09:46:29 +0800179static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
developera3511852023-06-14 14:12:59 +0800180 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
181 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
182 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
183 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
184 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
185 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
186 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
187 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
188 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
189 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
190 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
191 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
192 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
193 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
194 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
195 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
developer72fb0bb2023-01-11 09:46:29 +0800196};
197
198typedef unsigned long long u64;
199
200/* Enum to define WiFi Bands */
201typedef enum
202{
developera3511852023-06-14 14:12:59 +0800203 band_invalid = -1,
204 band_2_4 = 0,
205 band_5 = 1,
206 band_6 = 2,
developer72fb0bb2023-01-11 09:46:29 +0800207} wifi_band;
208
developer17038e62023-03-02 14:43:43 +0800209char* wifi_band_str[] = {
developera3511852023-06-14 14:12:59 +0800210 "2G",
211 "5G",
212 "6G",
developer17038e62023-03-02 14:43:43 +0800213};
214
developer72fb0bb2023-01-11 09:46:29 +0800215typedef enum {
developera3511852023-06-14 14:12:59 +0800216 WIFI_MODE_A = 0x01,
217 WIFI_MODE_B = 0x02,
218 WIFI_MODE_G = 0x04,
219 WIFI_MODE_N = 0x08,
220 WIFI_MODE_AC = 0x10,
221 WIFI_MODE_AX = 0x20,
222 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800223} wifi_ieee80211_Mode;
224
developer2f79c922023-06-02 17:33:42 +0800225typedef enum {
developera3511852023-06-14 14:12:59 +0800226 HT_BW_20,
227 HT_BW_40,
developer2f79c922023-06-02 17:33:42 +0800228} ht_config_bw;
developerd1824452023-05-18 12:30:04 +0800229
developer2f79c922023-06-02 17:33:42 +0800230typedef enum {
developera3511852023-06-14 14:12:59 +0800231 VHT_BW_2040,
232 VHT_BW_80,
233 VHT_BW_160,
234 VHT_BW_8080,
developer2f79c922023-06-02 17:33:42 +0800235} vht_config_bw;
developerd1824452023-05-18 12:30:04 +0800236
developer2f79c922023-06-02 17:33:42 +0800237typedef enum {
developera3511852023-06-14 14:12:59 +0800238 EHT_BW_20,
239 EHT_BW_40,
240 EHT_BW_80,
241 EHT_BW_160,
242 EHT_BW_320,
developer2f79c922023-06-02 17:33:42 +0800243} eht_config_bw;
developerd1824452023-05-18 12:30:04 +0800244
developer72fb0bb2023-01-11 09:46:29 +0800245#ifdef WIFI_HAL_VERSION_3
246
247// Return number of elements in array
248#ifndef ARRAY_SIZE
developera3511852023-06-14 14:12:59 +0800249#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
developer72fb0bb2023-01-11 09:46:29 +0800250#endif /* ARRAY_SIZE */
251
252#ifndef ARRAY_AND_SIZE
developera3511852023-06-14 14:12:59 +0800253#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
developer72fb0bb2023-01-11 09:46:29 +0800254#endif /* ARRAY_AND_SIZE */
255
developera3511852023-06-14 14:12:59 +0800256#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
developer72fb0bb2023-01-11 09:46:29 +0800257
258typedef struct {
developera3511852023-06-14 14:12:59 +0800259 int32_t value;
260 int32_t param;
261 intptr_t key;
262 intptr_t data;
developer72fb0bb2023-01-11 09:46:29 +0800263} wifi_secur_list;
264
265static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
266static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
developera3511852023-06-14 14:12:59 +0800267wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
268wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
269char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
developer72fb0bb2023-01-11 09:46:29 +0800270static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developer47cc27a2023-05-17 23:09:58 +0800271static void wifi_PrepareDefaultHostapdConfigs(void);
272static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800273static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800274static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer2f79c922023-06-02 17:33:42 +0800275int hostapd_raw_add_bss(int apIndex);
276int hostapd_raw_remove_bss(int apIndex);
developer47cc27a2023-05-17 23:09:58 +0800277
developercc5cbfb2023-06-13 18:29:52 +0800278static inline int os_snprintf_error(size_t size, int res)
279{
280 return res < 0 || (unsigned int) res >= size;
281}
282
developer49b17232023-05-19 16:35:19 +0800283/*type define the nl80211 call back func*/
284typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
285
286/**
287*struct mtk_nl80211_param
288* init mtk nl80211 using parameters
289* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
290* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
291* @if_idx: the index should match the interface or wiphy.
292* Note: NA
293**/
294struct mtk_nl80211_param {
295 unsigned int sub_cmd;
296 int if_type;
297 int if_idx;
298};
299
300/**
developer121a8e72023-05-22 09:19:39 +0800301*struct mtk_nl80211_cb_data
302* init mtk nl80211 call back parameters
303* @out_buf: store the mtk vendor output msg for wifi hal buffer.
304* @out_len: the output buffer length.
305* Note: NA
306**/
307struct mtk_nl80211_cb_data {
308 char * out_buf;
309 unsigned int out_len;
310};
311
312/**
developer49b17232023-05-19 16:35:19 +0800313*mtk_nl80211_init
314* init mtk nl80211 netlink and init the vendor msg common part.
315* @nl: netlink, just init it.
316* @msg: netlink message will alloc it.
317* the msg send success/fails is not free by app
318* only the nla_put etc api fails should use nlmsg_free.
319* @msg_data: vendor data msg attr pointer.
320* @param: init using interface and sub_cmd parameter.
321*
322*init the netlink context and mtk netlink vendor msg.
323*
324*return:
325* 0: success
326* other: fail
327**/
328
329int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
330 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
331 /*sanity check here*/
332 if (!nl || !param) {
333 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800334 "[%s][%d]:nl(%p) or param(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800335 __func__, __LINE__, nl, param);
336 return -1;
337 }
338 /*if_type check*/
339 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
340 (void)fprintf(stderr,
341 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
342 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
343 return -1;
344 }
345 /*init the nl*/
346 if (unl_genl_init(nl, "nl80211") < 0) {
347 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
348 __func__, __LINE__);
349 return -1;
350 }
351 /*init the msg*/
352 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
353
354 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
developera3511852023-06-14 14:12:59 +0800355 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
356 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
developer49b17232023-05-19 16:35:19 +0800357 (void)fprintf(stderr,
358 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
359 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
360 goto err;
361 }
362
363 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
364 if (!*msg_data) {
365 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
366 __func__, __LINE__);
367 goto err;
368 }
369
370 return 0;
371err:
developer49b17232023-05-19 16:35:19 +0800372 nlmsg_free(*msg);
373 unl_free(nl);
374 return -1;
375}
376
377/**
378*mtk_nl80211_send
379* set the vendor cmd call back and sent the vendor msg.
380* @nl: netlink.
381* @msg: netlink message.
382* @msg_data: vendor data msg attr pointer.
383* @handler: if the msg have call back shoud add the call back func
384* the event msg will handle by the call back func(exp:get cmd)
385* other set it as NULL(exp:set cmd).
386* @arg:call back func arg parameter.
387*add end of the netlink msg, set the call back and send msg
388*
389*return:
390* 0: success
391* other: fail
392**/
393int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
394 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
395 int ret = 0;
396 /*sanity check*/
397 if (!nl || !msg || !msg_data) {
398 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800399 "[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800400 __func__, __LINE__, nl, msg, msg_data);
401 return -1;
402 }
403 /*end the msg attr of vendor data*/
404 nla_nest_end(msg, msg_data);
405 /*send the msg and set call back */
406 ret = unl_genl_request(nl, msg, handler, arg);
407 if (ret)
408 (void)fprintf(stderr, "send nl80211 cmd fails\n");
409 return ret;
410}
411
412/**
413*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800414* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800415* @nl: netlink.
416*
developer2edaf012023-05-24 14:24:53 +0800417*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800418*
419*return:
420* 0: success
421**/
422
423int mtk_nl80211_deint(struct unl *nl) {
424 unl_free(nl);
425 return 0;
426}
427
developer72fb0bb2023-01-11 09:46:29 +0800428wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
429{
developera3511852023-06-14 14:12:59 +0800430 wifi_secur_list *item;
431 int i;
developer72fb0bb2023-01-11 09:46:29 +0800432
developera3511852023-06-14 14:12:59 +0800433 for (item = list,i = 0;i < list_sz; item++, i++) {
434 if ((int)(item->key) == key) {
435 return item;
436 }
437 }
developer72fb0bb2023-01-11 09:46:29 +0800438
developera3511852023-06-14 14:12:59 +0800439 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800440}
441
442char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
443{
developera3511852023-06-14 14:12:59 +0800444 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
developer72fb0bb2023-01-11 09:46:29 +0800445
developera3511852023-06-14 14:12:59 +0800446 if (!item) {
447 return "";
448 }
developer72fb0bb2023-01-11 09:46:29 +0800449
developera3511852023-06-14 14:12:59 +0800450 return (char *)(item->data);
developer72fb0bb2023-01-11 09:46:29 +0800451}
452
453wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
454{
developera3511852023-06-14 14:12:59 +0800455 wifi_secur_list *item;
456 int i;
developer72fb0bb2023-01-11 09:46:29 +0800457
developera3511852023-06-14 14:12:59 +0800458 for (item = list,i = 0;i < list_sz; item++, i++) {
459 if (strcmp((char *)(item->data), str) == 0) {
460 return item;
461 }
462 }
developer72fb0bb2023-01-11 09:46:29 +0800463
developera3511852023-06-14 14:12:59 +0800464 return NULL;
developer72fb0bb2023-01-11 09:46:29 +0800465}
466#endif /* WIFI_HAL_VERSION_3 */
467
developer96b38512023-02-22 11:17:45 +0800468
469static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800470char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
471char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
472#define MAX_SSID_LEN 64
473char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800474int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800475
476static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
477static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
478
developer96b38512023-02-22 11:17:45 +0800479
480static int
481get_value(const char *conf_file, const char *param, char *value, int len)
482{
developera3511852023-06-14 14:12:59 +0800483 FILE *fp;
484 int ret = -1;
485 int param_len = strlen(param);
486 int buf_len;
487 char buf[256];
developer96b38512023-02-22 11:17:45 +0800488
developera3511852023-06-14 14:12:59 +0800489 fp = fopen(conf_file, "r");
490 if (!fp) {
491 return -1;
492 }
developer96b38512023-02-22 11:17:45 +0800493
developera3511852023-06-14 14:12:59 +0800494 while (fgets(buf, sizeof(buf), fp)) {
495 buf_len = strlen(buf);
496 if (buf[buf_len - 1] == '\n') {
497 buf_len--;
498 buf[buf_len] = '\0';
499 }
500 if ((buf_len > param_len) &&
501 (strncmp(buf, param, param_len) == 0) &&
502 (buf[param_len] == '=')) {
developer96b38512023-02-22 11:17:45 +0800503
developera3511852023-06-14 14:12:59 +0800504 if (buf_len == (param_len + 1)) {
505 value[0] = '\0';
506 ret = 0;
507 } else {
508 ret = snprintf(value, len, "%s", buf + (param_len + 1));
509 }
510 fclose(fp);
511 return ret;
512 }
513 }
514 fclose(fp);
515 return -1;
developer96b38512023-02-22 11:17:45 +0800516}
517
518static int
519get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
520{
developera3511852023-06-14 14:12:59 +0800521 char buf[256];
522 int ret;
523 char *save_ptr = NULL;
524 char *tok = NULL;
developer96b38512023-02-22 11:17:45 +0800525
developera3511852023-06-14 14:12:59 +0800526 ret = get_value(conf_file, param, buf, sizeof(buf));
527 if (ret < 0)
528 return ret;
developer96b38512023-02-22 11:17:45 +0800529
developera3511852023-06-14 14:12:59 +0800530 tok = strtok_r(buf, ";", &save_ptr);
531 do {
532 if (idx == 0 || tok == NULL)
533 break;
534 else
535 idx--;
developer96b38512023-02-22 11:17:45 +0800536
developera3511852023-06-14 14:12:59 +0800537 tok = strtok_r(NULL, ";", &save_ptr);
538 } while (tok != NULL);
developer96b38512023-02-22 11:17:45 +0800539
developera3511852023-06-14 14:12:59 +0800540 if (tok) {
541 ret = snprintf(value, len, "%s", tok);
542 } else {
543 ret = 0;
544 value[0] = '\0';
545 }
developer96b38512023-02-22 11:17:45 +0800546
developera3511852023-06-14 14:12:59 +0800547 return ret;
developer96b38512023-02-22 11:17:45 +0800548}
549
550
developer72fb0bb2023-01-11 09:46:29 +0800551#ifdef HAL_NETLINK_IMPL
552typedef struct {
developera3511852023-06-14 14:12:59 +0800553 int id;
554 struct nl_sock* socket;
555 struct nl_cb* cb;
developer72fb0bb2023-01-11 09:46:29 +0800556} Netlink;
557
558static int mac_addr_aton(unsigned char *mac_addr, char *arg)
559{
developera3511852023-06-14 14:12:59 +0800560 unsigned char mac_addr_int[6]={};
561 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);
562 mac_addr[0] = mac_addr_int[0];
563 mac_addr[1] = mac_addr_int[1];
564 mac_addr[2] = mac_addr_int[2];
565 mac_addr[3] = mac_addr_int[3];
566 mac_addr[4] = mac_addr_int[4];
567 mac_addr[5] = mac_addr_int[5];
568 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800569}
570
571static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
572{
developera3511852023-06-14 14:12:59 +0800573 unsigned int mac_addr_int[6]={};
developere40952c2023-06-15 18:46:43 +0800574 int res;
575
developera3511852023-06-14 14:12:59 +0800576 mac_addr_int[0] = arg[0];
577 mac_addr_int[1] = arg[1];
578 mac_addr_int[2] = arg[2];
579 mac_addr_int[3] = arg[3];
580 mac_addr_int[4] = arg[4];
581 mac_addr_int[5] = arg[5];
developere40952c2023-06-15 18:46:43 +0800582 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]);
583 if (os_snprintf_error(20, res)) {
584 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
585 }
developera3511852023-06-14 14:12:59 +0800586 return;
developer72fb0bb2023-01-11 09:46:29 +0800587}
588
589static int ieee80211_frequency_to_channel(int freq)
590{
developera3511852023-06-14 14:12:59 +0800591 /* see 802.11-2007 17.3.8.3.2 and Annex J */
592 if (freq == 2484)
593 return 14;
594 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
595 else if (freq == 5935)
596 return 2;
597 else if (freq < 2484)
598 return (freq - 2407) / 5;
599 else if (freq >= 4910 && freq <= 4980)
600 return (freq - 4000) / 5;
601 else if (freq < 5950)
602 return (freq - 5000) / 5;
603 else if (freq <= 45000) /* DMG band lower limit */
604 /* see 802.11ax D6.1 27.3.23.2 */
605 return (freq - 5950) / 5;
606 else if (freq >= 58320 && freq <= 70200)
607 return (freq - 56160) / 2160;
608 else
609 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800610}
611
612static int initSock80211(Netlink* nl) {
developera3511852023-06-14 14:12:59 +0800613 nl->socket = nl_socket_alloc();
614 if (!nl->socket) {
615 fprintf(stderr, "Failing to allocate the sock\n");
616 return -ENOMEM;
617 }
developer72fb0bb2023-01-11 09:46:29 +0800618
developera3511852023-06-14 14:12:59 +0800619 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
developer72fb0bb2023-01-11 09:46:29 +0800620
developera3511852023-06-14 14:12:59 +0800621 if (genl_connect(nl->socket)) {
622 fprintf(stderr, "Failed to connect\n");
623 nl_close(nl->socket);
624 nl_socket_free(nl->socket);
625 return -ENOLINK;
626 }
developer72fb0bb2023-01-11 09:46:29 +0800627
developera3511852023-06-14 14:12:59 +0800628 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
629 if (nl->id< 0) {
630 fprintf(stderr, "interface not found.\n");
631 nl_close(nl->socket);
632 nl_socket_free(nl->socket);
633 return -ENOENT;
634 }
developer72fb0bb2023-01-11 09:46:29 +0800635
developera3511852023-06-14 14:12:59 +0800636 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
637 if ((!nl->cb)) {
638 fprintf(stderr, "Failed to allocate netlink callback.\n");
639 nl_close(nl->socket);
640 nl_socket_free(nl->socket);
641 return ENOMEM;
642 }
developer72fb0bb2023-01-11 09:46:29 +0800643
developera3511852023-06-14 14:12:59 +0800644 return nl->id;
developer72fb0bb2023-01-11 09:46:29 +0800645}
646
647static int nlfree(Netlink *nl)
648{
developera3511852023-06-14 14:12:59 +0800649 nl_cb_put(nl->cb);
650 nl_close(nl->socket);
651 nl_socket_free(nl->socket);
652 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800653}
654
655static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
developera3511852023-06-14 14:12:59 +0800656 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
657 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
658 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
developer72fb0bb2023-01-11 09:46:29 +0800659};
660
661static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
662};
663
664static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
665};
666
667typedef struct _wifi_channelStats_loc {
developera3511852023-06-14 14:12:59 +0800668 INT array_size;
669 INT ch_number;
670 BOOL ch_in_pool;
671 INT ch_noise;
672 BOOL ch_radar_noise;
673 INT ch_max_80211_rssi;
674 INT ch_non_80211_noise;
675 INT ch_utilization;
676 ULLONG ch_utilization_total;
677 ULLONG ch_utilization_busy;
678 ULLONG ch_utilization_busy_tx;
679 ULLONG ch_utilization_busy_rx;
680 ULLONG ch_utilization_busy_self;
681 ULLONG ch_utilization_busy_ext;
developer72fb0bb2023-01-11 09:46:29 +0800682} wifi_channelStats_t_loc;
683
684typedef struct wifi_device_info {
developera3511852023-06-14 14:12:59 +0800685 INT wifi_devIndex;
686 UCHAR wifi_devMacAddress[6];
687 CHAR wifi_devIPAddress[64];
688 BOOL wifi_devAssociatedDeviceAuthentiationState;
689 INT wifi_devSignalStrength;
690 INT wifi_devTxRate;
691 INT wifi_devRxRate;
developer72fb0bb2023-01-11 09:46:29 +0800692} wifi_device_info_t;
693
694#endif
695
696//For 5g Alias Interfaces
developer72fb0bb2023-01-11 09:46:29 +0800697static BOOL Radio_flag = TRUE;
698//wifi_setApBeaconRate(1, beaconRate);
699
700BOOL multiple_set = FALSE;
701
702struct params
703{
developera3511852023-06-14 14:12:59 +0800704 char * name;
705 char * value;
developer72fb0bb2023-01-11 09:46:29 +0800706};
707
708static int _syscmd(char *cmd, char *retBuf, int retBufSize)
709{
developera3511852023-06-14 14:12:59 +0800710 FILE *f;
711 char *ptr = retBuf;
712 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
developer72fb0bb2023-01-11 09:46:29 +0800713
developera3511852023-06-14 14:12:59 +0800714 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
715 if((f = popen(cmd, "r")) == NULL) {
716 fprintf(stderr,"\npopen %s error\n", cmd);
717 return RETURN_ERR;
718 }
developer72fb0bb2023-01-11 09:46:29 +0800719
developera3511852023-06-14 14:12:59 +0800720 while(!feof(f))
721 {
722 *ptr = 0;
723 if(bufSize>=128) {
724 bufbytes=128;
725 } else {
726 bufbytes=bufSize-1;
727 }
developer72fb0bb2023-01-11 09:46:29 +0800728
developera3511852023-06-14 14:12:59 +0800729 fgets(ptr,bufbytes,f);
730 readbytes=strlen(ptr);
developer72fb0bb2023-01-11 09:46:29 +0800731
developera3511852023-06-14 14:12:59 +0800732 if(!readbytes)
733 break;
developer72fb0bb2023-01-11 09:46:29 +0800734
developera3511852023-06-14 14:12:59 +0800735 bufSize-=readbytes;
736 ptr += readbytes;
737 }
738 cmd_ret = pclose(f);
739 retBuf[retBufSize-1]=0;
740 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800741
developera3511852023-06-14 14:12:59 +0800742 return cmd_ret >> 8;
developer72fb0bb2023-01-11 09:46:29 +0800743}
744
745INT radio_index_to_phy(int radioIndex)
746{
developera3511852023-06-14 14:12:59 +0800747 /* TODO */
748 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800749}
750
751INT wifi_getMaxRadioNumber(INT *max_radio_num)
752{
developera3511852023-06-14 14:12:59 +0800753 char cmd[64] = {0};
754 char buf[4] = {0};
developere40952c2023-06-15 18:46:43 +0800755 int res;
developera3511852023-06-14 14:12:59 +0800756 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800757
developere40952c2023-06-15 18:46:43 +0800758 res = snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
759 if (os_snprintf_error(sizeof(cmd), res)) {
760 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
761 return RETURN_ERR;
762 }
developera3511852023-06-14 14:12:59 +0800763 _syscmd(cmd, buf, sizeof(buf));
764 *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +0800765
developera3511852023-06-14 14:12:59 +0800766 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800767
developera3511852023-06-14 14:12:59 +0800768 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +0800769}
770
developer17038e62023-03-02 14:43:43 +0800771wifi_band radio_index_to_band(int radioIndex)
772{
developera3511852023-06-14 14:12:59 +0800773 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800774}
775
developer72fb0bb2023-01-11 09:46:29 +0800776wifi_band wifi_index_to_band(int apIndex)
777{
developera3511852023-06-14 14:12:59 +0800778 char cmd[128] = {0};
779 char buf[64] = {0};
780 int nl80211_band = 0;
781 int i = 0;
782 int phyIndex = 0;
783 int radioIndex = 0;
784 int max_radio_num = 0;
785 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +0800786 int res;
developer72fb0bb2023-01-11 09:46:29 +0800787
developera3511852023-06-14 14:12:59 +0800788 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +0800789
developera3511852023-06-14 14:12:59 +0800790 wifi_getMaxRadioNumber(&max_radio_num);
791 radioIndex = apIndex % max_radio_num;
792 phyIndex = radio_index_to_phy(radioIndex);
793 while(i < 10){
developere40952c2023-06-15 18:46:43 +0800794 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
795 if (os_snprintf_error(sizeof(cmd), res)) {
796 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
797 }
developera3511852023-06-14 14:12:59 +0800798 _syscmd(cmd, buf, sizeof(buf));
799 nl80211_band = strtol(buf, NULL, 10);
800 if (nl80211_band == 1)
801 band = band_2_4;
802 else if (nl80211_band == 2)
803 band = band_5;
804 else if (nl80211_band == 4) // band == 3 is 60GHz
805 band = band_6;
developer72fb0bb2023-01-11 09:46:29 +0800806
developera3511852023-06-14 14:12:59 +0800807 if(band != band_invalid)
808 break;
developer69b61b02023-03-07 17:17:44 +0800809
developera3511852023-06-14 14:12:59 +0800810 i++;
811 sleep(1);
812 }
developer72fb0bb2023-01-11 09:46:29 +0800813
developera3511852023-06-14 14:12:59 +0800814 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
815 return band;
developer72fb0bb2023-01-11 09:46:29 +0800816}
817
818static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
819{
developer7e4a2a62023-04-06 19:56:03 +0800820 char cmd[MAX_CMD_SIZE] = {0};
821 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800822 int res = 0;
developer72fb0bb2023-01-11 09:46:29 +0800823
developere40952c2023-06-15 18:46:43 +0800824 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 +0800825 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800826
developere40952c2023-06-15 18:46:43 +0800827 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
828 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
829 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +0800830 }
developere40952c2023-06-15 18:46:43 +0800831
832 res = _syscmd(cmd, buf, sizeof(buf));
833 if ((res != 0) && (strlen(buf) == 0)) {
developer7e4a2a62023-04-06 19:56:03 +0800834 printf("%s: _syscmd error!", __func__);
835 return -1;
836 }
837
developere40952c2023-06-15 18:46:43 +0800838 res = snprintf(output, output_size, "%s", buf);
839 if (os_snprintf_error(output_size, res)) {
840 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
841 return RETURN_ERR;
842 }
developer7e4a2a62023-04-06 19:56:03 +0800843
844 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800845}
846
847static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
848{
developera3511852023-06-14 14:12:59 +0800849 char cmd[MAX_CMD_SIZE] = {0};
850 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800851 int res;
developer72fb0bb2023-01-11 09:46:29 +0800852
developera3511852023-06-14 14:12:59 +0800853 for (int i = 0; i < item_count; i++) {
854 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
855 if (strlen(buf) == 0) /*no such item, insert it*/
developere40952c2023-06-15 18:46:43 +0800856 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 +0800857 else /*find the item, update it*/
developere40952c2023-06-15 18:46:43 +0800858 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 +0800859
developere40952c2023-06-15 18:46:43 +0800860 if (os_snprintf_error(sizeof(cmd), res)) {
861 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
862 return RETURN_ERR;
863 }
developera3511852023-06-14 14:12:59 +0800864 if(_syscmd(cmd, buf, sizeof(buf)))
865 return -1;
866 }
developer72fb0bb2023-01-11 09:46:29 +0800867
developera3511852023-06-14 14:12:59 +0800868 return 0;
developera1255e42023-05-13 17:45:02 +0800869}
developerfde01262023-05-22 15:15:24 +0800870
developera1255e42023-05-13 17:45:02 +0800871static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
872{
developera3511852023-06-14 14:12:59 +0800873 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +0800874 int res = 0;
developera3511852023-06-14 14:12:59 +0800875 int len;
developerfde01262023-05-22 15:15:24 +0800876
developere40952c2023-06-15 18:46:43 +0800877 res = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
878 if (os_snprintf_error(sizeof(cmd), res)) {
879 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
880 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800881 }
developerfde01262023-05-22 15:15:24 +0800882
developere40952c2023-06-15 18:46:43 +0800883
884 res = _syscmd(cmd, output, output_size);
885 if ((res != 0) && (strlen(output) == 0)) {
developera3511852023-06-14 14:12:59 +0800886 printf("%s: _syscmd error!", __func__);
887 return -1;
888 }
developera1255e42023-05-13 17:45:02 +0800889
developera3511852023-06-14 14:12:59 +0800890 len = strlen(output);
891 if ((len > 0) && (output[len - 1] == '\n')) {
892 output[len - 1] = '\0';
893 }
developerfde01262023-05-22 15:15:24 +0800894
developera3511852023-06-14 14:12:59 +0800895 return 0;
developerfde01262023-05-22 15:15:24 +0800896}
developera1255e42023-05-13 17:45:02 +0800897
developera1255e42023-05-13 17:45:02 +0800898static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
899{
developere40952c2023-06-15 18:46:43 +0800900 int res;
developera3511852023-06-14 14:12:59 +0800901 char cmd[MAX_CMD_SIZE] = {0};
902 char buf[MAX_BUF_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800903
developera3511852023-06-14 14:12:59 +0800904 for (int i = 0; i < item_count; i++) {
developere40952c2023-06-15 18:46:43 +0800905 res = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
906 if (os_snprintf_error(sizeof(cmd), res)) {
907 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
908 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +0800909 }
developera1255e42023-05-13 17:45:02 +0800910
developera3511852023-06-14 14:12:59 +0800911 if(_syscmd(cmd, buf, sizeof(buf)))
912 return -1;
913 }
developera1255e42023-05-13 17:45:02 +0800914
developera3511852023-06-14 14:12:59 +0800915 return 0;
developera1255e42023-05-13 17:45:02 +0800916}
917
developerfde01262023-05-22 15:15:24 +0800918static int wifi_l1ProfileRead(char *param, char *output, int output_size)
919{
developera3511852023-06-14 14:12:59 +0800920 int ret;
developerfde01262023-05-22 15:15:24 +0800921
developera3511852023-06-14 14:12:59 +0800922 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
923 if (!param || !output || (output_size <= 0)) {
924 fprintf(stderr, "%s: invalid parameters", __func__);
925 return RETURN_ERR;
926 }
developerfde01262023-05-22 15:15:24 +0800927
developera3511852023-06-14 14:12:59 +0800928 ret = wifi_datfileRead(l1profile, param, output, output_size);
929 if (ret != 0) {
930 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, l1profile, ret);
931 return RETURN_ERR;
932 }
developerfde01262023-05-22 15:15:24 +0800933
developera3511852023-06-14 14:12:59 +0800934 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
935 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +0800936}
937
938static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
939{
developera3511852023-06-14 14:12:59 +0800940 char option[64];
941 char card_profile_path[64];
developere40952c2023-06-15 18:46:43 +0800942 int res;
developerfde01262023-05-22 15:15:24 +0800943
developera3511852023-06-14 14:12:59 +0800944 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerfde01262023-05-22 15:15:24 +0800945
developera3511852023-06-14 14:12:59 +0800946 if (!param || !output || (output_size <= 0)) {
947 fprintf(stderr, "%s: invalid parameters", __func__);
948 return RETURN_ERR;
949 }
developerfde01262023-05-22 15:15:24 +0800950
developere40952c2023-06-15 18:46:43 +0800951 res = snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
952 if (os_snprintf_error(sizeof(option), res)) {
953 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
developera3511852023-06-14 14:12:59 +0800954 return RETURN_ERR;
955 }
developere40952c2023-06-15 18:46:43 +0800956 res = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
957 if (res != 0) {
958 fprintf(stderr, "%s: wifi_l1ProfileRead %s failed, ret:%d", __func__, option, res);
959 return RETURN_ERR;
960 }
developerfde01262023-05-22 15:15:24 +0800961
developere40952c2023-06-15 18:46:43 +0800962 res = wifi_datfileRead(card_profile_path, param, output, output_size);
963 if (res != 0) {
964 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, card_profile_path, res);
developera3511852023-06-14 14:12:59 +0800965 return RETURN_ERR;
966 }
developerfde01262023-05-22 15:15:24 +0800967
developera3511852023-06-14 14:12:59 +0800968 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
969 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +0800970}
971
972static int wifi_BandProfileRead(int card_idx,
developera3511852023-06-14 14:12:59 +0800973 int radio_idx,
974 char *param,
975 char *output,
976 int output_size,
977 char *default_value)
developerfde01262023-05-22 15:15:24 +0800978{
developera3511852023-06-14 14:12:59 +0800979 char option[64];
980 char band_profile_path[64];
developere40952c2023-06-15 18:46:43 +0800981 int ret, res;
developerfde01262023-05-22 15:15:24 +0800982
developera3511852023-06-14 14:12:59 +0800983 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
984 if (!param || !output || (output_size <= 0)) {
985 fprintf(stderr, "%s: invalid parameters", __func__);
986 return RETURN_ERR;
987 }
developerfde01262023-05-22 15:15:24 +0800988
developere40952c2023-06-15 18:46:43 +0800989 res = snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
990 if (os_snprintf_error(sizeof(option), res)) {
991 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
992 return RETURN_ERR;
993 }
developera3511852023-06-14 14:12:59 +0800994 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
995 if (ret != 0) {
996 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option, ret);
997 return RETURN_ERR;
998 }
developerfde01262023-05-22 15:15:24 +0800999
developera3511852023-06-14 14:12:59 +08001000 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1001 if (ret != 0) {
1002 if (default_value) {
developere40952c2023-06-15 18:46:43 +08001003 res = snprintf(output, output_size, "%s", default_value);
1004 if (os_snprintf_error(output_size, res)) {
1005 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1006 return RETURN_ERR;
1007 }
developera3511852023-06-14 14:12:59 +08001008 } else {
1009 output[0] = '\0';
1010 }
1011 }
developerfde01262023-05-22 15:15:24 +08001012
developera3511852023-06-14 14:12:59 +08001013 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1014 return RETURN_OK;
developerfde01262023-05-22 15:15:24 +08001015}
1016
developer72fb0bb2023-01-11 09:46:29 +08001017//For Getting Current Interface Name from corresponding hostapd configuration
1018static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1019{
developera3511852023-06-14 14:12:59 +08001020 char config_file[128] = {0};
developere40952c2023-06-15 18:46:43 +08001021 int res;
developer72fb0bb2023-01-11 09:46:29 +08001022
developera3511852023-06-14 14:12:59 +08001023 if (interface_name == NULL)
1024 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001025
developera3511852023-06-14 14:12:59 +08001026 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001027
developere40952c2023-06-15 18:46:43 +08001028 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1029 if (os_snprintf_error(sizeof(config_file), res)) {
1030 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1031 return RETURN_ERR;
1032 }
developera3511852023-06-14 14:12:59 +08001033 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1034 if (strlen(interface_name) == 0)
1035 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001036
developera3511852023-06-14 14:12:59 +08001037 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1038 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001039}
1040
developera1255e42023-05-13 17:45:02 +08001041static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1042{
developera3511852023-06-14 14:12:59 +08001043 char interface_name[IF_NAME_SIZE] = {0};
1044 char cmd[MAX_BUF_SIZE]={'\0'};
1045 char buf[MAX_CMD_SIZE]={'\0'};
1046 UCHAR channel = 0;
developere40952c2023-06-15 18:46:43 +08001047 int res;
developera1255e42023-05-13 17:45:02 +08001048
developera3511852023-06-14 14:12:59 +08001049 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1050 return RETURN_ERR;
1051 /*interface name to channel number*/
developere40952c2023-06-15 18:46:43 +08001052 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1053 if (os_snprintf_error(sizeof(cmd), res)) {
1054 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1055 return RETURN_ERR;
1056 }
1057
developera3511852023-06-14 14:12:59 +08001058 _syscmd(cmd, buf, sizeof(buf));
1059 channel = atoi(buf);
1060 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
developera1255e42023-05-13 17:45:02 +08001061 /*count dev number with the same channel*/
developere40952c2023-06-15 18:46:43 +08001062 res = snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1063 if (os_snprintf_error(sizeof(cmd), res)) {
1064 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1065 return RETURN_ERR;
1066 }
1067
developera3511852023-06-14 14:12:59 +08001068 _syscmd(cmd, buf, sizeof(buf));
1069 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1070 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1071 return RETURN_OK;
developera1255e42023-05-13 17:45:02 +08001072}
developer72fb0bb2023-01-11 09:46:29 +08001073
1074static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1075{
developera3511852023-06-14 14:12:59 +08001076 char interface_name[16] = {0};
1077 if (multiple_set == TRUE)
1078 return RETURN_OK;
1079 char cmd[MAX_CMD_SIZE]="", output[32]="";
1080 FILE *fp;
developere40952c2023-06-15 18:46:43 +08001081 int i, res;
developera3511852023-06-14 14:12:59 +08001082 //NOTE RELOAD should be done in ApplySSIDSettings
1083 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1084 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001085
1086 for (i=0; i<item_count; i++, list++) {
1087 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
1088 if (os_snprintf_error(sizeof(cmd), res)) {
1089 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1090 return RETURN_ERR;
1091 }
1092 if ((fp = popen(cmd, "r"))==NULL) {
developera3511852023-06-14 14:12:59 +08001093 perror("popen failed");
1094 return -1;
1095 }
developere40952c2023-06-15 18:46:43 +08001096 if (!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) {
1097 pclose(fp);
developera3511852023-06-14 14:12:59 +08001098 perror("fgets failed");
1099 return -1;
1100 }
developere40952c2023-06-15 18:46:43 +08001101 pclose(fp);
developera3511852023-06-14 14:12:59 +08001102 }
1103 return 0;
developer72fb0bb2023-01-11 09:46:29 +08001104}
1105
developer7e4a2a62023-04-06 19:56:03 +08001106static int wifi_quick_reload_ap(int apIndex)
1107{
1108 char interface_name[IF_NAME_SIZE] = {0};
1109 char cmd[MAX_CMD_SIZE] = {0};
1110 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001111 int res;
developer7e4a2a62023-04-06 19:56:03 +08001112
1113 if (multiple_set == TRUE)
1114 return RETURN_OK;
1115
1116 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1117 return RETURN_ERR;
1118
developere40952c2023-06-15 18:46:43 +08001119 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1120 if (os_snprintf_error(sizeof(cmd), res)) {
1121 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1122 return RETURN_ERR;
1123 }
developer7e4a2a62023-04-06 19:56:03 +08001124 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1125 return RETURN_ERR;
1126
1127 return RETURN_OK;
1128}
1129
developer72fb0bb2023-01-11 09:46:29 +08001130static int wifi_reloadAp(int apIndex)
1131{
developera3511852023-06-14 14:12:59 +08001132 char interface_name[16] = {0};
developer22e0c672023-06-07 15:25:37 +08001133 int res;
1134
developera3511852023-06-14 14:12:59 +08001135 if (multiple_set == TRUE)
1136 return RETURN_OK;
1137 char cmd[MAX_CMD_SIZE]="";
1138 char buf[MAX_BUF_SIZE]="";
developer72fb0bb2023-01-11 09:46:29 +08001139
developera3511852023-06-14 14:12:59 +08001140 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1141 return RETURN_ERR;
1142 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
developer22e0c672023-06-07 15:25:37 +08001143 if (os_snprintf_error(sizeof(cmd), res)) {
1144 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1145 return RETURN_ERR;
1146 }
developera3511852023-06-14 14:12:59 +08001147 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1148 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001149
developera3511852023-06-14 14:12:59 +08001150 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001151 if (os_snprintf_error(sizeof(cmd), res)) {
1152 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1153 return RETURN_ERR;
1154 }
developera3511852023-06-14 14:12:59 +08001155 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1156 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001157
developera3511852023-06-14 14:12:59 +08001158 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
developer22e0c672023-06-07 15:25:37 +08001159 if (os_snprintf_error(sizeof(cmd), res)) {
1160 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1161 return RETURN_ERR;
1162 }
developera3511852023-06-14 14:12:59 +08001163 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1164 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001165
developera3511852023-06-14 14:12:59 +08001166 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001167}
1168
1169INT File_Reading(CHAR *file, char *Value)
1170{
developera3511852023-06-14 14:12:59 +08001171 FILE *fp = NULL;
1172 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1173 int count = 0;
developer72fb0bb2023-01-11 09:46:29 +08001174
developera3511852023-06-14 14:12:59 +08001175 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1176 fp = popen(file,"r");
1177 if(fp == NULL)
1178 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001179
developera3511852023-06-14 14:12:59 +08001180 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1181 {
1182 for(count=0;buf[count]!='\n';count++)
1183 copy_buf[count]=buf[count];
1184 copy_buf[count]='\0';
1185 }
1186 strcpy(Value,copy_buf);
1187 pclose(fp);
1188 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001189
developera3511852023-06-14 14:12:59 +08001190 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001191}
1192
1193void wifi_RestartHostapd_2G()
1194{
developera3511852023-06-14 14:12:59 +08001195 int Public2GApIndex = 4;
developer72fb0bb2023-01-11 09:46:29 +08001196
developera3511852023-06-14 14:12:59 +08001197 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1198 wifi_setApEnable(Public2GApIndex, FALSE);
1199 wifi_setApEnable(Public2GApIndex, TRUE);
1200 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001201}
1202
1203void wifi_RestartHostapd_5G()
1204{
developera3511852023-06-14 14:12:59 +08001205 int Public5GApIndex = 5;
developer72fb0bb2023-01-11 09:46:29 +08001206
developera3511852023-06-14 14:12:59 +08001207 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1208 wifi_setApEnable(Public5GApIndex, FALSE);
1209 wifi_setApEnable(Public5GApIndex, TRUE);
1210 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001211}
1212
1213void wifi_RestartPrivateWifi_2G()
1214{
developera3511852023-06-14 14:12:59 +08001215 int PrivateApIndex = 0;
developer72fb0bb2023-01-11 09:46:29 +08001216
developera3511852023-06-14 14:12:59 +08001217 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1218 wifi_setApEnable(PrivateApIndex, FALSE);
1219 wifi_setApEnable(PrivateApIndex, TRUE);
1220 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001221}
1222
1223void wifi_RestartPrivateWifi_5G()
1224{
developera3511852023-06-14 14:12:59 +08001225 int Private5GApIndex = 1;
developer72fb0bb2023-01-11 09:46:29 +08001226
developera3511852023-06-14 14:12:59 +08001227 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1228 wifi_setApEnable(Private5GApIndex, FALSE);
1229 wifi_setApEnable(Private5GApIndex, TRUE);
1230 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001231}
1232
1233static int writeBandWidth(int radioIndex,char *bw_value)
1234{
developera3511852023-06-14 14:12:59 +08001235 char buf[MAX_BUF_SIZE];
1236 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08001237 int res;
developer72fb0bb2023-01-11 09:46:29 +08001238
developere40952c2023-06-15 18:46:43 +08001239 res = snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1240 if (os_snprintf_error(sizeof(cmd), res)) {
1241 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1242 return RETURN_ERR;
1243 }
1244
1245 if (_syscmd(cmd, buf, sizeof(buf))) {
1246 res = snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1247 if (os_snprintf_error(sizeof(cmd), res)) {
1248 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1249 return RETURN_ERR;
1250 }
developera3511852023-06-14 14:12:59 +08001251 _syscmd(cmd, buf, sizeof(buf));
1252 return RETURN_OK;
1253 }
developer72fb0bb2023-01-11 09:46:29 +08001254
developera3511852023-06-14 14:12:59 +08001255 sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1256 _syscmd(cmd,buf,sizeof(buf));
1257 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001258}
1259
1260// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1261INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1262{
developera3511852023-06-14 14:12:59 +08001263 struct params params={'\0'};
1264 char config_file[MAX_BUF_SIZE] = {0};
1265 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08001266 int res;
developer72fb0bb2023-01-11 09:46:29 +08001267
developera3511852023-06-14 14:12:59 +08001268 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1269 // Copy the numeric value
1270 if (strlen (beaconRate) >= 5) {
1271 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1272 buf[strlen(beaconRate) - 4] = '\0';
1273 } else if (strlen(beaconRate) > 0)
1274 strcpy(buf, beaconRate);
1275 else
1276 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001277
developera3511852023-06-14 14:12:59 +08001278 params.name = "beacon_rate";
1279 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1280 if (strncmp(buf, "5.5", 3) == 0) {
developere40952c2023-06-15 18:46:43 +08001281 res = snprintf(buf, sizeof(buf), "55");
1282 if (os_snprintf_error(sizeof(buf), res)) {
1283 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1284 return RETURN_ERR;
1285 }
developera3511852023-06-14 14:12:59 +08001286 params.value = buf;
1287 } else {
1288 strcat(buf, "0");
1289 params.value = buf;
1290 }
developer72fb0bb2023-01-11 09:46:29 +08001291
developera3511852023-06-14 14:12:59 +08001292 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1293 wifi_hostapdWrite(config_file, &params, 1);
1294 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1295 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001296
developera3511852023-06-14 14:12:59 +08001297 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001298}
1299
1300INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1301{
developera3511852023-06-14 14:12:59 +08001302 char config_file[128] = {'\0'};
1303 char temp_output[MAX_BUF_SIZE] = {'\0'};
1304 char buf[128] = {'\0'};
1305 char cmd[128] = {'\0'};
1306 int rate = 0;
developere40952c2023-06-15 18:46:43 +08001307 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08001308
developera3511852023-06-14 14:12:59 +08001309 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1310 if (NULL == beaconRate)
1311 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001312
developera3511852023-06-14 14:12:59 +08001313 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1314 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1315 phyId = radio_index_to_phy(radioIndex);
1316 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1317 if(strlen(buf) > 0) {
1318 if (strncmp(buf, "55", 2) == 0)
developere40952c2023-06-15 18:46:43 +08001319 res = snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
developera3511852023-06-14 14:12:59 +08001320 else {
1321 rate = strtol(buf, NULL, 10)/10;
developere40952c2023-06-15 18:46:43 +08001322 res = snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
developera3511852023-06-14 14:12:59 +08001323 }
1324 } else {
1325 // config not set, so we would use lowest rate as default
1326 sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1327 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08001328 res = snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
1329 }
1330 if (os_snprintf_error(sizeof(temp_output), res)) {
1331 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1332 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08001333 }
1334 strncpy(beaconRate, temp_output, strlen(temp_output));
1335 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001336
developera3511852023-06-14 14:12:59 +08001337 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001338}
1339
1340INT wifi_setLED(INT radioIndex, BOOL enable)
1341{
1342 return 0;
1343}
1344INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
1345{
1346 return RETURN_OK;
1347}
1348/**********************************************************************************
1349 *
developer69b61b02023-03-07 17:17:44 +08001350 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001351 *
1352**********************************************************************************/
1353//---------------------------------------------------------------------------------------------------
1354//Wifi system api
1355//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 +08001356INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001357{
developere40952c2023-06-15 18:46:43 +08001358 int res;
1359
developera3511852023-06-14 14:12:59 +08001360 if(!output_string)
1361 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08001362 res = snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1363 if (os_snprintf_error(64, res)) {
1364 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1365 return RETURN_ERR;
1366 }
developer72fb0bb2023-01-11 09:46:29 +08001367
developera3511852023-06-14 14:12:59 +08001368 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001369}
1370
1371
1372/* wifi_factoryReset() function */
1373/**
developer69b61b02023-03-07 17:17:44 +08001374* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001375* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1376*
1377* @param None
1378*
1379* @return The status of the operation.
1380* @retval RETURN_OK if successful.
1381* @retval RETURN_ERR if any error is detected
1382*
1383* @execution Synchronous
1384* @sideeffect None
1385*
1386* @note This function must not suspend and must not invoke any blocking system
1387* calls. It should probably just send a message to a driver event handler task.
1388*
1389*/
1390INT wifi_factoryReset()
1391{
developer47cc27a2023-05-17 23:09:58 +08001392 char cmd[MAX_CMD_SIZE] = {0};
1393 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001394 int res;
developer72fb0bb2023-01-11 09:46:29 +08001395
developer47cc27a2023-05-17 23:09:58 +08001396 /*delete running hostapd conf files*/
1397 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
developere40952c2023-06-15 18:46:43 +08001398 res = snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1399 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1400 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1401 return RETURN_ERR;
1402 }
1403
developer47cc27a2023-05-17 23:09:58 +08001404 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001405
developer47cc27a2023-05-17 23:09:58 +08001406 wifi_PrepareDefaultHostapdConfigs();
1407 wifi_psk_file_reset();
1408
1409 memset(cmd, 0, MAX_CMD_SIZE);
1410 memset(buf, 0, MAX_BUF_SIZE);
1411
developere40952c2023-06-15 18:46:43 +08001412 res = snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1413 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1414 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1415 return RETURN_ERR;
1416 }
1417
developer47cc27a2023-05-17 23:09:58 +08001418 _syscmd(cmd, buf, sizeof(buf));
1419
1420 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001421}
1422
1423/* wifi_factoryResetRadios() function */
1424/**
1425* @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.
1426*
1427* @param None
1428* @return The status of the operation
1429* @retval RETURN_OK if successful
1430* @retval RETURN_ERR if any error is detected
1431*
1432* @execution Synchronous
1433*
1434* @sideeffect None
1435*
1436* @note This function must not suspend and must not invoke any blocking system
1437* calls. It should probably just send a message to a driver event handler task.
1438*
1439*/
1440INT wifi_factoryResetRadios()
1441{
developera3511852023-06-14 14:12:59 +08001442 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1443 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001444
developera3511852023-06-14 14:12:59 +08001445 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001446}
1447
developerfead3972023-05-25 20:15:02 +08001448ULONG get_radio_reset_cnt(int radioIndex)
1449{
1450 char cmd[MAX_CMD_SIZE] = {0};
1451 char buf[MAX_BUF_SIZE] = {0};
1452 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001453 int res;
developerfead3972023-05-25 20:15:02 +08001454
developere40952c2023-06-15 18:46:43 +08001455 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 +08001456 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001457 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1458 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1459 return RETURN_ERR;
1460 }
1461
developerfead3972023-05-25 20:15:02 +08001462 _syscmd(cmd, buf, sizeof(buf));
1463
1464 if (strlen(buf) == 0)
1465 return 0;
1466 else {
1467 reset_count = atol(buf);
1468 return reset_count;
1469 }
1470}
1471void update_radio_reset_cnt(int radioIndex)
1472{
1473 char cmd[MAX_CMD_SIZE] = {0};
1474 char buf[MAX_BUF_SIZE] = {0};
1475 ULONG reset_count = 0;
developere40952c2023-06-15 18:46:43 +08001476 int res;
developerfead3972023-05-25 20:15:02 +08001477
developere40952c2023-06-15 18:46:43 +08001478 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 +08001479 RADIO_RESET_FILE, radioIndex);
developere40952c2023-06-15 18:46:43 +08001480 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1481 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1482 return;
1483 }
1484
developerfead3972023-05-25 20:15:02 +08001485 _syscmd(cmd, buf, sizeof(buf));
1486
1487 if (strlen(buf) == 0)
developere40952c2023-06-15 18:46:43 +08001488 res = snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
developerfead3972023-05-25 20:15:02 +08001489 else {
1490 reset_count = atol(buf);
1491 reset_count++;
developere40952c2023-06-15 18:46:43 +08001492 res = snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
1493 }
1494 if (os_snprintf_error(sizeof(cmd), res)) {
1495 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1496 return;
developerfead3972023-05-25 20:15:02 +08001497 }
1498 _syscmd(cmd, buf, sizeof(buf));
1499}
developer72fb0bb2023-01-11 09:46:29 +08001500
1501/* wifi_factoryResetRadio() function */
1502/**
1503* @description Restore selected radio parameters without touching access point parameters
1504*
1505* @param radioIndex - Index of Wi-Fi Radio channel
1506*
1507* @return The status of the operation.
1508* @retval RETURN_OK if successful.
1509* @retval RETURN_ERR if any error is detected
1510*
1511* @execution Synchronous.
1512* @sideeffect None.
1513*
1514* @note This function must not suspend and must not invoke any blocking system
1515* calls. It should probably just send a message to a driver event handler task.
1516*
1517*/
1518INT wifi_factoryResetRadio(int radioIndex) //RDKB
1519{
developer47cc27a2023-05-17 23:09:58 +08001520 char cmd[MAX_CMD_SIZE] = {0};
1521 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001522 int res;
developer72fb0bb2023-01-11 09:46:29 +08001523
developer47cc27a2023-05-17 23:09:58 +08001524 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001525
developerb2977562023-05-24 17:54:12 +08001526 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001527
developerb2977562023-05-24 17:54:12 +08001528 /*reset gi setting*/
developere40952c2023-06-15 18:46:43 +08001529 res = snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
1530 if (os_snprintf_error(sizeof(cmd), res)) {
1531 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1532 return RETURN_ERR;
1533 }
1534
developer47cc27a2023-05-17 23:09:58 +08001535 _syscmd(cmd, buf, sizeof(buf));
1536
developerb2977562023-05-24 17:54:12 +08001537 /*TBD: check mbss issue*/
1538 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08001539 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08001540
developer47cc27a2023-05-17 23:09:58 +08001541 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1542 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001543}
1544
1545/* wifi_initRadio() function */
1546/**
1547* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001548* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001549* different hardware implementations may have different initilization requirements.
1550* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1551*
1552* @return The status of the operation.
1553* @retval RETURN_OK if successful.
1554* @retval RETURN_ERR if any error is detected
1555*
1556* @execution Synchronous.
1557* @sideeffect None.
1558*
1559* @note This function must not suspend and must not invoke any blocking system
1560* calls. It should probably just send a message to a driver event handler task.
1561*
1562*/
1563INT wifi_initRadio(INT radioIndex)
1564{
developera3511852023-06-14 14:12:59 +08001565 //TODO: Initializes the wifi subsystem (for specified radio)
1566 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001567}
1568
developer17038e62023-03-02 14:43:43 +08001569static void
1570wifi_ParseProfile(void)
1571{
developere40952c2023-06-15 18:46:43 +08001572 int i, res;
developera3511852023-06-14 14:12:59 +08001573 int max_radio_num = 0;
1574 int card_idx;
1575 int band_idx;
1576 int phy_idx = 0;
1577 int wireless_mode = 0;
1578 char buf[MAX_BUF_SIZE] = {0};
1579 char chip_name[12];
1580 char card_profile[MAX_BUF_SIZE] = {0};
1581 char band_profile[MAX_BUF_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001582
developera3511852023-06-14 14:12:59 +08001583 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001584
developera3511852023-06-14 14:12:59 +08001585 memset(main_prefix, 0, sizeof(main_prefix));
1586 memset(ext_prefix, 0, sizeof(ext_prefix));
1587 memset(default_ssid, 0, sizeof(default_ssid));
1588 for (i = 0; i < MAX_NUM_RADIOS; i++)
1589 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001590
developera3511852023-06-14 14:12:59 +08001591 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1592 /* LOG */
developer17038e62023-03-02 14:43:43 +08001593 return;
developera3511852023-06-14 14:12:59 +08001594 }
developer17038e62023-03-02 14:43:43 +08001595
developera3511852023-06-14 14:12:59 +08001596 for (card_idx = 0; card_idx < 3; card_idx++) {
developere40952c2023-06-15 18:46:43 +08001597 res = snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1598 if (os_snprintf_error(sizeof(buf), res)) {
1599 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1600 return;
1601 }
developera3511852023-06-14 14:12:59 +08001602 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1603 break;
1604 }
developere40952c2023-06-15 18:46:43 +08001605 res = snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1606 if (os_snprintf_error(sizeof(buf), res)) {
1607 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1608 return;
1609 }
developera3511852023-06-14 14:12:59 +08001610 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1611 break;
1612 }
1613 for (band_idx = 0; band_idx < 3; band_idx++) {
developere40952c2023-06-15 18:46:43 +08001614 res = snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1615 if (os_snprintf_error(sizeof(buf), res)) {
1616 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1617 return;
1618 }
developera3511852023-06-14 14:12:59 +08001619 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1620 /* LOG */
1621 break;
1622 }
developer17038e62023-03-02 14:43:43 +08001623
developere40952c2023-06-15 18:46:43 +08001624 res = snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1625 if (os_snprintf_error(sizeof(buf), res)) {
1626 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1627 return;
1628 }
developera3511852023-06-14 14:12:59 +08001629 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1630 /* LOG */
1631 }
developer17038e62023-03-02 14:43:43 +08001632
developere40952c2023-06-15 18:46:43 +08001633 res = snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1634 if (os_snprintf_error(sizeof(buf), res)) {
1635 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1636 return;
1637 }
developera3511852023-06-14 14:12:59 +08001638 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1639 /* LOG */
1640 }
developer17038e62023-03-02 14:43:43 +08001641
developera3511852023-06-14 14:12:59 +08001642 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1643 /* LOG */
1644 }
1645 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1646 /* LOG */
1647 }
developer745f0bd2023-03-06 14:32:53 +08001648
developera3511852023-06-14 14:12:59 +08001649 wireless_mode = atoi(buf);
1650 switch (wireless_mode) {
1651 case 22:
1652 case 16:
1653 case 6:
1654 case 4:
1655 case 1:
1656 radio_band[phy_idx] = band_2_4;
1657 break;
1658 case 23:
1659 case 17:
1660 case 14:
1661 case 11:
1662 case 2:
1663 radio_band[phy_idx] = band_5;
1664 break;
1665 case 24:
1666 case 18:
1667 radio_band[phy_idx] = band_6;
1668 break;
1669 }
1670 phy_idx++;
1671 }
1672 }
developer17038e62023-03-02 14:43:43 +08001673
developera3511852023-06-14 14:12:59 +08001674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001675}
1676
1677static void
1678wifi_PrepareDefaultHostapdConfigs(void)
1679{
developere40952c2023-06-15 18:46:43 +08001680 int radio_idx, res;
developer0132ed92023-03-21 13:48:53 +08001681 int bss_idx;
1682 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001683 char buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001684 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer0132ed92023-03-21 13:48:53 +08001685 char ssid[MAX_BUF_SIZE] = {0};
1686 char interface[32] = {0};
1687 char ret_buf[MAX_BUF_SIZE] = {0};
1688 char psk_file[64] = {0};
1689 struct params params[3];
developer17038e62023-03-02 14:43:43 +08001690
developer0132ed92023-03-21 13:48:53 +08001691 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1692 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001693
developer0132ed92023-03-21 13:48:53 +08001694 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001695 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001696
developere40952c2023-06-15 18:46:43 +08001697 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1698 if (os_snprintf_error(sizeof(config_file), res)) {
1699 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1700 return;
1701 }
1702 res = snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
1703 if (os_snprintf_error(sizeof(buf), res)) {
1704 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1705 return;
1706 }
developer47cc27a2023-05-17 23:09:58 +08001707 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001708
developer47cc27a2023-05-17 23:09:58 +08001709 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08001710 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1711 if (os_snprintf_error(sizeof(ssid), res)) {
1712 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1713 return;
1714 }
1715 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1716 if (os_snprintf_error(sizeof(interface), res)) {
1717 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1718 return;
1719 }
developer47cc27a2023-05-17 23:09:58 +08001720 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08001721 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1722 if (os_snprintf_error(sizeof(ssid), res)) {
1723 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1724 return;
1725 }
1726 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1727 if (os_snprintf_error(sizeof(interface), res)) {
1728 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1729 return;
1730 }
developer47cc27a2023-05-17 23:09:58 +08001731 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08001732 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1733 if (os_snprintf_error(sizeof(ssid), res)) {
1734 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1735 return;
1736 }
1737 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1738 if (os_snprintf_error(sizeof(interface), res)) {
1739 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1740 return;
1741 }
developer47cc27a2023-05-17 23:09:58 +08001742 }
developer17038e62023-03-02 14:43:43 +08001743
developer47cc27a2023-05-17 23:09:58 +08001744 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08001745 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
1746 if (os_snprintf_error(sizeof(psk_file), res)) {
1747 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1748 return;
1749 }
developer17038e62023-03-02 14:43:43 +08001750
developer47cc27a2023-05-17 23:09:58 +08001751 params[0].name = "ssid";
1752 params[0].value = ssid;
1753 params[1].name = "interface";
1754 params[1].value = interface;
1755 params[2].name = "wpa_psk_file";
1756 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001757
developer47cc27a2023-05-17 23:09:58 +08001758 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001759 }
1760 }
1761 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001762}
1763
1764static void
developer17038e62023-03-02 14:43:43 +08001765wifi_BringDownInterfacesForRadio(int radio_idx)
1766{
developera3511852023-06-14 14:12:59 +08001767 char cmd[MAX_BUF_SIZE] = {0};
1768 char ret_buf[MAX_BUF_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08001769 int res;
1770
developera3511852023-06-14 14:12:59 +08001771 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001772
developere40952c2023-06-15 18:46:43 +08001773 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1774 if (os_snprintf_error(sizeof(cmd), res)) {
1775 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1776 return;
1777 }
developer8a3bbbf2023-03-15 17:47:23 +08001778 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1779
developera3511852023-06-14 14:12:59 +08001780 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001781}
1782
1783
1784static void
1785wifi_BringDownInterfaces(void)
1786{
developera3511852023-06-14 14:12:59 +08001787 int radio_idx;
1788 int band_idx;
developer17038e62023-03-02 14:43:43 +08001789
developera3511852023-06-14 14:12:59 +08001790 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1791 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1792 band_idx = radio_index_to_band(radio_idx);
1793 if (band_idx < 0) {
1794 break;
1795 }
1796 wifi_BringDownInterfacesForRadio(radio_idx);
1797 }
1798 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001799}
1800
developerb2977562023-05-24 17:54:12 +08001801static void wifi_dat_file_reset_by_radio(char radio_idx)
1802{
developerb149d9d2023-06-06 16:14:22 +08001803 char cmd[MAX_CMD_SIZE * 2] = {0};
developerb2977562023-05-24 17:54:12 +08001804 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001805 char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
1806 char dat_file[MAX_SUB_CMD_SIZE]= {0};
developere40952c2023-06-15 18:46:43 +08001807 int res;
developerb2977562023-05-24 17:54:12 +08001808
developere40952c2023-06-15 18:46:43 +08001809 res = snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1810 if (os_snprintf_error(sizeof(rom_dat_file), res)) {
1811 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1812 return;
1813 }
1814 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
1815 if (os_snprintf_error(sizeof(dat_file), res)) {
1816 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1817 return;
1818 }
1819 res = snprintf(cmd, (MAX_CMD_SIZE * 2), "cp -rf %s %s", rom_dat_file, dat_file);
1820 if (os_snprintf_error((MAX_CMD_SIZE * 2), res)) {
1821 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1822 return;
1823 }
developerb2977562023-05-24 17:54:12 +08001824 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1825
1826}
1827
developer47cc27a2023-05-17 23:09:58 +08001828static void wifi_psk_file_reset()
1829{
1830 char cmd[MAX_CMD_SIZE] = {0};
1831 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001832 char psk_file[MAX_SUB_CMD_SIZE]= {0};
developer47cc27a2023-05-17 23:09:58 +08001833 char vap_idx = 0;
developere40952c2023-06-15 18:46:43 +08001834 int res;
developer47cc27a2023-05-17 23:09:58 +08001835
1836 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
developere40952c2023-06-15 18:46:43 +08001837 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1838 if (os_snprintf_error(sizeof(psk_file), res)) {
1839 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1840 return;
1841 }
developer47cc27a2023-05-17 23:09:58 +08001842
1843 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001844 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1845 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1846 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1847 return;
1848 }
developer47cc27a2023-05-17 23:09:58 +08001849 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1850 } else {
developere40952c2023-06-15 18:46:43 +08001851 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1852 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1853 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1854 return;
1855 }
1856
developer47cc27a2023-05-17 23:09:58 +08001857 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1858 }
1859 }
developerb2977562023-05-24 17:54:12 +08001860}
1861
developer8a3bbbf2023-03-15 17:47:23 +08001862static void wifi_vap_status_reset()
1863{
developera3511852023-06-14 14:12:59 +08001864 char cmd[MAX_CMD_SIZE] = {0};
1865 char ret_buf[MAX_BUF_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08001866 int radio_idx = 0;
developer8a3bbbf2023-03-15 17:47:23 +08001867 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08001868 int res;
developer8666b312023-03-24 14:05:31 +08001869
developer8a3bbbf2023-03-15 17:47:23 +08001870 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001871 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
1872 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1873 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1874 return;
1875 }
developer8a3bbbf2023-03-15 17:47:23 +08001876 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1877 } else {
developere40952c2023-06-15 18:46:43 +08001878 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
1879 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1880 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1881 return;
1882 }
developer8a3bbbf2023-03-15 17:47:23 +08001883 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1884 }
1885
1886 memset(cmd, 0, MAX_CMD_SIZE);
1887 memset(ret_buf, 0, MAX_BUF_SIZE);
1888
1889 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
developera3511852023-06-14 14:12:59 +08001890 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developere40952c2023-06-15 18:46:43 +08001891 res = snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
1892 if (os_snprintf_error(MAX_CMD_SIZE, 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 }
1898
developerfead3972023-05-25 20:15:02 +08001899}
1900
1901static void wifi_radio_reset_count_reset()
1902{
developera3511852023-06-14 14:12:59 +08001903 char cmd[MAX_CMD_SIZE] = {0};
1904 char ret_buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08001905 int res;
developerfead3972023-05-25 20:15:02 +08001906
1907 if (access(VAP_STATUS_FILE, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08001908 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE);
1909 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1910 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1911 return;
1912 }
developerfead3972023-05-25 20:15:02 +08001913 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1914 } else {
developere40952c2023-06-15 18:46:43 +08001915 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE);
1916 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
1917 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1918 return;
1919 }
developerfead3972023-05-25 20:15:02 +08001920 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1921 }
developer8a3bbbf2023-03-15 17:47:23 +08001922}
developer17038e62023-03-02 14:43:43 +08001923
developer72fb0bb2023-01-11 09:46:29 +08001924// Initializes the wifi subsystem (all radios)
developera3511852023-06-14 14:12:59 +08001925INT wifi_init() //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001926{
developera3511852023-06-14 14:12:59 +08001927 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercc9a4f32023-05-30 17:40:02 +08001928 static int CallOnce = 1;
developera3511852023-06-14 14:12:59 +08001929 //Not intitializing macfilter for Turris-Omnia Platform for now
1930 //macfilter_init();
1931 if (CallOnce) {
developercc9a4f32023-05-30 17:40:02 +08001932 wifi_ParseProfile();
1933 wifi_PrepareDefaultHostapdConfigs();
1934 wifi_psk_file_reset();
1935 //system("/usr/sbin/iw reg set US");
1936 system("systemctl start hostapd.service");
1937 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08001938
developercc9a4f32023-05-30 17:40:02 +08001939 wifi_vap_status_reset();
1940 wifi_radio_reset_count_reset();
1941 CallOnce = 0;
developera3511852023-06-14 14:12:59 +08001942 }
developer96b38512023-02-22 11:17:45 +08001943
developera3511852023-06-14 14:12:59 +08001944 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001945
developera3511852023-06-14 14:12:59 +08001946 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001947}
1948
1949/* wifi_reset() function */
1950/**
1951* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08001952* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08001953* different hardware implementations may have different requirements.
1954* Parameters : None
1955*
1956* @return The status of the operation.
1957* @retval RETURN_OK if successful.
1958* @retval RETURN_ERR if any error is detected
1959*
1960* @execution Synchronous.
1961* @sideeffect None.
1962*
1963* @note This function must not suspend and must not invoke any blocking system
1964* calls. It should probably just send a message to a driver event handler task.
1965*
1966*/
1967INT wifi_reset()
1968{
developer17038e62023-03-02 14:43:43 +08001969
developera3511852023-06-14 14:12:59 +08001970 wifi_BringDownInterfaces();
1971 sleep(2);
developer17038e62023-03-02 14:43:43 +08001972
developera3511852023-06-14 14:12:59 +08001973 //TODO: resets the wifi subsystem, deletes all APs
1974 system("systemctl stop hostapd.service");
1975 sleep(2);
developer17038e62023-03-02 14:43:43 +08001976
developera3511852023-06-14 14:12:59 +08001977 system("systemctl start hostapd.service");
1978 sleep(5);
developer17038e62023-03-02 14:43:43 +08001979
developera3511852023-06-14 14:12:59 +08001980 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08001981 wifi_psk_file_reset();
developera3511852023-06-14 14:12:59 +08001982 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08001983
1984 wifi_vap_status_reset();
1985
developera3511852023-06-14 14:12:59 +08001986 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001987}
1988
1989/* wifi_down() function */
1990/**
1991* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08001992* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08001993* different hardware implementations may have different requirements.
1994*
1995* @param None
1996*
1997* @return The status of the operation
1998* @retval RETURN_OK if successful
1999* @retval RETURN_ERR if any error is detected
2000*
2001* @execution Synchronous
2002* @sideeffect None
2003*
2004* @note This function must not suspend and must not invoke any blocking system
2005* calls. It should probably just send a message to a driver event handler task.
2006*
2007*/
2008INT wifi_down()
2009{
developera3511852023-06-14 14:12:59 +08002010 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
2011 int max_num_radios = 0;
developerb2977562023-05-24 17:54:12 +08002012 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08002013
developerb2977562023-05-24 17:54:12 +08002014 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
2015 wifi_setRadioEnable(radioIndex, FALSE);
2016
developera3511852023-06-14 14:12:59 +08002017 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002018}
2019
2020
2021/* wifi_createInitialConfigFiles() function */
2022/**
2023* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08002024* and content of these files are implementation dependent. This function call is
2025* used to trigger this task if necessary. Some implementations may not need this
2026* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08002027* do nothing and return RETURN_OK.
2028*
2029* @param None
2030*
2031* @return The status of the operation
2032* @retval RETURN_OK if successful
2033* @retval RETURN_ERR if any error is detected
2034*
2035* @execution Synchronous
2036* @sideeffect None
2037*
2038* @note This function must not suspend and must not invoke any blocking system
2039* calls. It should probably just send a message to a driver event handler task.
2040*
2041*/
2042INT wifi_createInitialConfigFiles()
2043{
developera3511852023-06-14 14:12:59 +08002044 //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)
2045 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002046}
2047
developer7e4a2a62023-04-06 19:56:03 +08002048/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08002049INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
2050{
developera3511852023-06-14 14:12:59 +08002051 int ret;
developer72fb0bb2023-01-11 09:46:29 +08002052
developera3511852023-06-14 14:12:59 +08002053 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002054
developera3511852023-06-14 14:12:59 +08002055 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
2056 if (ret != 0) {
2057 fprintf(stderr, "%s: wifi_BandProfileRead CountryCode failed\n", __func__);
2058 return RETURN_ERR;
2059 }
developer7e4a2a62023-04-06 19:56:03 +08002060
developera3511852023-06-14 14:12:59 +08002061 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002062
developera3511852023-06-14 14:12:59 +08002063 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002064}
2065
2066INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
2067{
developer7e4a2a62023-04-06 19:56:03 +08002068 /*Set wifi config. Wait for wifi reset to apply*/
developer7e4a2a62023-04-06 19:56:03 +08002069 struct params params;
2070 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08002071 int ret = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002072
developer7e4a2a62023-04-06 19:56:03 +08002073 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002074
developer7e4a2a62023-04-06 19:56:03 +08002075 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
2076 printf("%s: input para error!!!\n", __func__);
2077 return RETURN_ERR;
2078 }
developer72fb0bb2023-01-11 09:46:29 +08002079
developerc79e9172023-06-06 19:48:03 +08002080 if (!strlen(CountryCode)) {
2081 memcpy(CountryCode, "US", strlen("US")); /*default set the code to US*/
2082 CountryCode[2] = '\0';
2083 }
developer72fb0bb2023-01-11 09:46:29 +08002084
developer7e4a2a62023-04-06 19:56:03 +08002085 params.name = "country_code";
2086 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08002087
developere40952c2023-06-15 18:46:43 +08002088 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2089 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
2090 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2091 return RETURN_ERR;
2092 }
developer7e4a2a62023-04-06 19:56:03 +08002093 ret = wifi_hostapdWrite(config_file, &params, 1);
2094
2095 if (ret) {
2096 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
2097 __func__, ret);
2098 }
2099
2100 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2101
2102 if (ret) {
2103 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
2104 __func__, ret);
2105 }
2106
2107 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2108
2109 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002110}
2111
2112INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
2113{
developera3511852023-06-14 14:12:59 +08002114 char interface_name[16] = {0};
2115 char channel_util_file[64] = {0};
2116 char cmd[128] = {0};
2117 char buf[128] = {0};
2118 char *line = NULL;
2119 char *param = NULL, *value = NULL;
developere40952c2023-06-15 18:46:43 +08002120 int read = 0, res;
developera3511852023-06-14 14:12:59 +08002121 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
2122 unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
2123 size_t len = 0;
2124 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08002125
developera3511852023-06-14 14:12:59 +08002126 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002127
developera3511852023-06-14 14:12:59 +08002128 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2129 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002130 res = snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
2131 if (os_snprintf_error(sizeof(cmd), res)) {
2132 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2133 return RETURN_ERR;
2134 }
2135
developera3511852023-06-14 14:12:59 +08002136 _syscmd(cmd, buf, sizeof(buf));
2137 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08002138
developera3511852023-06-14 14:12:59 +08002139 memset(cmd, 0, sizeof(cmd));
2140 memset(buf, 0, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08002141 res = snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
2142 if (os_snprintf_error(sizeof(cmd), res)) {
2143 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2144 return RETURN_ERR;
2145 }
developera3511852023-06-14 14:12:59 +08002146 if ((f = popen(cmd, "r")) == NULL) {
2147 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
2148 return RETURN_ERR;
2149 }
developer72fb0bb2023-01-11 09:46:29 +08002150
developera3511852023-06-14 14:12:59 +08002151 read = getline(&line, &len, f);
2152 while (read != -1) {
2153 param = strtok(line, ":\t");
2154 value = strtok(NULL, " ");
2155 if(strstr(param, "frequency") != NULL) {
2156 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
2157 }
2158 if(strstr(param, "noise") != NULL) {
2159 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
2160 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
2161 }
2162 if(strstr(param, "channel active time") != NULL) {
2163 ActiveTime = strtol(value, NULL, 10);
2164 }
2165 if(strstr(param, "channel busy time") != NULL) {
2166 BusyTime = strtol(value, NULL, 10);
2167 }
2168 if(strstr(param, "channel transmit time") != NULL) {
2169 TransmitTime = strtol(value, NULL, 10);
2170 }
2171 read = getline(&line, &len, f);
2172 }
2173 pclose(f);
developer72fb0bb2023-01-11 09:46:29 +08002174
developera3511852023-06-14 14:12:59 +08002175 // The file should store the last active, busy and transmit time
developere40952c2023-06-15 18:46:43 +08002176 res = snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2177 if (os_snprintf_error(sizeof(channel_util_file), res)) {
2178 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2179 return RETURN_ERR;
2180 }
2181
developera3511852023-06-14 14:12:59 +08002182 f = fopen(channel_util_file, "r");
2183 if (f != NULL) {
2184 read = getline(&line, &len, f);
2185 preActiveTime = strtol(line, NULL, 10);
2186 read = getline(&line, &len, f);
2187 preBusyTime = strtol(line, NULL, 10);
2188 read = getline(&line, &len, f);
2189 preTransmitTime = strtol(line, NULL, 10);
2190 fclose(f);
2191 }
developer72fb0bb2023-01-11 09:46:29 +08002192
developera3511852023-06-14 14:12:59 +08002193 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2194 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
developer72fb0bb2023-01-11 09:46:29 +08002195
developera3511852023-06-14 14:12:59 +08002196 f = fopen(channel_util_file, "w");
2197 if (f != NULL) {
2198 fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime);
2199 fclose(f);
2200 }
2201 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2202 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002203}
2204
2205/**********************************************************************************
2206 *
2207 * Wifi radio level function prototypes
2208 *
2209**********************************************************************************/
2210
2211//Get the total number of radios in this wifi subsystem
2212INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2213{
developera3511852023-06-14 14:12:59 +08002214 if (NULL == output)
2215 return RETURN_ERR;
2216 *output = MAX_NUM_RADIOS;
developer72fb0bb2023-01-11 09:46:29 +08002217
developera3511852023-06-14 14:12:59 +08002218 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002219}
2220
developer69b61b02023-03-07 17:17:44 +08002221//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002222INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2223{
developera3511852023-06-14 14:12:59 +08002224 if (NULL == output)
2225 return RETURN_ERR;
2226 *output = MAX_APS;
developer72fb0bb2023-01-11 09:46:29 +08002227
developera3511852023-06-14 14:12:59 +08002228 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002229}
2230
2231//Get the Radio enable config parameter
developera3511852023-06-14 14:12:59 +08002232INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08002233{
developer56fbedb2023-05-30 16:47:05 +08002234 char interface_name[16] = {0};
2235 char buf[128] = {0}, cmd[128] = {0};
2236 int apIndex;
2237 int max_radio_num = 0;
developer3a85ab82023-05-25 11:59:38 +08002238
developer56fbedb2023-05-30 16:47:05 +08002239 if (NULL == output_bool)
2240 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002241
developer56fbedb2023-05-30 16:47:05 +08002242 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08002243
developer56fbedb2023-05-30 16:47:05 +08002244 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002245
developer56fbedb2023-05-30 16:47:05 +08002246 if (radioIndex >= max_radio_num)
2247 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002248
developer56fbedb2023-05-30 16:47:05 +08002249 /* loop all interface in radio, if any is enable, reture true, else return false */
2250 for(apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num)
2251 {
2252 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2253 continue;
2254 memset(cmd, 0, sizeof(cmd));
2255 sprintf(cmd, "ifconfig %s 2> /dev/null | grep UP", interface_name);
2256 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? FALSE : TRUE;
2257 if (*output_bool == TRUE)
2258 break;
2259 }
2260
2261 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002262}
2263
developere82c0ca2023-05-10 16:25:35 +08002264typedef long time_t;
2265static time_t radio_up_time[MAX_NUM_RADIOS];
2266
developer72fb0bb2023-01-11 09:46:29 +08002267INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2268{
developera3511852023-06-14 14:12:59 +08002269 char interface_name[16] = {0};
2270 char cmd[MAX_CMD_SIZE] = {0};
2271 char buf[MAX_BUF_SIZE] = {0};
2272 int apIndex;
2273 int max_radio_num = 0;
developere40952c2023-06-15 18:46:43 +08002274 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002275
developera3511852023-06-14 14:12:59 +08002276 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002277
developera3511852023-06-14 14:12:59 +08002278 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002279
developera3511852023-06-14 14:12:59 +08002280 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002281
developera3511852023-06-14 14:12:59 +08002282 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002283
2284 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2285 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08002286
2287 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
2288 if (os_snprintf_error(sizeof(cmd), res)) {
2289 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2290 return RETURN_ERR;
2291 }
developer47cc27a2023-05-17 23:09:58 +08002292
developer8a3bbbf2023-03-15 17:47:23 +08002293 _syscmd(cmd, buf, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +08002294 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08002295 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
2296 if (os_snprintf_error(sizeof(cmd), res)) {
2297 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2298 return RETURN_ERR;
2299 }
developer56fbedb2023-05-30 16:47:05 +08002300 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002301 if(strncmp(buf, "OK", 2))
2302 fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002303 } else {
developere82c0ca2023-05-10 16:25:35 +08002304 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developera3511852023-06-14 14:12:59 +08002305 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2306 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002307
developer8a3bbbf2023-03-15 17:47:23 +08002308 memset(cmd, 0, MAX_CMD_SIZE);
2309 memset(buf, 0, MAX_BUF_SIZE);
2310
developere40952c2023-06-15 18:46:43 +08002311 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2312 if (os_snprintf_error(sizeof(cmd), res)) {
2313 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2314 return RETURN_ERR;
2315 }
developera3511852023-06-14 14:12:59 +08002316 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002317
developera3511852023-06-14 14:12:59 +08002318 if(*buf == '1') {
developere40952c2023-06-15 18:46:43 +08002319 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
2320 if (os_snprintf_error(sizeof(cmd), res)) {
2321 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2322 return RETURN_ERR;
2323 }
developer56fbedb2023-05-30 16:47:05 +08002324 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002325
2326 memset(cmd, 0, MAX_CMD_SIZE);
2327 memset(buf, 0, MAX_BUF_SIZE);
2328
developere40952c2023-06-15 18:46:43 +08002329 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 +08002330 phyId, apIndex);
developere40952c2023-06-15 18:46:43 +08002331 if (os_snprintf_error(sizeof(cmd), res)) {
2332 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2333 return RETURN_ERR;
2334 }
developera3511852023-06-14 14:12:59 +08002335 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002336
developera3511852023-06-14 14:12:59 +08002337 }
2338 }
developere82c0ca2023-05-10 16:25:35 +08002339 time(&radio_up_time[radioIndex]);
developera3511852023-06-14 14:12:59 +08002340 }
developer72fb0bb2023-01-11 09:46:29 +08002341
developera3511852023-06-14 14:12:59 +08002342 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2343 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002344}
2345
2346//Get the Radio enable status
2347INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2348{
developera3511852023-06-14 14:12:59 +08002349 if (NULL == output_bool)
2350 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002351
developera3511852023-06-14 14:12:59 +08002352 return wifi_getRadioEnable(radioIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08002353}
2354
2355//Get the Radio Interface name from platform, eg "wlan0"
2356INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2357{
developera3511852023-06-14 14:12:59 +08002358 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2359 return RETURN_ERR;
2360 return wifi_GetInterfaceName(radioIndex, output_string);
developer72fb0bb2023-01-11 09:46:29 +08002361}
2362
2363//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2364//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.
2365INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2366{
developera3511852023-06-14 14:12:59 +08002367 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2368 // For max bit rate, we should always choose the best MCS
2369 char mode[64] = {0};
2370 char channel_bandwidth_str[64] = {0};
2371 UINT mode_map = 0;
2372 UINT num_subcarrier = 0;
2373 UINT code_bits = 0;
2374 float code_rate = 0; // use max code rate
2375 int NSS = 0;
2376 UINT Symbol_duration = 0;
2377 UINT GI_duration = 0;
2378 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2379 BOOL enable = FALSE;
2380 float bit_rate = 0;
developere40952c2023-06-15 18:46:43 +08002381 int ant_bitmap = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002382
developera3511852023-06-14 14:12:59 +08002383 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2384 if (NULL == output_string)
2385 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002386
developera3511852023-06-14 14:12:59 +08002387 wifi_getRadioEnable(radioIndex, &enable);
2388 if (enable == FALSE) {
developere40952c2023-06-15 18:46:43 +08002389 res = snprintf(output_string, 64, "0 Mb/s");
2390 if (os_snprintf_error(64, res)) {
2391 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2392 return RETURN_ERR;
2393 }
developera3511852023-06-14 14:12:59 +08002394 return RETURN_OK;
2395 }
developer72fb0bb2023-01-11 09:46:29 +08002396
developera3511852023-06-14 14:12:59 +08002397 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
2398 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
2399 return RETURN_ERR;
2400 }
developer72fb0bb2023-01-11 09:46:29 +08002401
developera3511852023-06-14 14:12:59 +08002402 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
2403 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
2404 return RETURN_ERR;
2405 }
developer72fb0bb2023-01-11 09:46:29 +08002406
developera3511852023-06-14 14:12:59 +08002407 if (gi == wifi_guard_interval_3200)
2408 GI_duration = 32;
2409 else if (gi == wifi_guard_interval_1600)
2410 GI_duration = 16;
2411 else if (gi == wifi_guard_interval_800)
2412 GI_duration = 8;
2413 else // auto, 400
2414 GI_duration = 4;
developer72fb0bb2023-01-11 09:46:29 +08002415
developera3511852023-06-14 14:12:59 +08002416 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
2417 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
2418 return RETURN_ERR;
2419 }
developer72fb0bb2023-01-11 09:46:29 +08002420
developera3511852023-06-14 14:12:59 +08002421 if (strstr(channel_bandwidth_str, "80+80") != NULL)
2422 strcpy(channel_bandwidth_str, "160");
developer72fb0bb2023-01-11 09:46:29 +08002423
developera3511852023-06-14 14:12:59 +08002424 if (mode_map & WIFI_MODE_AX) {
2425 if (strstr(channel_bandwidth_str, "160") != NULL)
2426 num_subcarrier = 1960;
2427 else if (strstr(channel_bandwidth_str, "80") != NULL)
2428 num_subcarrier = 980;
2429 else if (strstr(channel_bandwidth_str, "40") != NULL)
2430 num_subcarrier = 468;
2431 else if (strstr(channel_bandwidth_str, "20") != NULL)
2432 num_subcarrier = 234;
2433 code_bits = 10;
2434 code_rate = (float)5/6;
2435 Symbol_duration = 128;
2436 GI_duration = 8;/*HE no GI 400ns*/
2437 } else if (mode_map & WIFI_MODE_AC) {
2438 if (strstr(channel_bandwidth_str, "160") != NULL)
2439 num_subcarrier = 468;
2440 else if (strstr(channel_bandwidth_str, "80") != NULL)
2441 num_subcarrier = 234;
2442 else if (strstr(channel_bandwidth_str, "40") != NULL)
2443 num_subcarrier = 108;
2444 else if (strstr(channel_bandwidth_str, "20") != NULL)
2445 num_subcarrier = 52;
2446 code_bits = 8;
2447 code_rate = (float)5/6;
2448 Symbol_duration = 32;
2449 } else if (mode_map & WIFI_MODE_N) {
2450 if (strstr(channel_bandwidth_str, "160") != NULL)
2451 num_subcarrier = 468;
2452 else if (strstr(channel_bandwidth_str, "80") != NULL)
2453 num_subcarrier = 234;
2454 else if (strstr(channel_bandwidth_str, "40") != NULL)
2455 num_subcarrier = 108;
2456 else if (strstr(channel_bandwidth_str, "20") != NULL)
2457 num_subcarrier = 52;
2458 code_bits = 6;
2459 code_rate = (float)3/4;
2460 Symbol_duration = 32;
2461 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2462 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
developere40952c2023-06-15 18:46:43 +08002463 res = snprintf(output_string, 64, "65 Mb/s");
2464 if (os_snprintf_error(64, res)) {
2465 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2466 return RETURN_ERR;
2467 }
developera3511852023-06-14 14:12:59 +08002468 return RETURN_OK;
2469 } else {
developere40952c2023-06-15 18:46:43 +08002470 res = snprintf(output_string, 64, "0 Mb/s");
2471 if (os_snprintf_error(64, res)) {
2472 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2473 return RETURN_ERR;
2474 }
developera3511852023-06-14 14:12:59 +08002475 return RETURN_OK;
2476 }
developer72fb0bb2023-01-11 09:46:29 +08002477
developera3511852023-06-14 14:12:59 +08002478 // Spatial streams
2479 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
2480 fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
2481 return RETURN_ERR;
2482 }
2483 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2484 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002485
developera3511852023-06-14 14:12:59 +08002486 // multiple 10 is to align duration unit (0.1 us)
2487 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
developere40952c2023-06-15 18:46:43 +08002488 res = snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
2489 if (os_snprintf_error(64, res)) {
2490 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2491 return RETURN_ERR;
2492 }
developera3511852023-06-14 14:12:59 +08002493 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2494 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
2495 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002496
developera3511852023-06-14 14:12:59 +08002497 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002498}
developer72fb0bb2023-01-11 09:46:29 +08002499
2500//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2501//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.
2502INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2503{
developera3511852023-06-14 14:12:59 +08002504 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08002505
developera3511852023-06-14 14:12:59 +08002506 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2507 if (NULL == output_string)
2508 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002509
developera3511852023-06-14 14:12:59 +08002510 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002511
developera3511852023-06-14 14:12:59 +08002512 memset(output_string, 0, 10);
2513 if (band == band_2_4)
2514 strcpy(output_string, "2.4GHz");
2515 else if (band == band_5)
2516 strcpy(output_string, "5GHz");
2517 else if (band == band_6)
2518 strcpy(output_string, "6GHz");
2519 else
2520 return RETURN_ERR;
2521 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002522
developera3511852023-06-14 14:12:59 +08002523 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002524}
2525
2526//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2527//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.
2528INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2529{
developera3511852023-06-14 14:12:59 +08002530 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08002531 int res;
2532
developera3511852023-06-14 14:12:59 +08002533 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2534 if (NULL == output_string)
2535 return RETURN_ERR;
2536 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08002537
developera3511852023-06-14 14:12:59 +08002538 if (band == band_2_4)
developere40952c2023-06-15 18:46:43 +08002539 res = snprintf(output_string, 64, "2.4GHz");
developera3511852023-06-14 14:12:59 +08002540 else if (band == band_5)
developere40952c2023-06-15 18:46:43 +08002541 res = snprintf(output_string, 64, "5GHz");
developera3511852023-06-14 14:12:59 +08002542 else if (band == band_6)
developere40952c2023-06-15 18:46:43 +08002543 res = snprintf(output_string, 64, "6GHz");
developer72fb0bb2023-01-11 09:46:29 +08002544
developere40952c2023-06-15 18:46:43 +08002545 if (os_snprintf_error(64, res)) {
2546 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2547 return RETURN_ERR;
2548 }
developera3511852023-06-14 14:12:59 +08002549 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002550
developera3511852023-06-14 14:12:59 +08002551 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002552}
2553
2554//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2555//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.
2556INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2557{
developera3511852023-06-14 14:12:59 +08002558 char cmd[128]={0};
2559 char buf[128]={0};
2560 char temp_output[128] = {0};
2561 wifi_band band;
developere40952c2023-06-15 18:46:43 +08002562 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08002563
developera3511852023-06-14 14:12:59 +08002564 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2565 if (NULL == output_string)
2566 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002567
developera3511852023-06-14 14:12:59 +08002568 band = wifi_index_to_band(radioIndex);
2569 if (band == band_2_4) {
2570 strcat(temp_output, "b,g,");
2571 } else if (band == band_5) {
2572 strcat(temp_output, "a,");
2573 }
2574 phyId = radio_index_to_phy(radioIndex);
2575 // ht capabilities
developere40952c2023-06-15 18:46:43 +08002576 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);
2577 if (os_snprintf_error(sizeof(cmd), res)) {
2578 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2579 return RETURN_ERR;
2580 }
developera3511852023-06-14 14:12:59 +08002581 _syscmd(cmd, buf, sizeof(buf));
2582 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
2583 strcat(temp_output, "n,");
2584 }
developer72fb0bb2023-01-11 09:46:29 +08002585
developera3511852023-06-14 14:12:59 +08002586 // vht capabilities
2587 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08002588 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2589 if (os_snprintf_error(sizeof(cmd), res)) {
2590 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2591 return RETURN_ERR;
2592 }
2593 _syscmd(cmd, buf, sizeof(buf));
2594 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
developera3511852023-06-14 14:12:59 +08002595 strcat(temp_output, "ac,");
2596 }
2597 }
developer72fb0bb2023-01-11 09:46:29 +08002598
developera3511852023-06-14 14:12:59 +08002599 // he capabilities
developere40952c2023-06-15 18:46:43 +08002600 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);
2601 if (os_snprintf_error(sizeof(cmd), res)) {
2602 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2603 return RETURN_ERR;
2604 }
developera3511852023-06-14 14:12:59 +08002605 _syscmd(cmd, buf, sizeof(buf));
2606 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2607 strcat(temp_output, "ax,");
2608 }
developer72fb0bb2023-01-11 09:46:29 +08002609
developere82c0ca2023-05-10 16:25:35 +08002610 // eht capabilities
developere40952c2023-06-15 18:46:43 +08002611 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);
2612 if (os_snprintf_error(sizeof(cmd), res)) {
2613 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2614 return RETURN_ERR;
2615 }
developera3511852023-06-14 14:12:59 +08002616 _syscmd(cmd, buf, sizeof(buf));
2617 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2618 strcat(temp_output, "be,");
2619 }
developere82c0ca2023-05-10 16:25:35 +08002620
developera3511852023-06-14 14:12:59 +08002621 // Remove the last comma
2622 if (strlen(temp_output) != 0)
2623 temp_output[strlen(temp_output)-1] = '\0';
2624 strncpy(output_string, temp_output, strlen(temp_output));
2625 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2626 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002627}
2628
2629//Get the radio operating mode, and pure mode flag. eg: "ac"
2630//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.
2631INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
2632{
developere40952c2023-06-15 18:46:43 +08002633 int res;
2634
developera3511852023-06-14 14:12:59 +08002635 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2636 if (NULL == output_string)
2637 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002638
developera3511852023-06-14 14:12:59 +08002639 if (radioIndex == 0) {
developere40952c2023-06-15 18:46:43 +08002640 res = snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
2641 if (os_snprintf_error(64, res)) {
2642 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2643 return RETURN_ERR;
2644 }
developera3511852023-06-14 14:12:59 +08002645 *gOnly = FALSE;
2646 *nOnly = TRUE;
2647 *acOnly = FALSE;
2648 } else {
developere40952c2023-06-15 18:46:43 +08002649 res = snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
2650 if (os_snprintf_error(64, res)) {
2651 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2652 return RETURN_ERR;
2653 }
developera3511852023-06-14 14:12:59 +08002654 *gOnly = FALSE;
2655 *nOnly = FALSE;
2656 *acOnly = FALSE;
2657 }
2658 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002659
developera3511852023-06-14 14:12:59 +08002660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002661}
2662
developer0f10c772023-05-16 21:43:39 +08002663enum WIFI_MODE {
2664 WMODE_INVALID = 0,
2665 WMODE_A = 1 << 0,
2666 WMODE_B = 1 << 1,
2667 WMODE_G = 1 << 2,
2668 WMODE_GN = 1 << 3,
2669 WMODE_AN = 1 << 4,
2670 WMODE_AC = 1 << 5,
2671 WMODE_AX_24G = 1 << 6,
2672 WMODE_AX_5G = 1 << 7,
2673 WMODE_AX_6G = 1 << 8,
2674 WMODE_BE_24G = 1 << 9,
2675 WMODE_BE_5G = 1 << 10,
2676 WMODE_BE_6G = 1 << 11,
2677 /*
2678 * total types of supported wireless mode,
2679 * add this value once yow add new type
2680 */
2681 WMODE_COMP = 12,
2682};
2683
2684#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08002685
2686int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08002687{
developerfead3972023-05-25 20:15:02 +08002688 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2689 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
2690 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2691 unsigned int *phymode;
2692 int err = 0;
2693 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08002694
developerfead3972023-05-25 20:15:02 +08002695 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08002696 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developerfead3972023-05-25 20:15:02 +08002697 return NL_SKIP;
2698 }
developer72fb0bb2023-01-11 09:46:29 +08002699
developerfead3972023-05-25 20:15:02 +08002700 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2701 genlmsg_attrlen(gnlh, 0), NULL);
2702 if (err < 0) {
2703 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
2704 return NL_SKIP;
2705 }
developer0f10c772023-05-16 21:43:39 +08002706
developerfead3972023-05-25 20:15:02 +08002707 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2708 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
2709 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2710 if (err < 0)
2711 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08002712
developerfead3972023-05-25 20:15:02 +08002713 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
2714 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
2715
2716 memset(cb_data->out_buf, 0, cb_data->out_len);
2717 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
2718 }
2719 } else
2720 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
2721
2722 return NL_OK;
2723}
developer0f10c772023-05-16 21:43:39 +08002724
developerfead3972023-05-25 20:15:02 +08002725void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
2726{
2727 wifi_band band;
2728 unsigned char radio_mode_tem_len;
developere40952c2023-06-15 18:46:43 +08002729 int res;
developerfead3972023-05-25 20:15:02 +08002730
2731 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08002732 // puremode is a bit map
developera3511852023-06-14 14:12:59 +08002733 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08002734 memset(output_string, 0, RADIO_MODE_LEN);
2735
2736 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2737
2738 switch (band) {
2739 case band_2_4:
2740 if (phymode & WMODE_B) {
developere40952c2023-06-15 18:46:43 +08002741 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
2742 if (os_snprintf_error(radio_mode_tem_len, res)) {
2743 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2744 return;
2745 }
developer0f10c772023-05-16 21:43:39 +08002746 *pureMode |= WIFI_MODE_B;
2747 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2748 }
2749 if (phymode & WMODE_G) {
developere40952c2023-06-15 18:46:43 +08002750 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
2751 if (os_snprintf_error(radio_mode_tem_len, res)) {
2752 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2753 return;
2754 }
developer0f10c772023-05-16 21:43:39 +08002755 *pureMode |= WIFI_MODE_G;
2756 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2757 }
2758 if (phymode & WMODE_GN) {
developere40952c2023-06-15 18:46:43 +08002759 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2760 if (os_snprintf_error(radio_mode_tem_len, res)) {
2761 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2762 return;
2763 }
developer0f10c772023-05-16 21:43:39 +08002764 *pureMode |= WIFI_MODE_N;
2765 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2766 }
2767 if (phymode & WMODE_AX_24G) {
developere40952c2023-06-15 18:46:43 +08002768 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2769 if (os_snprintf_error(radio_mode_tem_len, res)) {
2770 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2771 return;
2772 }
developer0f10c772023-05-16 21:43:39 +08002773 *pureMode |= WIFI_MODE_AX;
2774 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2775 }
2776 if (phymode & WMODE_BE_24G) {
developere40952c2023-06-15 18:46:43 +08002777 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2778 if (os_snprintf_error(radio_mode_tem_len, res)) {
2779 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2780 return;
2781 }
developer0f10c772023-05-16 21:43:39 +08002782 *pureMode |= WIFI_MODE_BE;
2783 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2784 }
2785 break;
2786 case band_5:
2787 if (phymode & WMODE_A) {
developere40952c2023-06-15 18:46:43 +08002788 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
2789 if (os_snprintf_error(radio_mode_tem_len, res)) {
2790 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2791 return;
2792 }
developer0f10c772023-05-16 21:43:39 +08002793 *pureMode |= WIFI_MODE_A;
2794 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2795 }
2796 if (phymode & WMODE_AN) {
developere40952c2023-06-15 18:46:43 +08002797 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2798 if (os_snprintf_error(radio_mode_tem_len, res)) {
2799 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2800 return;
2801 }
developer0f10c772023-05-16 21:43:39 +08002802 *pureMode |= WIFI_MODE_N;
2803 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2804 }
2805 if (phymode & WMODE_AC) {
developere40952c2023-06-15 18:46:43 +08002806 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
2807 if (os_snprintf_error(radio_mode_tem_len, res)) {
2808 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2809 return;
2810 }
developer0f10c772023-05-16 21:43:39 +08002811 *pureMode |= WIFI_MODE_AC;
2812 }
2813 if (phymode & WMODE_AX_5G) {
developere40952c2023-06-15 18:46:43 +08002814 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2815 if (os_snprintf_error(radio_mode_tem_len, res)) {
2816 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2817 return;
2818 }
developer0f10c772023-05-16 21:43:39 +08002819 *pureMode |= WIFI_MODE_AX;
2820 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2821 }
2822 if (phymode & WMODE_BE_5G) {
developere40952c2023-06-15 18:46:43 +08002823 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2824 if (os_snprintf_error(radio_mode_tem_len, res)) {
2825 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2826 return;
2827 }
developer0f10c772023-05-16 21:43:39 +08002828 *pureMode |= WIFI_MODE_BE;
2829 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2830 }
2831 break;
2832 case band_6:
2833 if (phymode & WMODE_AX_6G) {
developere40952c2023-06-15 18:46:43 +08002834 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2835 if (os_snprintf_error(radio_mode_tem_len, res)) {
2836 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2837 return;
2838 }
developer0f10c772023-05-16 21:43:39 +08002839 *pureMode |= WIFI_MODE_AX;
2840 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2841 }
2842 if (phymode & WMODE_BE_6G) {
developere40952c2023-06-15 18:46:43 +08002843 res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2844 if (os_snprintf_error(radio_mode_tem_len, res)) {
2845 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
2846 return;
2847 }
developer0f10c772023-05-16 21:43:39 +08002848 *pureMode |= WIFI_MODE_BE;
2849 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2850 }
2851 break;
2852 default:
2853 fprintf(stderr, "%s band_idx invalid\n", __func__);
2854 break;
2855 }
2856
2857 /* Remove the last comma */
2858 if (strlen(output_string) != 0)
developera3511852023-06-14 14:12:59 +08002859 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08002860
developerfead3972023-05-25 20:15:02 +08002861}
2862
2863INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
2864{
2865 unsigned int phymode;
2866 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08002867 int ret = -1;
2868 unsigned int if_idx = 0;
2869 struct unl unl_ins;
2870 struct nl_msg *msg = NULL;
2871 struct nlattr * msg_data = NULL;
2872 struct mtk_nl80211_param param;
2873 struct mtk_nl80211_cb_data cb_data;
2874
developera3511852023-06-14 14:12:59 +08002875 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2876 if (NULL == output_string || NULL == pureMode)
developerdaf24792023-06-06 11:40:04 +08002877 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08002878
2879 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2880 return RETURN_ERR;
2881
2882 if_idx = if_nametoindex(interface_name);
2883 if (!if_idx) {
2884 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
2885 return RETURN_ERR;
2886 }
2887 /*init mtk nl80211 vendor cmd*/
2888 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
2889 param.if_type = NL80211_ATTR_IFINDEX;
2890 param.if_idx = if_idx;
2891
2892 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
2893 if (ret) {
2894 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
2895 return RETURN_ERR;
2896 }
2897
2898 /*add mtk vendor cmd data*/
2899 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
2900 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
2901 nlmsg_free(msg);
2902 goto err;
2903 }
2904
2905 /*send mtk nl80211 vendor msg*/
2906 cb_data.out_buf = (char *)&phymode;
2907 cb_data.out_len = sizeof(unsigned int);
2908
2909 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
2910
2911 if (ret) {
2912 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
2913 goto err;
2914 }
2915 /*deinit mtk nl80211 vendor msg*/
2916 mtk_nl80211_deint(&unl_ins);
2917
2918 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
2919 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
2920
developera3511852023-06-14 14:12:59 +08002921 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2922 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08002923err:
2924 mtk_nl80211_deint(&unl_ins);
2925 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
2926 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002927}
2928
2929// Set the radio operating mode, and pure mode flag.
2930INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
2931{
developera3511852023-06-14 14:12:59 +08002932 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
2933 if (strcmp (channelMode,"11A") == 0)
2934 {
2935 writeBandWidth(radioIndex,"20MHz");
2936 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2937 printf("\nChannel Mode is 802.11a (5GHz)\n");
2938 }
2939 else if (strcmp (channelMode,"11NAHT20") == 0)
2940 {
2941 writeBandWidth(radioIndex,"20MHz");
2942 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2943 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
2944 }
2945 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
2946 {
2947 writeBandWidth(radioIndex,"40MHz");
2948 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2949 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
2950 }
2951 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
2952 {
2953 writeBandWidth(radioIndex,"40MHz");
2954 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2955 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
2956 }
2957 else if (strcmp (channelMode,"11ACVHT20") == 0)
2958 {
2959 writeBandWidth(radioIndex,"20MHz");
2960 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2961 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
2962 }
2963 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
2964 {
2965 writeBandWidth(radioIndex,"40MHz");
2966 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2967 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
2968 }
2969 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
2970 {
2971 writeBandWidth(radioIndex,"40MHz");
2972 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2973 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
2974 }
2975 else if (strcmp (channelMode,"11ACVHT80") == 0)
2976 {
2977 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
2978 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
2979 }
2980 else if (strcmp (channelMode,"11ACVHT160") == 0)
2981 {
2982 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
2983 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
2984 }
2985 else if (strcmp (channelMode,"11B") == 0)
2986 {
2987 writeBandWidth(radioIndex,"20MHz");
2988 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2989 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
2990 }
2991 else if (strcmp (channelMode,"11G") == 0)
2992 {
2993 writeBandWidth(radioIndex,"20MHz");
2994 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2995 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
2996 }
2997 else if (strcmp (channelMode,"11NGHT20") == 0)
2998 {
2999 writeBandWidth(radioIndex,"20MHz");
3000 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3001 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3002 }
3003 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3004 {
3005 writeBandWidth(radioIndex,"40MHz");
3006 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3007 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3008 }
3009 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3010 {
3011 writeBandWidth(radioIndex,"40MHz");
3012 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3013 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3014 }
3015 else
3016 {
3017 return RETURN_ERR;
3018 }
3019 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003020
developera3511852023-06-14 14:12:59 +08003021 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003022}
3023
developer0f10c772023-05-16 21:43:39 +08003024typedef enum _RT_802_11_PHY_MODE {
3025 PHY_11BG_MIXED = 0,
3026 PHY_11B = 1,
3027 PHY_11A = 2,
3028 PHY_11ABG_MIXED = 3,
3029 PHY_11G = 4,
3030 PHY_11ABGN_MIXED = 5, /* both band 5 */
developera3511852023-06-14 14:12:59 +08003031 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3032 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3033 PHY_11AN_MIXED = 8, /* 5G band 8 */
3034 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3035 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3036 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
developer0f10c772023-05-16 21:43:39 +08003037 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3038 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3039 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3040 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3041 PHY_11AX_24G = 16,
3042 PHY_11AX_5G = 17,
3043 PHY_11AX_6G = 18,
3044 PHY_11AX_24G_6G = 19,
3045 PHY_11AX_5G_6G = 20,
3046 PHY_11AX_24G_5G_6G = 21,
3047 PHY_11BE_24G = 22,
3048 PHY_11BE_5G = 23,
3049 PHY_11BE_6G = 24,
3050 PHY_11BE_24G_6G = 25,
3051 PHY_11BE_5G_6G = 26,
3052 PHY_11BE_24G_5G_6G = 27,
3053 PHY_MODE_MAX,
3054} RT_802_11_PHY_MODE;
3055
3056unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3057{
3058 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003059 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003060
3061 band_idx = radio_index_to_band(radioIndex);
3062
3063 switch (band_idx) {
3064 case band_2_4:
3065 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3066 wireless_mode = PHY_11GN_MIXED;
3067 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3068 wireless_mode = PHY_11BGN_MIXED;
3069 if (pureMode & WIFI_MODE_AX)
3070 wireless_mode = PHY_11AX_24G;
3071 if (pureMode & WIFI_MODE_BE)
3072 wireless_mode = PHY_11BE_24G;
3073 break;
3074 case band_5:
3075 if (pureMode == WIFI_MODE_N)
3076 wireless_mode = PHY_11N_5G;
3077 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3078 wireless_mode = PHY_11VHT_N_MIXED;
3079 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3080 wireless_mode = PHY_11VHT_N_A_MIXED;
3081 if (pureMode & WIFI_MODE_AX)
3082 wireless_mode = PHY_11AX_5G;
3083 if (pureMode & WIFI_MODE_BE)
3084 wireless_mode = PHY_11BE_5G;
3085 break;
3086 case band_6:
3087 if (pureMode & WIFI_MODE_AX)
3088 wireless_mode = PHY_11AX_6G;
3089 if (pureMode & WIFI_MODE_BE)
3090 wireless_mode = PHY_11BE_6G;
3091 break;
3092 default:
3093 fprintf(stderr, "%s band_idx invalid\n", __func__);
3094 break;
3095 }
3096
3097 return wireless_mode;
3098}
3099
developer72fb0bb2023-01-11 09:46:29 +08003100// Set the radio operating mode, and pure mode flag.
3101INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3102{
developerfead3972023-05-25 20:15:02 +08003103 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003104
developer0f10c772023-05-16 21:43:39 +08003105 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003106 int ret = -1;
3107 unsigned int if_idx = 0;
3108 struct unl unl_ins;
3109 struct nl_msg *msg = NULL;
3110 struct nlattr * msg_data = NULL;
3111 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003112
developer0f10c772023-05-16 21:43:39 +08003113 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003114
developer0f10c772023-05-16 21:43:39 +08003115 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003116
developera3511852023-06-14 14:12:59 +08003117 if (wireless_mode == PHY_MODE_MAX) {
developer0f10c772023-05-16 21:43:39 +08003118 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3119 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003120 }
developer72fb0bb2023-01-11 09:46:29 +08003121
developer0f10c772023-05-16 21:43:39 +08003122 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08003123 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003124
3125 if_idx = if_nametoindex(interface_name);
3126 if (!if_idx) {
3127 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3128 return RETURN_ERR;
3129 }
3130 /*init mtk nl80211 vendor cmd*/
3131 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3132 param.if_type = NL80211_ATTR_IFINDEX;
3133 param.if_idx = if_idx;
3134
3135 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3136 if (ret) {
3137 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3138 return RETURN_ERR;
3139 }
3140
3141 /*add mtk vendor cmd data*/
3142 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3143 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3144 nlmsg_free(msg);
3145 goto err;
3146 }
3147 /*send mtk nl80211 vendor msg*/
3148 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3149 if (ret) {
3150 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3151 goto err;
3152 }
3153 /*deinit mtk nl80211 vendor msg*/
3154 mtk_nl80211_deint(&unl_ins);
3155 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003156
developera3511852023-06-14 14:12:59 +08003157 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer0f10c772023-05-16 21:43:39 +08003158
developera3511852023-06-14 14:12:59 +08003159 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003160err:
3161 mtk_nl80211_deint(&unl_ins);
3162 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3163 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003164}
3165
3166INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3167{
developerfead3972023-05-25 20:15:02 +08003168 unsigned char wireless_mode = PHY_MODE_MAX;
developera3511852023-06-14 14:12:59 +08003169 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003170 char dat_file[MAX_BUF_SIZE] = {0};
3171 struct params params={0};
developere40952c2023-06-15 18:46:43 +08003172 int res;
developer0f10c772023-05-16 21:43:39 +08003173
3174 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3175
3176 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3177
developera3511852023-06-14 14:12:59 +08003178 if (wireless_mode == PHY_MODE_MAX) {
developer0f10c772023-05-16 21:43:39 +08003179 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3180 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08003181 }
developer0f10c772023-05-16 21:43:39 +08003182
3183 params.name = "WirelessMode";
developere40952c2023-06-15 18:46:43 +08003184 res = snprintf(buf, sizeof(buf), "%d", wireless_mode);
3185 if (os_snprintf_error(sizeof(buf), res)) {
3186 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3187 return RETURN_ERR;
3188 }
3189
developera3511852023-06-14 14:12:59 +08003190 params.value = buf;
developer0f10c772023-05-16 21:43:39 +08003191
developere40952c2023-06-15 18:46:43 +08003192 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3193 if (os_snprintf_error(sizeof(dat_file), res)) {
3194 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3195 return RETURN_ERR;
3196 }
developera3511852023-06-14 14:12:59 +08003197 wifi_datfileWrite(dat_file, &params, 1);
developer0f10c772023-05-16 21:43:39 +08003198
developera3511852023-06-14 14:12:59 +08003199 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003200
developera3511852023-06-14 14:12:59 +08003201 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003202}
3203
3204INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3205
developera3511852023-06-14 14:12:59 +08003206 char config_file[64] = {0};
3207 char buf[64] = {0};
3208 struct params params = {0};
3209 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003210 int res;
developer72fb0bb2023-01-11 09:46:29 +08003211
developera3511852023-06-14 14:12:59 +08003212 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003213
developera3511852023-06-14 14:12:59 +08003214 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003215
developera3511852023-06-14 14:12:59 +08003216 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3217 return RETURN_ERR;
3218 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3219 return RETURN_ERR;
3220 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3221 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003222
developera3511852023-06-14 14:12:59 +08003223 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3224 params.name = "hw_mode";
3225 params.value = hw_mode;
3226 wifi_hostapdWrite(config_file, &params, 1);
3227 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003228
developera3511852023-06-14 14:12:59 +08003229 if (band == band_2_4) {
3230 if (strncmp(hw_mode, "b", 1) == 0) {
3231 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
developere40952c2023-06-15 18:46:43 +08003232 res = snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3233 if (os_snprintf_error(sizeof(buf), res)) {
3234 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3235 return RETURN_ERR;
3236 }
developera3511852023-06-14 14:12:59 +08003237 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003238 res = snprintf(buf, sizeof(buf), "%s", "1,2");
3239 if (os_snprintf_error(sizeof(buf), res)) {
3240 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3241 return RETURN_ERR;
3242 }
developera3511852023-06-14 14:12:59 +08003243 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3244 } else {
3245 // 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 +08003246
developere40952c2023-06-15 18:46:43 +08003247 res = snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3248 if (os_snprintf_error(sizeof(buf), res)) {
3249 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3250 return RETURN_ERR;
3251 }
developera3511852023-06-14 14:12:59 +08003252 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
developere40952c2023-06-15 18:46:43 +08003253 res = snprintf(buf, sizeof(buf), "%s", "6,12,24");
3254 if (os_snprintf_error(sizeof(buf), res)) {
3255 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3256 return RETURN_ERR;
3257 }
developera3511852023-06-14 14:12:59 +08003258 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3259 }
3260 }
developer72fb0bb2023-01-11 09:46:29 +08003261
developera3511852023-06-14 14:12:59 +08003262 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3263 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003264}
3265
3266INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3267{
developera3511852023-06-14 14:12:59 +08003268 char config_file[64] = {0};
3269 struct params params = {0};
3270 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003271
developera3511852023-06-14 14:12:59 +08003272 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003273
developera3511852023-06-14 14:12:59 +08003274 band = wifi_index_to_band(radioIndex);
3275 if (band != band_2_4)
3276 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003277
developera3511852023-06-14 14:12:59 +08003278 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3279 params.name = "noscan";
3280 params.value = noscan;
3281 wifi_hostapdWrite(config_file, &params, 1);
3282 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003283
developera3511852023-06-14 14:12:59 +08003284 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3285 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003286}
3287
3288//Get the list of supported channel. eg: "1-11"
3289//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.
3290INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3291{
developera3511852023-06-14 14:12:59 +08003292 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3293 if (NULL == output_string)
3294 return RETURN_ERR;
3295 char cmd[256] = {0};
3296 char buf[128] = {0};
3297 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +08003298 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08003299
developera3511852023-06-14 14:12:59 +08003300 // Parse possible channel number and separate them with commas.
3301 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3302 phyId = radio_index_to_phy(radioIndex);
3303 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3304 if (dfs_enable)
developere40952c2023-06-15 18:46:43 +08003305 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 +08003306 else
developere40952c2023-06-15 18:46:43 +08003307 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 +08003308
developere40952c2023-06-15 18:46:43 +08003309 if (os_snprintf_error(sizeof(cmd), res)) {
3310 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3311 return RETURN_ERR;
3312 }
developera3511852023-06-14 14:12:59 +08003313 _syscmd(cmd,buf,sizeof(buf));
3314 strncpy(output_string, buf, strlen(buf) < sizeof(buf) ? strlen(buf) : sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003315
developera3511852023-06-14 14:12:59 +08003316 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3317 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003318}
developerd1824452023-05-18 12:30:04 +08003319//Getting current radio extension channel
3320INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3321{
developera3511852023-06-14 14:12:59 +08003322 CHAR buf[150] = {0};
developerd1824452023-05-18 12:30:04 +08003323
developera3511852023-06-14 14:12:59 +08003324 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
3325 if (strncmp(buf, "Below", 5) == 0) //below
3326 strcpy(Value,"BelowControlChannel");
3327 if(strncmp(buf, "Above", 5) == 0) //above
3328 strcpy(Value,"AboveControlChannel");
3329 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08003330}
developerf6a87542023-05-16 15:47:28 +08003331
developer72fb0bb2023-01-11 09:46:29 +08003332//Get the list for used channel. eg: "1,6,9,11"
3333//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.
3334INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3335{
developera3511852023-06-14 14:12:59 +08003336 char interface_name[16] = {0};
3337 char cmd[128] = {0};
3338 char buf[128] = {0};
3339 char config_file[64] = {0};
3340 int channel = 0;
3341 int freq = 0;
3342 int bandwidth = 0;
3343 int center_freq = 0;
3344 int center_channel = 0;
3345 int channel_delta = 0;
3346 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003347 int res;
developer72fb0bb2023-01-11 09:46:29 +08003348
developera3511852023-06-14 14:12:59 +08003349 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003350
developera3511852023-06-14 14:12:59 +08003351 if (NULL == output_string)
3352 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003353
developera3511852023-06-14 14:12:59 +08003354 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3355 return RETURN_ERR;
3356 sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3357 _syscmd(cmd, buf, sizeof(buf));
3358 if (strlen(buf) == 0) {
3359 fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__);
3360 return RETURN_ERR;
3361 }
3362 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
developer72fb0bb2023-01-11 09:46:29 +08003363
developera3511852023-06-14 14:12:59 +08003364 if (bandwidth == 20) {
developere40952c2023-06-15 18:46:43 +08003365 res = snprintf(output_string, 256, "%d", channel);
3366 if (os_snprintf_error(256, res)) {
3367 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3368 return RETURN_ERR;
3369 }
developera3511852023-06-14 14:12:59 +08003370 return RETURN_OK;
3371 }
developer72fb0bb2023-01-11 09:46:29 +08003372
developera3511852023-06-14 14:12:59 +08003373 center_channel = ieee80211_frequency_to_channel(center_freq);
developer72fb0bb2023-01-11 09:46:29 +08003374
developera3511852023-06-14 14:12:59 +08003375 band = wifi_index_to_band(radioIndex);
3376 if (band == band_2_4 && bandwidth == 40) {
3377 sprintf(config_file, "%s%d.dat", LOGAN_DAT_FILE, band);
3378 memset(buf, 0, sizeof(buf));
3379 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
developer72fb0bb2023-01-11 09:46:29 +08003380
developera3511852023-06-14 14:12:59 +08003381 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
developere40952c2023-06-15 18:46:43 +08003382 res = snprintf(output_string, 256, "%d,%d", channel, channel+4);
developera3511852023-06-14 14:12:59 +08003383 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
developere40952c2023-06-15 18:46:43 +08003384 res = snprintf(output_string, 256, "%d,%d", channel-4, channel);
developera3511852023-06-14 14:12:59 +08003385 } else {
3386 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
3387 return RETURN_ERR;
3388 }
developere40952c2023-06-15 18:46:43 +08003389
3390 if (os_snprintf_error(256, res)) {
3391 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3392 return RETURN_ERR;
3393 }
developera3511852023-06-14 14:12:59 +08003394 } else if (band == band_5 || band == band_6){
3395 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
3396 // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6.
3397 channel_delta = (bandwidth-20)/10;
3398 memset(output_string, 0, 256);
3399 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3400 // If i is not the last channel, we add a comma.
developere40952c2023-06-15 18:46:43 +08003401 res = snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
3402
3403 if (os_snprintf_error(sizeof(buf), res)) {
3404 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3405 return RETURN_ERR;
3406 }
developera3511852023-06-14 14:12:59 +08003407 strncat(output_string, buf, strlen(buf));
3408 }
3409 } else
3410 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003411
developera3511852023-06-14 14:12:59 +08003412 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3413 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003414}
3415
developer69b61b02023-03-07 17:17:44 +08003416//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003417INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003418{
developera3511852023-06-14 14:12:59 +08003419 char channel_str[16] = {0};
3420 char config_file[128] = {0};
3421 char buf[MAX_BUF_SIZE] = {0};
3422 char cmd[MAX_CMD_SIZE] = {0};
3423 char interface_name[IF_NAME_SIZE] = {0};
3424 wifi_band band = band_invalid;
3425 ULONG iwChannel = 0;
developere40952c2023-06-15 18:46:43 +08003426 int res;
developer47a56bf2023-05-30 13:38:57 +08003427
developera3511852023-06-14 14:12:59 +08003428 if (output_ulong == NULL)
3429 return RETURN_ERR;
3430 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08003431 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3432 if (os_snprintf_error(sizeof(config_file), res)) {
3433 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3434 return RETURN_ERR;
3435 }
3436
developera3511852023-06-14 14:12:59 +08003437 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
3438 *output_ulong = strtoul(channel_str, NULL, 10);
3439 if (*output_ulong == 0) {
3440 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3441 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08003442 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
3443 if (os_snprintf_error(sizeof(cmd), res)) {
3444 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3445 return RETURN_ERR;
3446 }
3447
developera3511852023-06-14 14:12:59 +08003448 _syscmd(cmd,buf,sizeof(buf));
3449 sscanf(buf, "%lu", &iwChannel);
3450 *output_ulong = iwChannel;
3451 }
developer72fb0bb2023-01-11 09:46:29 +08003452
developera3511852023-06-14 14:12:59 +08003453 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003454}
3455
developer72fb0bb2023-01-11 09:46:29 +08003456INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
3457{
developera3511852023-06-14 14:12:59 +08003458 char cmd[1024] = {0}, buf[5] = {0};
3459 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08003460 int res;
developer72fb0bb2023-01-11 09:46:29 +08003461
developera3511852023-06-14 14:12:59 +08003462 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3463 if (NULL == output_ulong)
3464 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003465
developera3511852023-06-14 14:12:59 +08003466 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
3467 return RETURN_ERR;
developer47a56bf2023-05-30 13:38:57 +08003468
developere40952c2023-06-15 18:46:43 +08003469 res = snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
3470 if (os_snprintf_error(sizeof(cmd), res)) {
3471 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3472 return RETURN_ERR;
3473 }
developera3511852023-06-14 14:12:59 +08003474 _syscmd(cmd,buf,sizeof(buf));
3475 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
3476 if (*output_ulong == 0) {
3477 return RETURN_ERR;
3478 }
developer72fb0bb2023-01-11 09:46:29 +08003479
developera3511852023-06-14 14:12:59 +08003480 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3481 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003482}
developer72fb0bb2023-01-11 09:46:29 +08003483//Storing the previous channel value
3484INT wifi_storeprevchanval(INT radioIndex)
3485{
developera3511852023-06-14 14:12:59 +08003486 char buf[256] = {0};
3487 char output[4]={'\0'};
3488 char config_file[MAX_BUF_SIZE] = {0};
3489 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003490 int res;
developerd1824452023-05-18 12:30:04 +08003491
developera3511852023-06-14 14:12:59 +08003492 band = wifi_index_to_band(radioIndex);
3493 if (band == band_invalid) {
3494 return RETURN_ERR;
3495 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
3496 }
developere40952c2023-06-15 18:46:43 +08003497 res = snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
3498 if (os_snprintf_error(sizeof(config_file), res)) {
3499 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3500 return RETURN_ERR;
3501 }
3502
developera3511852023-06-14 14:12:59 +08003503 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
developerd1824452023-05-18 12:30:04 +08003504
developera3511852023-06-14 14:12:59 +08003505 if(band == band_2_4)
3506 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
3507 else if(band == band_5)
3508 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
3509 else
3510 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
3511 system(buf);
3512 Radio_flag = FALSE;
3513 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003514}
3515
3516//Set the running channel number
3517INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
3518{
developera3511852023-06-14 14:12:59 +08003519 // We only write hostapd config here
3520 char str_channel[8]={0};
3521 char *list_channel;
3522 char possible_channels[256] = {0};
3523 char config_file_dat[128] = {0};
3524 struct params dat = {0};
3525 struct params acs = {0};
3526 wifi_band band = band_invalid;
3527 bool acs_channel = false;
developere40952c2023-06-15 18:46:43 +08003528 int res;
developer72fb0bb2023-01-11 09:46:29 +08003529
developera3511852023-06-14 14:12:59 +08003530 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003531
developera3511852023-06-14 14:12:59 +08003532 if (channel == 0)
3533 acs_channel = true;
3534 // Check valid
3535 sprintf(str_channel, "%lu", channel);
developer72fb0bb2023-01-11 09:46:29 +08003536
developer47a56bf2023-05-30 13:38:57 +08003537
developera3511852023-06-14 14:12:59 +08003538 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
3539 list_channel = strtok(possible_channels, ",");
3540 while(true)
3541 {
3542 if(list_channel == NULL) { // input not in the list
3543 fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel);
3544 return RETURN_ERR;
3545 }
3546 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
3547 break;
3548 list_channel = strtok(NULL, ",");
3549 }
3550 /*
3551 list.name = "channel";
3552 list.value = str_channel;
3553 wifi_getMaxRadioNumber(&max_radio_num);
3554 for(int i=0; i<=MAX_APS/max_radio_num;i++)
3555 {
3556 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3557 wifi_hostapdWrite(config_file, &list, 1);
3558 }
3559 */
3560 dat.name = "Channel";
3561 dat.value = str_channel;
3562 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08003563 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3564 if (os_snprintf_error(sizeof(config_file_dat), res)) {
3565 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3566 return RETURN_ERR;
3567 }
3568
developera3511852023-06-14 14:12:59 +08003569 wifi_datfileWrite(config_file_dat, &dat, 1);
3570 if (acs_channel == true) {
3571 acs.name = "AutoChannelSelect";
3572 acs.value = "3";
3573 } else {
3574 acs.name = "AutoChannelSelect";
3575 acs.value = "0";
3576 }
3577 wifi_datfileWrite(config_file_dat, &acs, 1);
3578 wifi_reloadAp(radioIndex);
3579 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3580 return RETURN_OK;
3581}
3582
3583INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
3584{
3585 struct params list[2];
3586 char str_idx[16];
3587 char config_file[64];
developere40952c2023-06-15 18:46:43 +08003588 int max_num_radios = 0, res;
developera3511852023-06-14 14:12:59 +08003589 wifi_band band = band_invalid;
3590
3591 band = wifi_index_to_band(radioIndex);
3592 if (band == band_2_4)
3593 return RETURN_OK;
3594
developere40952c2023-06-15 18:46:43 +08003595 res = snprintf(str_idx, sizeof(str_idx), "%lu", channel);
3596 if (os_snprintf_error(sizeof(str_idx), res)) {
3597 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3598 return RETURN_ERR;
3599 }
3600
developera3511852023-06-14 14:12:59 +08003601 list[0].name = "vht_oper_centr_freq_seg0_idx";
3602 list[0].value = str_idx;
3603 list[1].name = "he_oper_centr_freq_seg0_idx";
3604 list[1].value = str_idx;
3605
3606 wifi_getMaxRadioNumber(&max_num_radios);
3607 for(int i=0; i<=MAX_APS/max_num_radios; i++)
3608 {
developere40952c2023-06-15 18:46:43 +08003609 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
3610 if (os_snprintf_error(sizeof(config_file), res)) {
3611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3612 return RETURN_ERR;
3613 }
developera3511852023-06-14 14:12:59 +08003614 if (band == band_6)
3615 wifi_hostapdWrite(config_file, &list[1], 1);
3616 else
3617 wifi_hostapdWrite(config_file, list, 2);
3618 }
3619
3620 return RETURN_OK;
3621}
3622
3623//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
3624//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
3625INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
3626{
3627 //Set to wifi config only. Wait for wifi reset to apply.
3628 ULONG Value = 0;
3629 char config_file_dat[128] = {0};
3630 struct params acs = {0};
3631 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003632 int res;
developera3511852023-06-14 14:12:59 +08003633
3634 if(enable == TRUE) {
3635 wifi_setRadioChannel(radioIndex,Value);
3636 } else {
3637 acs.name = "AutoChannelSelect";
3638 acs.value = "0";
3639 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08003640 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3641 if (os_snprintf_error(sizeof(config_file_dat), res)) {
3642 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3643 return RETURN_ERR;
3644 }
developera3511852023-06-14 14:12:59 +08003645 wifi_datfileWrite(config_file_dat, &acs, 1);
3646 }
3647 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003648}
3649
3650INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
3651{
developera3511852023-06-14 14:12:59 +08003652 if (output_bool == NULL)
3653 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003654
developera3511852023-06-14 14:12:59 +08003655 *output_bool = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08003656
developera3511852023-06-14 14:12:59 +08003657 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003658}
3659
3660INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
3661{
developera3511852023-06-14 14:12:59 +08003662 if (NULL == output_bool)
3663 return RETURN_ERR;
3664 *output_bool=FALSE;
3665 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003666}
3667
3668INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
3669{
developera3511852023-06-14 14:12:59 +08003670 if (NULL == output_bool)
3671 return RETURN_ERR;
3672 *output_bool=FALSE;
3673 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003674}
3675
developera3511852023-06-14 14:12:59 +08003676INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003677{
developera3511852023-06-14 14:12:59 +08003678 //Set to wifi config only. Wait for wifi reset to apply.
3679 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003680}
3681
3682INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
3683{
developera3511852023-06-14 14:12:59 +08003684 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003685}
3686
3687INT wifi_factoryResetAP(int apIndex)
3688{
developerb149d9d2023-06-06 16:14:22 +08003689 char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08003690 char cmd[MAX_CMD_SIZE] = {0};
3691 char ret_buf[MAX_BUF_SIZE] = {0};
3692 int radio_idx = 0;
3693 int bss_idx = 0;
3694 char ssid[32] = {0};
3695 char interface[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08003696 char psk_file[MAX_SUB_CMD_SIZE] = {0};
developera3511852023-06-14 14:12:59 +08003697 struct params params[3] = {0};
developere40952c2023-06-15 18:46:43 +08003698 int res;
developer72fb0bb2023-01-11 09:46:29 +08003699
developera3511852023-06-14 14:12:59 +08003700 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003701
developer47cc27a2023-05-17 23:09:58 +08003702 /*del old config file*/
developere40952c2023-06-15 18:46:43 +08003703 res = snprintf(ap_config_file, MAX_CMD_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
3704 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
3705 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3706 return RETURN_ERR;
3707 }
3708
3709 res = snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
3710 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
3711 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3712 return RETURN_ERR;
3713 }
3714
developer47cc27a2023-05-17 23:09:58 +08003715 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003716
developer47cc27a2023-05-17 23:09:58 +08003717 memset(cmd, 0, sizeof(cmd));
3718 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003719
developer47cc27a2023-05-17 23:09:58 +08003720 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
3721
3722 /*prepare new config file*/
developere40952c2023-06-15 18:46:43 +08003723 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
3724 if (os_snprintf_error(sizeof(cmd), res)) {
3725 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3726 return RETURN_ERR;
3727 }
3728
developer47cc27a2023-05-17 23:09:58 +08003729 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3730
3731 if (radio_idx == band_2_4) {
developere40952c2023-06-15 18:46:43 +08003732 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
3733 if (os_snprintf_error(sizeof(ssid), res)) {
3734 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3735 return RETURN_ERR;
3736 }
3737
3738 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
3739 if (os_snprintf_error(sizeof(interface), res)) {
3740 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3741 return RETURN_ERR;
3742 }
developer47cc27a2023-05-17 23:09:58 +08003743 } else if (radio_idx == band_5) {
developere40952c2023-06-15 18:46:43 +08003744 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
3745 if (os_snprintf_error(sizeof(ssid), res)) {
3746 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3747 return RETURN_ERR;
3748 }
3749
3750 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
3751 if (os_snprintf_error(sizeof(interface), res)) {
3752 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3753 return RETURN_ERR;
3754 }
developer47cc27a2023-05-17 23:09:58 +08003755 } else if (radio_idx == band_6) {
developere40952c2023-06-15 18:46:43 +08003756 res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
3757 if (os_snprintf_error(sizeof(ssid), res)) {
3758 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3759 return RETURN_ERR;
3760 }
3761
3762 res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
3763 if (os_snprintf_error(sizeof(interface), res)) {
3764 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3765 return RETURN_ERR;
3766 }
developer47cc27a2023-05-17 23:09:58 +08003767 }
3768
3769 /* fix wpa_psk_file path */
developere40952c2023-06-15 18:46:43 +08003770 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
3771 if (os_snprintf_error(sizeof(psk_file), res)) {
3772 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3773 return RETURN_ERR;
3774 }
developer47cc27a2023-05-17 23:09:58 +08003775
3776 params[0].name = "ssid";
3777 params[0].value = ssid;
3778 params[1].name = "interface";
3779 params[1].value = interface;
3780 params[2].name = "wpa_psk_file";
3781 params[2].value = psk_file;
3782
3783 wifi_hostapdWrite(ap_config_file, params, 3);
3784
3785 /*clear psk file*/
3786 memset(cmd, 0, sizeof(cmd));
3787 memset(ret_buf, 0, sizeof(ret_buf));
3788
developere40952c2023-06-15 18:46:43 +08003789 res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
3790 if (os_snprintf_error(sizeof(psk_file), res)) {
3791 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3792 return RETURN_ERR;
3793 }
developer47cc27a2023-05-17 23:09:58 +08003794
3795 if (access(psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08003796 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
3797 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
3798 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3799 return RETURN_ERR;
3800 }
3801
developer47cc27a2023-05-17 23:09:58 +08003802 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3803 } else {
developere40952c2023-06-15 18:46:43 +08003804 res = snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
3805 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
3806 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3807 return RETURN_ERR;
3808 }
3809
developer47cc27a2023-05-17 23:09:58 +08003810 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3811 }
3812
developer429ba832023-05-31 11:03:35 +08003813 wifi_setApEnable(apIndex, FALSE);
3814 wifi_setApEnable(apIndex, TRUE);
developer47cc27a2023-05-17 23:09:58 +08003815 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3816
3817 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003818}
3819
developer72fb0bb2023-01-11 09:46:29 +08003820INT wifi_setBandSteeringApGroup(char *ApGroup)
3821{
developera3511852023-06-14 14:12:59 +08003822 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003823}
3824
3825INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
3826{
developera3511852023-06-14 14:12:59 +08003827 char config_file[128] = {'\0'};
3828 char buf[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +08003829 int res;
developer72fb0bb2023-01-11 09:46:29 +08003830
developera3511852023-06-14 14:12:59 +08003831 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3832 if (dtimInterval == NULL)
3833 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08003834
3835 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
3836 if (os_snprintf_error(sizeof(config_file), res)) {
3837 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3838 return RETURN_ERR;
3839 }
developer72fb0bb2023-01-11 09:46:29 +08003840
developera3511852023-06-14 14:12:59 +08003841 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003842
developera3511852023-06-14 14:12:59 +08003843 if (strlen(buf) == 0) {
3844 *dtimInterval = 2;
3845 } else {
3846 *dtimInterval = strtoul(buf, NULL, 10);
3847 }
developer72fb0bb2023-01-11 09:46:29 +08003848
developera3511852023-06-14 14:12:59 +08003849 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3850 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003851}
3852
3853INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
3854{
developera3511852023-06-14 14:12:59 +08003855 struct params params={0};
3856 char config_file[MAX_BUF_SIZE] = {'\0'};
3857 char buf[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08003858 int res;
developer72fb0bb2023-01-11 09:46:29 +08003859
developera3511852023-06-14 14:12:59 +08003860 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3861 if (dtimInterval < 1 || dtimInterval > 255) {
3862 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
3863 return RETURN_ERR;
3864 }
developer69b61b02023-03-07 17:17:44 +08003865
developera3511852023-06-14 14:12:59 +08003866 params.name = "dtim_period";
developere40952c2023-06-15 18:46:43 +08003867 res = snprintf(buf, sizeof(buf), "%d", dtimInterval);
3868 if (os_snprintf_error(sizeof(buf), res)) {
3869 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3870 return RETURN_ERR;
3871 }
developera3511852023-06-14 14:12:59 +08003872 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08003873
developera3511852023-06-14 14:12:59 +08003874 sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex);
3875 wifi_hostapdWrite(config_file, &params, 1);
3876 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08003877
developera3511852023-06-14 14:12:59 +08003878 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3879 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003880}
3881
3882//Check if the driver support the Dfs
3883INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
3884{
developera3511852023-06-14 14:12:59 +08003885 wifi_band band = band_invalid;
3886 if (NULL == output_bool)
3887 return RETURN_ERR;
3888 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +08003889
developera3511852023-06-14 14:12:59 +08003890 band = wifi_index_to_band(radioIndex);
3891 if (band == band_5)
3892 *output_bool = TRUE;
3893 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003894}
3895
3896//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.
3897//The value of this parameter is a comma seperated list of channel number
3898INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
3899{
developere40952c2023-06-15 18:46:43 +08003900 int res;
3901
developera3511852023-06-14 14:12:59 +08003902 if (NULL == output_pool)
3903 return RETURN_ERR;
3904 if (radioIndex==1)
3905 return RETURN_OK;//TODO need to handle for 5GHz band, i think
developere40952c2023-06-15 18:46:43 +08003906 res = snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
3907 if (os_snprintf_error(256, res)) {
3908 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3909 return RETURN_ERR;
3910 }
developer72fb0bb2023-01-11 09:46:29 +08003911
developera3511852023-06-14 14:12:59 +08003912 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003913}
3914
3915INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
3916{
developera3511852023-06-14 14:12:59 +08003917 //Set to wifi config. And apply instantly.
3918 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003919}
3920
3921INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
3922{
developera3511852023-06-14 14:12:59 +08003923 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
3924 return RETURN_ERR;
3925 *output_interval_seconds=1800;
3926 *output_dwell_milliseconds=40;
developer72fb0bb2023-01-11 09:46:29 +08003927
developera3511852023-06-14 14:12:59 +08003928 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003929}
3930
3931INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
3932{
developera3511852023-06-14 14:12:59 +08003933 //Set to wifi config. And apply instantly.
3934 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003935}
3936
3937INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
3938{
developera3511852023-06-14 14:12:59 +08003939 if (output_bool == NULL)
3940 return RETURN_ERR;
3941 *output_bool = true;
3942 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003943}
3944
3945INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
3946{
developera3511852023-06-14 14:12:59 +08003947 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003948}
3949
3950//Get the Dfs enable status
3951INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
3952{
developera3511852023-06-14 14:12:59 +08003953 char buf[16] = {0};
3954 char config_file_dat[128] = {0};
3955 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003956 int res;
developer72fb0bb2023-01-11 09:46:29 +08003957
developera3511852023-06-14 14:12:59 +08003958 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003959
developera3511852023-06-14 14:12:59 +08003960 if (output_bool == NULL)
3961 return RETURN_ERR;
3962 *output_bool = TRUE; // default
3963 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08003964 res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3965 if (os_snprintf_error(sizeof(config_file_dat), res)) {
3966 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
3967 return RETURN_ERR;
3968 }
developerd1824452023-05-18 12:30:04 +08003969
developera3511852023-06-14 14:12:59 +08003970 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08003971
developera3511852023-06-14 14:12:59 +08003972 if (strncmp(buf, "0", 1) == 0)
3973 *output_bool = FALSE;
3974 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3975 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003976}
3977
3978//Set the Dfs enable status
3979INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
3980{
developera3511852023-06-14 14:12:59 +08003981 char config_dat_file[128] = {0};
3982 FILE *f = NULL;
3983 struct params dat = {0};
3984 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08003985 int res;
developer72fb0bb2023-01-11 09:46:29 +08003986
developera3511852023-06-14 14:12:59 +08003987 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003988
developera3511852023-06-14 14:12:59 +08003989 f = fopen(DFS_ENABLE_FILE, "w");
3990 if (f == NULL)
3991 return RETURN_ERR;
3992 fprintf(f, "%d", enable);
3993 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08003994
developera3511852023-06-14 14:12:59 +08003995 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08003996
developera3511852023-06-14 14:12:59 +08003997 dat.name = "DfsEnable";
3998 dat.value = enable?"1":"0";
3999 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004000 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4001 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4002 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4003 return RETURN_ERR;
4004 }
4005
developera3511852023-06-14 14:12:59 +08004006 wifi_datfileWrite(config_dat_file, &dat, 1);
4007 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4008 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004009}
4010
4011//Check if the driver support the AutoChannelRefreshPeriod
4012INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
4013{
developera3511852023-06-14 14:12:59 +08004014 if (NULL == output_bool)
4015 return RETURN_ERR;
4016 *output_bool=FALSE; //not support
developer72fb0bb2023-01-11 09:46:29 +08004017
developera3511852023-06-14 14:12:59 +08004018 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004019}
4020
4021//Get the ACS refresh period in seconds
4022INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
4023{
developera3511852023-06-14 14:12:59 +08004024 if (NULL == output_ulong)
4025 return RETURN_ERR;
4026 *output_ulong=300;
developer72fb0bb2023-01-11 09:46:29 +08004027
developera3511852023-06-14 14:12:59 +08004028 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004029}
4030
4031//Set the ACS refresh period in seconds
4032INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
4033{
developera3511852023-06-14 14:12:59 +08004034 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004035}
4036
4037//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
4038//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.
4039INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
4040{
developera3511852023-06-14 14:12:59 +08004041 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
4042 char extchannel[128] = {0};
4043 char interface_name[64] = {0};
developere40952c2023-06-15 18:46:43 +08004044 int ret = 0, len=0, res;
developera3511852023-06-14 14:12:59 +08004045 BOOL radio_enable = FALSE;
4046 wifi_band band;
developer72fb0bb2023-01-11 09:46:29 +08004047
developera3511852023-06-14 14:12:59 +08004048 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004049
developera3511852023-06-14 14:12:59 +08004050 if (NULL == output_string) {
4051 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
4052 return RETURN_ERR;
4053 }
4054 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
4055 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
4056 return RETURN_ERR;
4057 }
4058 if (radio_enable != TRUE) {
4059 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
4060 return RETURN_OK;
4061 }
4062 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4063 return RETURN_ERR;
4064 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08004065
developere40952c2023-06-15 18:46:43 +08004066 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
4067 if (os_snprintf_error(sizeof(cmd), res)) {
4068 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4069 return RETURN_ERR;
4070 }
developera3511852023-06-14 14:12:59 +08004071 ret = _syscmd(cmd, buf, sizeof(buf));
4072 len = strlen(buf);
4073 if((ret != 0) || (len == 0))
4074 {
4075 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4076 return RETURN_ERR;
4077 }
developer8666b312023-03-24 14:05:31 +08004078
developera3511852023-06-14 14:12:59 +08004079 band = wifi_index_to_band(radioIndex);
4080 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
4081 wifi_getRadioExtChannel(radioIndex, extchannel);
developere40952c2023-06-15 18:46:43 +08004082 if (strncmp(extchannel, "Auto", 4) != 0) {
4083 res = snprintf(buf, sizeof(buf), "40");
4084 if (os_snprintf_error(sizeof(buf), res)) {
4085 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4086 return RETURN_ERR;
4087 }
4088 }
4089 }
4090 res = snprintf(output_string, 64, "%sMHz", buf);
4091 if (os_snprintf_error(64, res)) {
4092 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4093 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08004094 }
developera3511852023-06-14 14:12:59 +08004095 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004096
developera3511852023-06-14 14:12:59 +08004097 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004098}
4099
4100enum mwctl_chan_width {
4101 MWCTL_CHAN_WIDTH_20,
4102 MWCTL_CHAN_WIDTH_40,
4103 MWCTL_CHAN_WIDTH_80,
4104 MWCTL_CHAN_WIDTH_160,
4105 MWCTL_CHAN_WIDTH_320,
4106};
4107
4108struct bw_option {
4109 unsigned int bandwith;
4110 enum mwctl_chan_width mode;
4111};
4112
4113struct bw_option bw_opt[] = {
4114 {20, MWCTL_CHAN_WIDTH_20},
4115 {40, MWCTL_CHAN_WIDTH_40},
4116 {80, MWCTL_CHAN_WIDTH_80},
4117 {160, MWCTL_CHAN_WIDTH_160},
4118 {320, MWCTL_CHAN_WIDTH_320},
4119};
4120
4121INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
4122{
4123 int ret = -1;
4124 int i;
4125 struct unl unl_ins;
4126 struct nl_msg *msg = NULL;
4127 struct nlattr * msg_data = NULL;
4128 struct mtk_nl80211_param param;
4129 bool b_match = FALSE;
4130
4131 /*init mtk nl80211 vendor cmd*/
4132 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
4133 param.if_type = NL80211_ATTR_WIPHY;
4134 param.if_idx = radio_index_to_phy(radioIndex);
4135
4136 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4137 if (ret) {
4138 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4139 return RETURN_ERR;
4140 }
4141
4142 /*add mtk vendor cmd data*/
4143 if (channel != NULL)
4144 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
4145 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
4146 nlmsg_free(msg);
4147 goto err;
4148 }
4149
4150 if (bandwidth != NULL) {
4151 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
4152 if (bw_opt[i].bandwith == *bandwidth) {
4153 b_match = true;
4154 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
4155 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
4156 nlmsg_free(msg);
4157 goto err;
4158 }
4159 break;
4160 }
4161 }
4162
4163 if (!b_match) {
4164 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
4165 nlmsg_free(msg);
4166 goto err;
4167 }
4168 }
4169
4170 /*send mtk nl80211 vendor msg*/
4171 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4172 if (ret) {
4173 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4174 goto err;
4175 }
4176 /*deinit mtk nl80211 vendor msg*/
4177 mtk_nl80211_deint(&unl_ins);
4178 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developera3511852023-06-14 14:12:59 +08004179 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developerfead3972023-05-25 20:15:02 +08004180
developera3511852023-06-14 14:12:59 +08004181 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004182err:
4183 mtk_nl80211_deint(&unl_ins);
4184 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4185 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004186}
developerfead3972023-05-25 20:15:02 +08004187
developer72fb0bb2023-01-11 09:46:29 +08004188//Set the Operating Channel Bandwidth.
4189INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
4190{
developera3511852023-06-14 14:12:59 +08004191 char config_file[128];
4192 char ht_value[16];
4193 char vht_value[16];
4194 char eht_value[16];
4195 struct params dat[3];
4196 wifi_band band = band_invalid;
4197 unsigned int bw = 20;
developere40952c2023-06-15 18:46:43 +08004198 int ret = 0, res1, res2, res3;
developer72fb0bb2023-01-11 09:46:29 +08004199
developera3511852023-06-14 14:12:59 +08004200 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004201
developera3511852023-06-14 14:12:59 +08004202 if(NULL == bandwidth)
4203 return RETURN_ERR;
4204 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004205
developera3511852023-06-14 14:12:59 +08004206 if(strstr(bandwidth,"320") != NULL) {
developere40952c2023-06-15 18:46:43 +08004207 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4208 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4209 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developera3511852023-06-14 14:12:59 +08004210 bw = 320;
4211 } else if(strstr(bandwidth,"160") != NULL) {
developere40952c2023-06-15 18:46:43 +08004212 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4213 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4214 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developera3511852023-06-14 14:12:59 +08004215 bw = 160;
4216 } else if(strstr(bandwidth,"80") != NULL) {
developere40952c2023-06-15 18:46:43 +08004217 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4218 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
4219 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developera3511852023-06-14 14:12:59 +08004220 bw = 80;
4221 } else if(strstr(bandwidth,"40") != NULL) {
developere40952c2023-06-15 18:46:43 +08004222 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4223 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4224 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developera3511852023-06-14 14:12:59 +08004225 bw = 40;
4226 } else if(strstr(bandwidth,"20") != NULL) {
developere40952c2023-06-15 18:46:43 +08004227 res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
4228 res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4229 res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developera3511852023-06-14 14:12:59 +08004230 bw = 20;
4231 } else {
4232 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
4233 return RETURN_ERR;
4234 }
developer72fb0bb2023-01-11 09:46:29 +08004235
developere40952c2023-06-15 18:46:43 +08004236 if (os_snprintf_error(sizeof(ht_value), res1)) {
4237 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4238 return RETURN_ERR;
4239 }
4240 if (os_snprintf_error(sizeof(vht_value), res2)) {
4241 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4242 return RETURN_ERR;
4243 }
4244 if (os_snprintf_error(sizeof(eht_value), res3)) {
4245 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4246 return RETURN_ERR;
4247 }
4248
4249 res1 = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4250 if (os_snprintf_error(sizeof(config_file), res1)) {
4251 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4252 return RETURN_ERR;
4253 }
developera3511852023-06-14 14:12:59 +08004254 dat[0].name = "HT_BW";
4255 dat[0].value = ht_value;
4256 dat[1].name = "VHT_BW";
4257 dat[1].value = vht_value;
4258 dat[2].name = "EHT_ApBw";
4259 dat[2].value = eht_value;
4260 wifi_datfileWrite(config_file, dat, 3);
4261 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
developerfead3972023-05-25 20:15:02 +08004262 if (ret != RETURN_OK) {
developera3511852023-06-14 14:12:59 +08004263 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
4264 return RETURN_ERR;
4265 }
developer72fb0bb2023-01-11 09:46:29 +08004266
developera3511852023-06-14 14:12:59 +08004267 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4268 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004269}
4270
developer72fb0bb2023-01-11 09:46:29 +08004271//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
4272//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.
4273INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
4274{
developera3511852023-06-14 14:12:59 +08004275 char config_file[64] = {0};
4276 char config_dat_file[64] = {0};
4277 char mode_str[16] = {0};
4278 char buf[64] = {0};
4279 char cmd[MAX_CMD_SIZE] = {0};
4280 char interface_name[64] = {0};
4281 int ret = 0, len=0;
4282 wifi_band band;
4283 ULONG channel = 0;
4284 int centr_channel = 0;
4285 UINT mode_map = 0;
developere40952c2023-06-15 18:46:43 +08004286 int freq=0, res;
developer72fb0bb2023-01-11 09:46:29 +08004287
developera3511852023-06-14 14:12:59 +08004288 if (output_string == NULL)
4289 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004290
developera3511852023-06-14 14:12:59 +08004291 wifi_getRadioMode(radioIndex, mode_str, &mode_map);
developer72fb0bb2023-01-11 09:46:29 +08004292
developera3511852023-06-14 14:12:59 +08004293 band = wifi_index_to_band(radioIndex);
4294 if (band == band_invalid)
4295 return RETURN_ERR;
4296 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4297 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004298
developere40952c2023-06-15 18:46:43 +08004299 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4300 if (os_snprintf_error(sizeof(config_file), res)) {
4301 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4302 return RETURN_ERR;
4303 }
4304
4305 res = snprintf(output_string, 64, "Auto");
4306 if (os_snprintf_error(64, res)) {
4307 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4308 return RETURN_ERR;
4309 }
developer72fb0bb2023-01-11 09:46:29 +08004310
developera3511852023-06-14 14:12:59 +08004311 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
4312 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
developere40952c2023-06-15 18:46:43 +08004313 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4314 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4315 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4316 return RETURN_ERR;
4317 }
4318
developera3511852023-06-14 14:12:59 +08004319 wifi_halgetRadioExtChannel(config_dat_file, output_string);
4320 if (!(mode_map&WIFI_MODE_N))
developere40952c2023-06-15 18:46:43 +08004321 res = snprintf(output_string, 64, "Auto");
developera3511852023-06-14 14:12:59 +08004322 } else {
4323 // 5G and 6G band with ac or ax mode.
4324 wifi_getRadioChannel(radioIndex, &channel);
developere40952c2023-06-15 18:46:43 +08004325 res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
4326 if (os_snprintf_error(sizeof(cmd), res)) {
4327 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4328 return RETURN_ERR;
4329 }
developerd1824452023-05-18 12:30:04 +08004330
developera3511852023-06-14 14:12:59 +08004331 ret = _syscmd(cmd, buf, sizeof(buf));
4332 len = strlen(buf);
4333 if((ret != 0) || (len == 0))
4334 {
4335 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4336 return RETURN_ERR;
4337 }
4338 sscanf(buf, "%d", &freq);
4339 centr_channel = ieee80211_frequency_to_channel(freq);
4340 if (centr_channel > (int)channel)
developere40952c2023-06-15 18:46:43 +08004341 res = snprintf(output_string, 64, "AboveControlChannel");
developera3511852023-06-14 14:12:59 +08004342 else
developere40952c2023-06-15 18:46:43 +08004343 res = snprintf(output_string, 64, "BelowControlChannel");
4344
4345 if (os_snprintf_error(64, res)) {
4346 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4347 return RETURN_ERR;
4348 }
developera3511852023-06-14 14:12:59 +08004349 }
developer72fb0bb2023-01-11 09:46:29 +08004350
developera3511852023-06-14 14:12:59 +08004351 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004352}
4353
4354//Set the extension channel.
4355INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08004356{
developera3511852023-06-14 14:12:59 +08004357 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4358 struct params params={0};
4359 char config_file[64] = {0};
4360 char config_dat_file[64] = {0};
4361 char ext_channel[64] = {0};
4362 char buf[128] = {0};
4363 char cmd[128] = {0};
4364 int max_radio_num =0, ret = 0, bandwidth = 0;
4365 unsigned long channel = 0;
4366 bool stbcEnable = FALSE;
4367 params.name = "ht_capab";
4368 wifi_band band;
developere40952c2023-06-15 18:46:43 +08004369 int res;
developer72fb0bb2023-01-11 09:46:29 +08004370
developera3511852023-06-14 14:12:59 +08004371 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
developere40952c2023-06-15 18:46:43 +08004372 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
4373 if (os_snprintf_error(sizeof(cmd), res)) {
4374 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4375 return RETURN_ERR;
4376 }
developera3511852023-06-14 14:12:59 +08004377 _syscmd(cmd, buf, sizeof(buf));
4378 if (strlen(buf) != 0)
4379 stbcEnable = TRUE;
4380 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
4381 return RETURN_ERR;
4382 bandwidth = strtol(buf, NULL, 10);
4383 // TDK expected to get error with 20MHz
4384 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
4385 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
4386 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004387
developera3511852023-06-14 14:12:59 +08004388 band = wifi_index_to_band(radioIndex);
4389 if (band == band_invalid)
4390 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004391
developera3511852023-06-14 14:12:59 +08004392 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
4393 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004394
developere40952c2023-06-15 18:46:43 +08004395 res = snprintf(buf, sizeof(buf), "HT%d", bandwidth);
4396 if (os_snprintf_error(sizeof(buf), res)) {
4397 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4398 return RETURN_ERR;
4399 }
developera3511852023-06-14 14:12:59 +08004400 ret = util_get_sec_chan_offset(channel, buf);
4401 if (ret == -EINVAL)
4402 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004403
developera3511852023-06-14 14:12:59 +08004404 if(NULL!= strstr(string,"Above")) {
4405 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
4406 return RETURN_OK;
developer262f4cb2023-05-24 12:22:04 +08004407 strcpy(ext_channel, "Above");
developera3511852023-06-14 14:12:59 +08004408 } else if(NULL!= strstr(string,"Below")) {
4409 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
4410 return RETURN_OK;
4411 strcpy(ext_channel, "Below");
4412 } else {
4413 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08004414 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08004415 }
4416 params.name = "HT_EXTCHA";
4417 params.value = ext_channel;
developer72fb0bb2023-01-11 09:46:29 +08004418
developera3511852023-06-14 14:12:59 +08004419 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developere40952c2023-06-15 18:46:43 +08004420 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4421 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4422 return RETURN_ERR;
4423 }
developera3511852023-06-14 14:12:59 +08004424 wifi_datfileWrite(config_dat_file, &params, 1);
developerd1824452023-05-18 12:30:04 +08004425
developera3511852023-06-14 14:12:59 +08004426 wifi_getMaxRadioNumber(&max_radio_num);
4427 for(int i=0; i<=MAX_APS/max_radio_num; i++)
4428 {
4429 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
4430 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
4431 }
developer72fb0bb2023-01-11 09:46:29 +08004432
developera3511852023-06-14 14:12:59 +08004433 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
4434 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4435 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004436}
4437
4438//Get the guard interval value. eg "400nsec" or "800nsec"
4439//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.
4440INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
4441{
developera3511852023-06-14 14:12:59 +08004442 wifi_guard_interval_t GI;
developer72fb0bb2023-01-11 09:46:29 +08004443
developera3511852023-06-14 14:12:59 +08004444 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004445
developera3511852023-06-14 14:12:59 +08004446 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
4447 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004448
developera3511852023-06-14 14:12:59 +08004449 if (GI == wifi_guard_interval_400)
4450 strcpy(output_string, "400nsec");
4451 else if (GI == wifi_guard_interval_800)
4452 strcpy(output_string, "800nsec");
4453 else if (GI == wifi_guard_interval_1600)
4454 strcpy(output_string, "1600nsec");
4455 else if (GI == wifi_guard_interval_3200)
4456 strcpy(output_string, "3200nsec");
4457 else
4458 strcpy(output_string, "Auto");
developer72fb0bb2023-01-11 09:46:29 +08004459
developera3511852023-06-14 14:12:59 +08004460 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4461 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004462}
4463
4464//Set the guard interval value.
4465INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
4466{
developera3511852023-06-14 14:12:59 +08004467 wifi_guard_interval_t GI;
4468 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08004469
developera3511852023-06-14 14:12:59 +08004470 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004471
developera3511852023-06-14 14:12:59 +08004472 if (strcmp(string, "400nsec") == 0)
4473 GI = wifi_guard_interval_400;
4474 else if (strcmp(string , "800nsec") == 0)
4475 GI = wifi_guard_interval_800;
4476 else if (strcmp(string , "1600nsec") == 0)
4477 GI = wifi_guard_interval_1600;
4478 else if (strcmp(string , "3200nsec") == 0)
4479 GI = wifi_guard_interval_3200;
4480 else
4481 GI = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +08004482
developera3511852023-06-14 14:12:59 +08004483 ret = wifi_setGuardInterval(radioIndex, GI);
developer72fb0bb2023-01-11 09:46:29 +08004484
developera3511852023-06-14 14:12:59 +08004485 if (ret == RETURN_ERR) {
4486 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
4487 return RETURN_ERR;
4488 }
developer72fb0bb2023-01-11 09:46:29 +08004489
developera3511852023-06-14 14:12:59 +08004490 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4491 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004492}
4493
4494//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
4495INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
4496{
developera3511852023-06-14 14:12:59 +08004497 char buf[32]={0};
4498 char mcs_file[64] = {0};
4499 char cmd[MAX_CMD_SIZE] = {0};
4500 UINT mode_bitmap = 0;
developere40952c2023-06-15 18:46:43 +08004501 int res;
developer72fb0bb2023-01-11 09:46:29 +08004502
developera3511852023-06-14 14:12:59 +08004503 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4504 if(output_int == NULL)
4505 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004506 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4507 if (os_snprintf_error(sizeof(mcs_file), res)) {
4508 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4509 return RETURN_ERR;
4510 }
4511
4512 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
4513 if (os_snprintf_error(sizeof(cmd), res)) {
4514 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4515 return RETURN_ERR;
4516 }
developer72fb0bb2023-01-11 09:46:29 +08004517
developera3511852023-06-14 14:12:59 +08004518 _syscmd(cmd, buf, sizeof(buf));
4519 if (strlen(buf) > 0)
4520 *output_int = strtol(buf, NULL, 10);
4521 else {
4522 // output the max MCS for the current radio mode
4523 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
4524 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
4525 return RETURN_ERR;
4526 }
4527 if (mode_bitmap & WIFI_MODE_AX) {
4528 *output_int = 11;
4529 } else if (mode_bitmap & WIFI_MODE_AC) {
4530 *output_int = 9;
4531 } else if (mode_bitmap & WIFI_MODE_N) {
4532 *output_int = 7;
4533 }
4534 }
4535 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004536
developera3511852023-06-14 14:12:59 +08004537 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004538}
4539
4540//Set the Modulation Coding Scheme index
4541INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
4542{
developera3511852023-06-14 14:12:59 +08004543 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
4544 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
4545 char config_file[64] = {0};
4546 char set_value[16] = {0};
4547 char mcs_file[32] = {0};
4548 struct params set_config = {0};
4549 FILE *f = NULL;
4550 INT nss = 0;
4551 int ant_bitmap = 0;
4552 unsigned short cal_value = 0;
4553 UCHAR tval = 0, i = 0;
developere40952c2023-06-15 18:46:43 +08004554 int res;
developer72fb0bb2023-01-11 09:46:29 +08004555
developera3511852023-06-14 14:12:59 +08004556 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004557
developere40952c2023-06-15 18:46:43 +08004558 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4559 if (os_snprintf_error(sizeof(config_file), res)) {
4560 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4561 return RETURN_ERR;
4562 }
developer72fb0bb2023-01-11 09:46:29 +08004563
developera3511852023-06-14 14:12:59 +08004564 // -1 means auto
4565 if (MCS > 15 || MCS < -1) {
4566 fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS);
4567 return RETURN_ERR;
4568 }
4569 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
4570 for(; ant_bitmap > 0; ant_bitmap >>= 1)
4571 nss += 1;
4572 //printf("%s:nss = %d\n", __func__, nss);
4573 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
4574 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
4575 if (MCS > 9 || MCS == -1)
4576 tval = 2;/*one stream value*/
4577 else if (MCS > 7)
4578 tval = 1;
4579 else
4580 tval = 0;
4581 for (i = 0; i < nss; i++)
4582 cal_value |= (tval << (2*i));
developere40952c2023-06-15 18:46:43 +08004583 res = snprintf(set_value, sizeof(set_value), "%x", cal_value);
4584 if (os_snprintf_error(sizeof(set_value), res)) {
4585 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4586 return RETURN_ERR;
4587 }
4588
developera3511852023-06-14 14:12:59 +08004589 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
4590 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
4591 set_config.value = set_value;
developer72fb0bb2023-01-11 09:46:29 +08004592
developera3511852023-06-14 14:12:59 +08004593 wifi_hostapdWrite(config_file, &set_config, 1);
4594 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
developer72fb0bb2023-01-11 09:46:29 +08004595
developera3511852023-06-14 14:12:59 +08004596 // 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 +08004597 res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4598 if (os_snprintf_error(sizeof(mcs_file), res)) {
4599 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4600 return RETURN_ERR;
4601 }
4602
developera3511852023-06-14 14:12:59 +08004603 f = fopen(mcs_file, "w");
4604 if (f == NULL) {
4605 fprintf(stderr, "%s: fopen failed\n", __func__);
4606 return RETURN_ERR;
4607 }
4608 fprintf(f, "%d", MCS);
4609 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08004610
developera3511852023-06-14 14:12:59 +08004611 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4612 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004613}
4614
4615//Get supported Transmit Power list, eg : "0,25,50,75,100"
4616//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.
4617INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
4618{
developere40952c2023-06-15 18:46:43 +08004619 int res;
4620 if (NULL == output_list)
4621 return RETURN_ERR;
4622 res = snprintf(output_list, 64,"0,25,50,75,100");
4623 if (os_snprintf_error(64, res)) {
4624 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4625 return RETURN_ERR;
4626 }
4627
4628 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004629}
4630
4631//Get current Transmit Power in dBm units.
4632//The transmite power level is in units of full power for this radio.
4633INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
4634{
developera3511852023-06-14 14:12:59 +08004635 char interface_name[16] = {0};
4636 char cmd[MAX_CMD_SIZE]={0};
4637 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08004638 char pwr_file[128]={0};
developere40952c2023-06-15 18:46:43 +08004639 int res;
developera1255e42023-05-13 17:45:02 +08004640
developera3511852023-06-14 14:12:59 +08004641 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004642
developera3511852023-06-14 14:12:59 +08004643 if(output_ulong == NULL)
4644 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004645
developera3511852023-06-14 14:12:59 +08004646 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4647 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004648 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4649 if (os_snprintf_error(sizeof(pwr_file), res)) {
4650 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4651 return RETURN_ERR;
4652 }
4653
4654 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
4655 if (os_snprintf_error(sizeof(cmd), res)) {
4656 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4657 return RETURN_ERR;
4658 }
4659
developera1255e42023-05-13 17:45:02 +08004660 _syscmd(cmd, buf, sizeof(buf));
4661 if (strlen(buf) > 0)
4662 *output_ulong = strtol(buf, NULL, 10);
4663 else
4664 *output_ulong = 100;
developera3511852023-06-14 14:12:59 +08004665 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4666 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004667}
4668
4669//Set Transmit Power
4670//The transmite power level is in units of full power for this radio.
4671INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
4672{
developera3511852023-06-14 14:12:59 +08004673 char interface_name[16] = {0};
4674 char *support;
4675 char buf[128]={0};
4676 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08004677 char pwr_file[128]={0};
developera3511852023-06-14 14:12:59 +08004678 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08004679 int if_idx, ret = 0;
4680 struct nl_msg *msg = NULL;
4681 struct nlattr * msg_data = NULL;
4682 struct mtk_nl80211_param param;
4683 struct unl unl_ins;
developere40952c2023-06-15 18:46:43 +08004684 int res;
developer72fb0bb2023-01-11 09:46:29 +08004685
developera3511852023-06-14 14:12:59 +08004686 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004687
developera3511852023-06-14 14:12:59 +08004688 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4689 return RETURN_ERR;
4690 // Get the Tx power supported list and check that is the input in the list
developere40952c2023-06-15 18:46:43 +08004691 res = snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4692 if (os_snprintf_error(sizeof(txpower_str), res)) {
4693 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4694 return RETURN_ERR;
4695 }
developera3511852023-06-14 14:12:59 +08004696 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4697 support = strtok(buf, ",");
4698 while(true)
4699 {
4700 if(support == NULL) { // input not in the list
4701 wifi_dbg_printf("Input value is invalid.\n");
4702 return RETURN_ERR;
4703 }
4704 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4705 break;
4706 }
4707 support = strtok(NULL, ",");
4708 }
developerfead3972023-05-25 20:15:02 +08004709
4710 if_idx = if_nametoindex(interface_name);
4711 /*init mtk nl80211 vendor cmd*/
4712 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
4713 param.if_type = NL80211_ATTR_IFINDEX;
4714 param.if_idx = if_idx;
4715 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4716 if (ret) {
4717 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4718 return RETURN_ERR;
4719 }
4720 /*add mtk vendor cmd data*/
4721 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
4722 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4723 nlmsg_free(msg);
4724 goto err;
4725 }
4726
4727 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
4728 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4729 nlmsg_free(msg);
4730 goto err;
4731 }
4732
4733 /*send mtk nl80211 vendor msg*/
4734 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4735 if (ret) {
4736 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4737 goto err;
4738 }
4739 /*deinit mtk nl80211 vendor msg*/
4740 mtk_nl80211_deint(&unl_ins);
4741 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
4742
developere40952c2023-06-15 18:46:43 +08004743 res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4744 if (os_snprintf_error(sizeof(pwr_file), res)) {
4745 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4746 return RETURN_ERR;
4747 }
4748
developera3511852023-06-14 14:12:59 +08004749 f = fopen(pwr_file, "w");
4750 if (f == NULL) {
4751 fprintf(stderr, "%s: fopen failed\n", __func__);
4752 return RETURN_ERR;
4753 }
4754 fprintf(f, "%lu", TransmitPower);
4755 fclose(f);
developera1255e42023-05-13 17:45:02 +08004756 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004757err:
4758 mtk_nl80211_deint(&unl_ins);
4759 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4760 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004761}
4762
4763//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
4764INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
4765{
developera3511852023-06-14 14:12:59 +08004766 if (NULL == Supported)
4767 return RETURN_ERR;
4768 *Supported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08004769
developera3511852023-06-14 14:12:59 +08004770 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004771}
4772
4773//Get 80211h feature enable
4774INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
4775{
developera3511852023-06-14 14:12:59 +08004776 char buf[64]={'\0'};
4777 char config_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08004778
developera3511852023-06-14 14:12:59 +08004779 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4780 if(enable == NULL)
4781 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004782
developera3511852023-06-14 14:12:59 +08004783 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4784 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
4785 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004786
developera3511852023-06-14 14:12:59 +08004787 if (strncmp(buf, "1", 1) == 0)
4788 *enable = TRUE;
4789 else
4790 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08004791
developera3511852023-06-14 14:12:59 +08004792 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4793 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004794}
4795
4796//Set 80211h feature enable
4797INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
4798{
developera3511852023-06-14 14:12:59 +08004799 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4800 struct params params={'\0'};
4801 struct params dat={0};
4802 char config_file[MAX_BUF_SIZE] = {0};
4803 char config_dat_file[MAX_BUF_SIZE] = {0};
4804 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08004805 int res;
developer72fb0bb2023-01-11 09:46:29 +08004806
developera3511852023-06-14 14:12:59 +08004807 params.name = "ieee80211h";
developer72fb0bb2023-01-11 09:46:29 +08004808
developera3511852023-06-14 14:12:59 +08004809 if (enable) {
4810 params.value = "1";
4811 } else {
4812 params.value = "0";
4813 }
developer72fb0bb2023-01-11 09:46:29 +08004814
developera3511852023-06-14 14:12:59 +08004815 dat.name = "IEEE80211H";
4816 dat.value = params.value;
developerd1824452023-05-18 12:30:04 +08004817
developera3511852023-06-14 14:12:59 +08004818 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +08004819 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4820 if (os_snprintf_error(sizeof(config_file), res)) {
4821 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4822 return RETURN_ERR;
4823 }
4824
4825 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4826 if (os_snprintf_error(sizeof(config_dat_file), res)) {
4827 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4828 return RETURN_ERR;
4829 }
developer69b61b02023-03-07 17:17:44 +08004830
developera3511852023-06-14 14:12:59 +08004831 wifi_hostapdWrite(config_file, &params, 1);
4832 wifi_datfileWrite(config_dat_file, &dat, 1);
4833 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4834 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4835 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004836}
4837
4838//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.
4839INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
4840{
developera3511852023-06-14 14:12:59 +08004841 if (NULL == output)
4842 return RETURN_ERR;
4843 *output=100;
developer72fb0bb2023-01-11 09:46:29 +08004844
developera3511852023-06-14 14:12:59 +08004845 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004846}
4847
4848//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.
4849INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
4850{
developera3511852023-06-14 14:12:59 +08004851 if (NULL == output)
4852 return RETURN_ERR;
4853 *output = -99;
developer72fb0bb2023-01-11 09:46:29 +08004854
developera3511852023-06-14 14:12:59 +08004855 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004856}
4857
4858INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
4859{
developera3511852023-06-14 14:12:59 +08004860 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004861}
4862
4863
4864//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
4865INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
4866{
developera3511852023-06-14 14:12:59 +08004867 char interface_name[16] = {0};
4868 char cmd[MAX_BUF_SIZE]={'\0'};
4869 char buf[MAX_CMD_SIZE]={'\0'};
developere40952c2023-06-15 18:46:43 +08004870 int res;
developer72fb0bb2023-01-11 09:46:29 +08004871
developera3511852023-06-14 14:12:59 +08004872 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4873 if(output == NULL)
4874 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004875
developera3511852023-06-14 14:12:59 +08004876 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4877 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08004878 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
4879 if (os_snprintf_error(sizeof(cmd), res)) {
4880 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4881 return RETURN_ERR;
4882 }
4883
developera3511852023-06-14 14:12:59 +08004884 _syscmd(cmd, buf, sizeof(buf));
4885 *output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08004886
developera3511852023-06-14 14:12:59 +08004887 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4888 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004889}
developer69b61b02023-03-07 17:17:44 +08004890
developer72fb0bb2023-01-11 09:46:29 +08004891INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
4892{
developera3511852023-06-14 14:12:59 +08004893 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4894 struct params params={'\0'};
4895 char buf[MAX_BUF_SIZE] = {'\0'};
4896 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08004897 int res;
developer72fb0bb2023-01-11 09:46:29 +08004898
developera3511852023-06-14 14:12:59 +08004899 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
4900 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004901
developera3511852023-06-14 14:12:59 +08004902 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08004903 res = snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
4904 if (os_snprintf_error(sizeof(buf), res)) {
4905 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
4906 return RETURN_ERR;
4907 }
4908
developera3511852023-06-14 14:12:59 +08004909 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08004910
developera3511852023-06-14 14:12:59 +08004911 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4912 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08004913
developera3511852023-06-14 14:12:59 +08004914 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4915 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4916 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004917}
4918
4919//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.
4920INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
4921{
developera3511852023-06-14 14:12:59 +08004922 //TODO: need to revisit below implementation
4923 char *temp;
4924 char temp_output[128] = {0};
4925 char temp_TransmitRates[64] = {0};
4926 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004927
developera3511852023-06-14 14:12:59 +08004928 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4929 if (NULL == output)
4930 return RETURN_ERR;
4931 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4932 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08004933
developera3511852023-06-14 14:12:59 +08004934 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
4935 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
4936 } else {
4937 temp = strtok(temp_TransmitRates," ");
4938 while(temp!=NULL)
4939 {
4940 // Convert 100 kbps to Mbps
4941 temp[strlen(temp)-1]=0;
4942 if((temp[0]=='5') && (temp[1]=='\0'))
4943 {
4944 temp="5.5";
4945 }
4946 strcat(temp_output,temp);
4947 temp = strtok(NULL," ");
4948 if(temp!=NULL)
4949 {
4950 strcat(temp_output,",");
4951 }
4952 }
4953 strcpy(output,temp_output);
4954 }
4955 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4956 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004957}
4958
4959INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
4960{
developera3511852023-06-14 14:12:59 +08004961 char *temp;
4962 char temp1[128];
4963 char temp_output[128];
4964 char temp_TransmitRates[128];
4965 char set[128];
4966 char sub_set[128];
4967 int set_count=0,subset_count=0;
4968 int set_index=0,subset_index=0;
4969 char *token;
4970 int flag=0, i=0;
4971 struct params params={'\0'};
4972 char config_file[MAX_BUF_SIZE] = {0};
4973 wifi_band band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004974
developera3511852023-06-14 14:12:59 +08004975 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4976 if(NULL == TransmitRates)
4977 return RETURN_ERR;
4978 strcpy(sub_set,TransmitRates);
developer72fb0bb2023-01-11 09:46:29 +08004979
developera3511852023-06-14 14:12:59 +08004980 //Allow only supported Data transmit rate to be set
4981 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
4982 token = strtok(sub_set,",");
4983 while( token != NULL ) /* split the basic rate to be set, by comma */
4984 {
4985 sub_set[subset_count]=atoi(token);
4986 subset_count++;
4987 token=strtok(NULL,",");
4988 }
4989 token=strtok(set,",");
4990 while(token!=NULL) /* split the supported rate by comma */
4991 {
4992 set[set_count]=atoi(token);
4993 set_count++;
4994 token=strtok(NULL,",");
4995 }
4996 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
4997 {
4998 for(set_index=0;set_index < set_count;set_index++)
4999 {
5000 flag=0;
5001 if(sub_set[subset_index]==set[set_index])
5002 break;
5003 else
5004 flag=1; /* No match found */
5005 }
5006 if(flag==1)
5007 return RETURN_ERR; //If value not found return Error
5008 }
5009 strcpy(temp_TransmitRates,TransmitRates);
developer72fb0bb2023-01-11 09:46:29 +08005010
developera3511852023-06-14 14:12:59 +08005011 for(i=0;i<strlen(temp_TransmitRates);i++)
5012 {
5013 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
5014 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
5015 {
5016 continue;
5017 }
5018 else
5019 {
5020 return RETURN_ERR;
5021 }
5022 }
5023 strcpy(temp_output,"");
5024 temp = strtok(temp_TransmitRates,",");
5025 while(temp!=NULL)
5026 {
5027 strcpy(temp1,temp);
5028 if(band == band_5)
5029 {
5030 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
5031 {
5032 return RETURN_ERR;
5033 }
5034 }
developer72fb0bb2023-01-11 09:46:29 +08005035
developera3511852023-06-14 14:12:59 +08005036 if(strcmp(temp,"5.5")==0)
5037 {
5038 strcpy(temp1,"55");
5039 }
5040 else
5041 {
5042 strcat(temp1,"0");
5043 }
5044 strcat(temp_output,temp1);
5045 temp = strtok(NULL,",");
5046 if(temp!=NULL)
5047 {
5048 strcat(temp_output," ");
5049 }
5050 }
5051 strcpy(TransmitRates,temp_output);
developer72fb0bb2023-01-11 09:46:29 +08005052
developera3511852023-06-14 14:12:59 +08005053 params.name= "basic_rates";
5054 params.value =TransmitRates;
developer72fb0bb2023-01-11 09:46:29 +08005055
developera3511852023-06-14 14:12:59 +08005056 wifi_dbg_printf("\n%s:",__func__);
5057 wifi_dbg_printf("\nparams.value=%s\n",params.value);
5058 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
5059 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
5060 wifi_hostapdWrite(config_file,&params,1);
5061 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5062 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005063}
5064
5065//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
5066INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
5067{
developera3511852023-06-14 14:12:59 +08005068 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5069 FILE *fp = NULL;
5070 char path[256] = {0}, output_string[256] = {0};
5071 int count = 0;
5072 char *interface = NULL;
developer72fb0bb2023-01-11 09:46:29 +08005073
developera3511852023-06-14 14:12:59 +08005074 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
5075 if (fp == NULL)
5076 {
5077 printf("Failed to run command in Function %s\n", __FUNCTION__);
5078 return RETURN_ERR;
5079 }
5080 if (fgets(path, sizeof(path) - 1, fp) != NULL)
5081 {
5082 interface = strchr(path, '=');
developer72fb0bb2023-01-11 09:46:29 +08005083
developera3511852023-06-14 14:12:59 +08005084 if (interface != NULL)
5085 {
5086 strcpy(output_string, interface + 1);
5087 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
5088 interface_name[count] = output_string[count];
developer72fb0bb2023-01-11 09:46:29 +08005089
developera3511852023-06-14 14:12:59 +08005090 interface_name[count] = '\0';
5091 }
5092 }
5093 pclose(fp);
5094 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5095 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005096}
5097
5098INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
5099{
developera3511852023-06-14 14:12:59 +08005100 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5101 output_struct->radio_BytesSent = 0;
5102 output_struct->radio_BytesReceived = 0;
5103 output_struct->radio_PacketsSent = 0;
5104 output_struct->radio_PacketsReceived = 0;
5105 output_struct->radio_ErrorsSent = 0;
5106 output_struct->radio_ErrorsReceived = 0;
5107 output_struct->radio_DiscardPacketsSent = 0;
5108 output_struct->radio_DiscardPacketsReceived = 0;
5109 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5110 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005111}
5112
5113
5114INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
5115{
developera3511852023-06-14 14:12:59 +08005116 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5117 CHAR buf[MAX_CMD_SIZE] = {0};
5118 CHAR Value[MAX_BUF_SIZE] = {0};
5119 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08005120 int res;
developer72fb0bb2023-01-11 09:46:29 +08005121
developera3511852023-06-14 14:12:59 +08005122 if (ifname == NULL || strlen(ifname) <= 1)
5123 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005124
developere40952c2023-06-15 18:46:43 +08005125 res = snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
5126 if (os_snprintf_error(sizeof(buf), res)) {
5127 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5128 return RETURN_ERR;
5129 }
5130
developera3511852023-06-14 14:12:59 +08005131 system(buf);
developer72fb0bb2023-01-11 09:46:29 +08005132
developera3511852023-06-14 14:12:59 +08005133 fp = fopen("/tmp/Radio_Stats.txt", "r");
5134 if(fp == NULL)
5135 {
5136 printf("/tmp/Radio_Stats.txt not exists \n");
5137 return RETURN_ERR;
5138 }
5139 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +08005140
developera3511852023-06-14 14:12:59 +08005141 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5142 File_Reading(buf, Value);
5143 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005144
developera3511852023-06-14 14:12:59 +08005145 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5146 File_Reading(buf, Value);
5147 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005148
developera3511852023-06-14 14:12:59 +08005149 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5150 File_Reading(buf, Value);
5151 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005152
developera3511852023-06-14 14:12:59 +08005153 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5154 File_Reading(buf, Value);
5155 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005156
developera3511852023-06-14 14:12:59 +08005157 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5158 File_Reading(buf, Value);
5159 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005160
developera3511852023-06-14 14:12:59 +08005161 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5162 File_Reading(buf, Value);
5163 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005164
developera3511852023-06-14 14:12:59 +08005165 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5166 File_Reading(buf, Value);
5167 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005168
developera3511852023-06-14 14:12:59 +08005169 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5170 File_Reading(buf, Value);
5171 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005172
developera3511852023-06-14 14:12:59 +08005173 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5174 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005175}
5176
5177INT GetIfacestatus(CHAR *interface_name, CHAR *status)
5178{
developer7e4a2a62023-04-06 19:56:03 +08005179 CHAR buf[MAX_CMD_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005180
developer7e4a2a62023-04-06 19:56:03 +08005181 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5182
5183 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
5184 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
5185 File_Reading(buf, status);
5186 }
5187
5188 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5189 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005190}
5191
5192//Get detail radio traffic static info
5193INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
5194{
developera3511852023-06-14 14:12:59 +08005195 CHAR interface_name[64] = {0};
5196 BOOL iface_status = FALSE;
5197 wifi_radioTrafficStats2_t radioTrafficStats = {0};
developer72fb0bb2023-01-11 09:46:29 +08005198
developera3511852023-06-14 14:12:59 +08005199 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5200 if (NULL == output_struct)
5201 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005202
developera3511852023-06-14 14:12:59 +08005203 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5204 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005205
developera3511852023-06-14 14:12:59 +08005206 wifi_getApEnable(radioIndex, &iface_status);
developer72fb0bb2023-01-11 09:46:29 +08005207
developera3511852023-06-14 14:12:59 +08005208 if (iface_status == TRUE)
5209 wifi_halGetIfStats(interface_name, &radioTrafficStats);
5210 else
5211 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
developer72fb0bb2023-01-11 09:46:29 +08005212
developera3511852023-06-14 14:12:59 +08005213 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
5214 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
5215 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
5216 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
5217 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
5218 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
5219 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
5220 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +08005221
developera3511852023-06-14 14:12:59 +08005222 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
5223 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].
5224 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
5225 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.
5226 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
5227 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
5228 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
5229 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
5230 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 +08005231
developera3511852023-06-14 14:12:59 +08005232 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
5233 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
5234 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
5235 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 +08005236
developera3511852023-06-14 14:12:59 +08005237 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005238
developera3511852023-06-14 14:12:59 +08005239 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005240}
5241
5242//Set radio traffic static Measureing rules
5243INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
5244{
developera3511852023-06-14 14:12:59 +08005245 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005246}
5247
5248//To start or stop RadioTrafficStats
5249INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
5250{
developera3511852023-06-14 14:12:59 +08005251 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005252}
5253
5254//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
5255INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
5256{
developera3511852023-06-14 14:12:59 +08005257 if (NULL == SignalLevel)
5258 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08005259
developera3511852023-06-14 14:12:59 +08005260 *SignalLevel=(radioIndex==0)?-19:-19;
developer72fb0bb2023-01-11 09:46:29 +08005261
developera3511852023-06-14 14:12:59 +08005262 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005263}
5264
5265//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5266INT wifi_applyRadioSettings(INT radioIndex)
5267{
developera3511852023-06-14 14:12:59 +08005268 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005269}
5270
5271//Get the radio index assocated with this SSID entry
5272INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
5273{
developera3511852023-06-14 14:12:59 +08005274 if(NULL == radioIndex)
5275 return RETURN_ERR;
5276 int max_radio_num = 0;
5277 wifi_getMaxRadioNumber(&max_radio_num);
5278 *radioIndex = ssidIndex%max_radio_num;
5279 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005280}
5281
5282//Device.WiFi.SSID.{i}.Enable
5283//Get SSID enable configuration parameters (not the SSID enable status)
5284INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
5285{
developera3511852023-06-14 14:12:59 +08005286 if (NULL == output_bool)
5287 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005288
developera3511852023-06-14 14:12:59 +08005289 return wifi_getApEnable(ssidIndex, output_bool);
developer72fb0bb2023-01-11 09:46:29 +08005290}
5291
5292//Device.WiFi.SSID.{i}.Enable
5293//Set SSID enable configuration parameters
5294INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
5295{
developera3511852023-06-14 14:12:59 +08005296 return wifi_setApEnable(ssidIndex, enable);
developer72fb0bb2023-01-11 09:46:29 +08005297}
5298
5299//Device.WiFi.SSID.{i}.Status
5300//Get the SSID enable status
5301INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
5302{
developera3511852023-06-14 14:12:59 +08005303 BOOL output_bool;
developere40952c2023-06-15 18:46:43 +08005304 int res;
developer72fb0bb2023-01-11 09:46:29 +08005305
developera3511852023-06-14 14:12:59 +08005306 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5307 if (NULL == output_string)
5308 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08005309
developera3511852023-06-14 14:12:59 +08005310 wifi_getApEnable(ssidIndex,&output_bool);
developere40952c2023-06-15 18:46:43 +08005311 res = snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
5312 if (os_snprintf_error(32, res)) {
5313 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5314 return RETURN_ERR;
5315 }
developer72fb0bb2023-01-11 09:46:29 +08005316
developera3511852023-06-14 14:12:59 +08005317 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5318 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005319}
5320
5321// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
5322INT wifi_getSSIDName(INT apIndex, CHAR *output)
5323{
developera3511852023-06-14 14:12:59 +08005324 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005325
developera3511852023-06-14 14:12:59 +08005326 if (NULL == output)
5327 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005328
developera3511852023-06-14 14:12:59 +08005329 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5330 wifi_hostapdRead(config_file,"ssid",output,32);
developer72fb0bb2023-01-11 09:46:29 +08005331
developera3511852023-06-14 14:12:59 +08005332 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
5333 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005334}
5335
developer69b61b02023-03-07 17:17:44 +08005336// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08005337INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
5338{
developera3511852023-06-14 14:12:59 +08005339 struct params params;
5340 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005341
developera3511852023-06-14 14:12:59 +08005342 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5343 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
5344 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005345
developera3511852023-06-14 14:12:59 +08005346 params.name = "ssid";
5347 params.value = ssid_string;
5348 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5349 wifi_hostapdWrite(config_file, &params, 1);
5350 wifi_hostapdProcessUpdate(apIndex, &params, 1);
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//Get the BSSID
5357INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
5358{
developer7e4a2a62023-04-06 19:56:03 +08005359 char cmd[MAX_CMD_SIZE] = {0};
5360 char inf_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08005361 int res;
developer72fb0bb2023-01-11 09:46:29 +08005362
developera3511852023-06-14 14:12:59 +08005363 if (!output_string)
developerdaf24792023-06-06 11:40:04 +08005364 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005365
developer47cc27a2023-05-17 23:09:58 +08005366 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
5367 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08005368
developer5b2f10c2023-05-25 17:02:21 +08005369 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
5370 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
5371 strncpy(output_string, "\0", 1);
5372 return RETURN_ERR;
5373 }
developere40952c2023-06-15 18:46:43 +08005374 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
5375 if (os_snprintf_error(sizeof(cmd), res)) {
5376 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5377 return RETURN_ERR;
5378 }
5379
developer5b2f10c2023-05-25 17:02:21 +08005380 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08005381
developer5b2f10c2023-05-25 17:02:21 +08005382 /* if hostapd does not control interface even if this interface has been brought up,
5383 * try to get its mac address by iw command.
5384 */
5385 if(strlen(output_string) == 0) {
5386 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08005387 res = snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
5388 if (os_snprintf_error(sizeof(cmd), res)) {
5389 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5390 return RETURN_ERR;
5391 }
5392
developer5b2f10c2023-05-25 17:02:21 +08005393 _syscmd(cmd, output_string, 64);
5394 }
developer72fb0bb2023-01-11 09:46:29 +08005395
developer5b2f10c2023-05-25 17:02:21 +08005396 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005397}
5398
5399//Get the MAC address associated with this Wifi SSID
5400INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
5401{
developera3511852023-06-14 14:12:59 +08005402 wifi_getBaseBSSID(ssidIndex,output_string);
5403 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005404}
5405
5406//Get the basic SSID traffic static info
5407//Apply SSID and AP (in the case of Acess Point devices) to the hardware
5408//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5409INT wifi_applySSIDSettings(INT ssidIndex)
5410{
developera3511852023-06-14 14:12:59 +08005411 char interface_name[16] = {0};
5412 BOOL status = false;
5413 char cmd[MAX_CMD_SIZE] = {0};
5414 char buf[MAX_CMD_SIZE] = {0};
5415 int apIndex, ret;
5416 int max_radio_num = 0;
5417 int radioIndex = 0;
developere40952c2023-06-15 18:46:43 +08005418 int res;
developer72fb0bb2023-01-11 09:46:29 +08005419
developera3511852023-06-14 14:12:59 +08005420 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08005421
developera3511852023-06-14 14:12:59 +08005422 radioIndex = ssidIndex % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +08005423
developera3511852023-06-14 14:12:59 +08005424 wifi_getApEnable(ssidIndex,&status);
5425 // Do not apply when ssid index is disabled
5426 if (status == false)
5427 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005428
developera3511852023-06-14 14:12:59 +08005429 /* Doing full remove and add for ssid Index
5430 * Not all hostapd options are supported with reload
5431 * for example macaddr_acl
5432 */
5433 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
5434 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005435
developera3511852023-06-14 14:12:59 +08005436 ret = wifi_setApEnable(ssidIndex,true);
developer72fb0bb2023-01-11 09:46:29 +08005437
developera3511852023-06-14 14:12:59 +08005438 /* Workaround for hostapd issue with multiple bss definitions
5439 * when first created interface will be removed
5440 * then all vaps other vaps on same phy are removed
5441 * after calling setApEnable to false readd all enabled vaps */
5442 for(int i=0; i < MAX_APS/max_radio_num; i++) {
5443 apIndex = max_radio_num*i+radioIndex;
5444 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5445 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005446 res = snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
5447 if (os_snprintf_error(sizeof(cmd), res)) {
5448 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5449 return RETURN_ERR;
5450 }
5451
developera3511852023-06-14 14:12:59 +08005452 _syscmd(cmd, buf, sizeof(buf));
5453 if(*buf == '1')
5454 wifi_setApEnable(apIndex, true);
5455 }
developer72fb0bb2023-01-11 09:46:29 +08005456
developera3511852023-06-14 14:12:59 +08005457 return ret;
developer72fb0bb2023-01-11 09:46:29 +08005458}
5459
5460struct channels_noise {
developera3511852023-06-14 14:12:59 +08005461 int channel;
5462 int noise;
developer72fb0bb2023-01-11 09:46:29 +08005463};
5464
5465// Return noise array for each channel
5466int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
5467{
developera3511852023-06-14 14:12:59 +08005468 char interface_name[16] = {0};
5469 FILE *f = NULL;
5470 char cmd[128] = {0};
5471 char line[256] = {0};
5472 int tmp = 0, arr_index = -1;
developer72fb0bb2023-01-11 09:46:29 +08005473
developera3511852023-06-14 14:12:59 +08005474 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5475 return RETURN_ERR;
5476 sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08005477
developera3511852023-06-14 14:12:59 +08005478 if ((f = popen(cmd, "r")) == NULL) {
5479 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5480 return RETURN_ERR;
5481 }
developer69b61b02023-03-07 17:17:44 +08005482
developera3511852023-06-14 14:12:59 +08005483 while(fgets(line, sizeof(line), f) != NULL) {
5484 if(arr_index < channels_num){
5485 sscanf(line, "%d", &tmp);
5486 if (tmp > 0) { // channel frequency, the first line must be frequency
5487 arr_index++;
5488 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
5489 } else { // noise
5490 channels_noise_arr[arr_index].noise = tmp;
5491 }
5492 }else{
5493 break;
5494 }
5495 }
5496 pclose(f);
5497 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005498}
5499
5500//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
5501//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08005502INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08005503{
developera3511852023-06-14 14:12:59 +08005504 int index = -1;
5505 wifi_neighbor_ap2_t *scan_array = NULL;
5506 char cmd[256]={0};
5507 char buf[128]={0};
5508 char file_name[32] = {0};
5509 char filter_SSID[32] = {0};
5510 char line[256] = {0};
5511 char interface_name[16] = {0};
5512 char *ret = NULL;
5513 int freq=0;
5514 FILE *f = NULL;
5515 int channels_num = 0;
5516 int vht_channel_width = 0;
5517 int get_noise_ret = RETURN_ERR;
5518 bool filter_enable = false;
5519 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
developere40952c2023-06-15 18:46:43 +08005520 int phyId = 0, res;
developer72fb0bb2023-01-11 09:46:29 +08005521
developera3511852023-06-14 14:12:59 +08005522 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005523
developera3511852023-06-14 14:12:59 +08005524 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5525 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005526
5527 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
5528 if (os_snprintf_error(sizeof(file_name), res)) {
5529 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5530 return RETURN_ERR;
5531 }
developer72fb0bb2023-01-11 09:46:29 +08005532
developera3511852023-06-14 14:12:59 +08005533 f = fopen(file_name, "r");
5534 if (f != NULL) {
5535 fgets(buf, sizeof(file_name), f);
5536 if ((strncmp(buf, "0", 1)) != 0) {
5537 fgets(filter_SSID, sizeof(file_name), f);
5538 if (strlen(filter_SSID) != 0)
5539 filter_enable = true;
5540 }
5541 fclose(f);
5542 }
developer72fb0bb2023-01-11 09:46:29 +08005543
developera3511852023-06-14 14:12:59 +08005544 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08005545 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
5546 if (os_snprintf_error(sizeof(cmd), res)) {
5547 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5548 return RETURN_ERR;
5549 }
5550
developera3511852023-06-14 14:12:59 +08005551 _syscmd(cmd, buf, sizeof(buf));
5552 channels_num = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005553
developera3511852023-06-14 14:12:59 +08005554 sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
5555 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
5556 fprintf(stderr, "cmd: %s\n", cmd);
5557 if ((f = popen(cmd, "r")) == NULL) {
5558 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5559 return RETURN_ERR;
5560 }
developer69b61b02023-03-07 17:17:44 +08005561
developera3511852023-06-14 14:12:59 +08005562 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
5563 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08005564
developera3511852023-06-14 14:12:59 +08005565 ret = fgets(line, sizeof(line), f);
5566 while (ret != NULL) {
5567 if(strstr(line, "BSS") != NULL) { // new neighbor info
5568 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
5569 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
5570 // 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 +08005571
developera3511852023-06-14 14:12:59 +08005572 if (!filter_BSS) {
5573 index++;
5574 wifi_neighbor_ap2_t *tmp;
5575 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
5576 if (tmp == NULL) { // no more memory to use
5577 index--;
5578 wifi_dbg_printf("%s: realloc failed\n", __func__);
5579 break;
5580 }
5581 scan_array = tmp;
5582 }
5583 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +08005584
developera3511852023-06-14 14:12:59 +08005585 filter_BSS = false;
5586 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
developerc79e9172023-06-06 19:48:03 +08005587 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +08005588 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +08005589 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +08005590 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +08005591 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +08005592 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
5593 } else if (strstr(line, "freq") != NULL) {
5594 sscanf(line," freq: %d", &freq);
5595 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +08005596
developera3511852023-06-14 14:12:59 +08005597 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +08005598 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08005599 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +08005600 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08005601 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +08005602 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08005603 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
5604 }
5605 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +08005606 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +08005607 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +08005608 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +08005609 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +08005610 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +08005611 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
5612 }
developer72fb0bb2023-01-11 09:46:29 +08005613
developera3511852023-06-14 14:12:59 +08005614 scan_array[index].ap_Noise = 0;
5615 if (get_noise_ret == RETURN_OK) {
5616 for (int i = 0; i < channels_num; i++) {
5617 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
5618 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
5619 break;
5620 }
5621 }
5622 }
5623 } else if (strstr(line, "beacon interval") != NULL) {
5624 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
5625 } else if (strstr(line, "signal") != NULL) {
5626 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
5627 } else if (strstr(line,"SSID") != NULL) {
5628 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
5629 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
5630 filter_BSS = true;
5631 }
5632 } else if (strstr(line, "Supported rates") != NULL) {
5633 char SRate[80] = {0}, *tmp = NULL;
5634 memset(buf, 0, sizeof(buf));
5635 strcpy(SRate, line);
5636 tmp = strtok(SRate, ":");
5637 tmp = strtok(NULL, ":");
5638 strcpy(buf, tmp);
5639 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +08005640
developera3511852023-06-14 14:12:59 +08005641 tmp = strtok(buf, " \n");
5642 while (tmp != NULL) {
5643 strcat(SRate, tmp);
5644 if (SRate[strlen(SRate) - 1] == '*') {
5645 SRate[strlen(SRate) - 1] = '\0';
5646 }
5647 strcat(SRate, ",");
developer72fb0bb2023-01-11 09:46:29 +08005648
developera3511852023-06-14 14:12:59 +08005649 tmp = strtok(NULL, " \n");
5650 }
5651 SRate[strlen(SRate) - 1] = '\0';
5652 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
5653 } else if (strstr(line, "DTIM") != NULL) {
5654 sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod));
5655 } else if (strstr(line, "VHT capabilities") != NULL) {
5656 strcat(scan_array[index].ap_SupportedStandards, ",ac");
5657 strcpy(scan_array[index].ap_OperatingStandards, "ac");
5658 } else if (strstr(line, "HT capabilities") != NULL) {
5659 strcat(scan_array[index].ap_SupportedStandards, ",n");
5660 strcpy(scan_array[index].ap_OperatingStandards, "n");
5661 } else if (strstr(line, "VHT operation") != NULL) {
5662 ret = fgets(line, sizeof(line), f);
5663 sscanf(line," * channel width: %d", &vht_channel_width);
5664 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +08005665 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +08005666 } else {
developere40952c2023-06-15 18:46:43 +08005667 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +08005668 }
developere40952c2023-06-15 18:46:43 +08005669 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
5670 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5671 return RETURN_ERR;
5672 }
5673
developera3511852023-06-14 14:12:59 +08005674 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5675 continue;
5676 } else if (strstr(line, "HT operation") != NULL) {
5677 ret = fgets(line, sizeof(line), f);
5678 sscanf(line," * secondary channel offset: %s", buf);
5679 if (!strcmp(buf, "above")) {
5680 //40Mhz +
developere40952c2023-06-15 18:46:43 +08005681 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 +08005682 }
5683 else if (!strcmp(buf, "below")) {
5684 //40Mhz -
developere40952c2023-06-15 18:46:43 +08005685 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 +08005686 } else {
5687 //20Mhz
developere40952c2023-06-15 18:46:43 +08005688 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
5689 }
5690 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
5691 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5692 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08005693 }
developere40952c2023-06-15 18:46:43 +08005694
developera3511852023-06-14 14:12:59 +08005695 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5696 continue;
5697 } else if (strstr(line, "HE capabilities") != NULL) {
5698 strcat(scan_array[index].ap_SupportedStandards, ",ax");
5699 strcpy(scan_array[index].ap_OperatingStandards, "ax");
5700 ret = fgets(line, sizeof(line), f);
5701 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
5702 if (strstr(line, "HE40/2.4GHz") != NULL)
5703 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
5704 else
5705 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
5706 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
5707 if (strstr(line, "HE80/5GHz") != NULL) {
5708 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
5709 ret = fgets(line, sizeof(line), f);
5710 } else
5711 continue;
5712 if (strstr(line, "HE160/5GHz") != NULL)
5713 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
5714 }
5715 continue;
5716 } else if (strstr(line, "WPA") != NULL) {
5717 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
5718 } else if (strstr(line, "RSN") != NULL) {
5719 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
5720 } else if (strstr(line, "Group cipher") != NULL) {
5721 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
5722 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
5723 strcpy(scan_array[index].ap_EncryptionMode, "AES");
5724 }
5725 }
5726 ret = fgets(line, sizeof(line), f);
5727 }
developer72fb0bb2023-01-11 09:46:29 +08005728
developera3511852023-06-14 14:12:59 +08005729 if (!filter_BSS) {
5730 *output_array_size = index + 1;
5731 } else {
5732 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5733 *output_array_size = index;
5734 }
5735 *neighbor_ap_array = scan_array;
5736 pclose(f);
5737 free(channels_noise_arr);
5738 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5739 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005740}
5741
5742//>> Deprecated: used for old RDKB code.
5743INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
5744{
developera3511852023-06-14 14:12:59 +08005745 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005746
developera3511852023-06-14 14:12:59 +08005747 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5748 output_struct->wifi_PLCPErrorCount = 0;
5749 output_struct->wifi_FCSErrorCount = 0;
5750 output_struct->wifi_InvalidMACCount = 0;
5751 output_struct->wifi_PacketsOtherReceived = 0;
5752 output_struct->wifi_Noise = 0;
5753 status = RETURN_OK;
5754 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5755 return status;
developer72fb0bb2023-01-11 09:46:29 +08005756}
5757
5758INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
5759{
developera3511852023-06-14 14:12:59 +08005760 char interface_name[16] = {0};
5761 char cmd[128] = {0};
5762 char buf[1280] = {0};
5763 char *pos = NULL;
developere40952c2023-06-15 18:46:43 +08005764 int res;
developer72fb0bb2023-01-11 09:46:29 +08005765
developera3511852023-06-14 14:12:59 +08005766 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5767 if (NULL == output_struct)
5768 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005769
developera3511852023-06-14 14:12:59 +08005770 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5771 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005772
developera3511852023-06-14 14:12:59 +08005773 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08005774
developere40952c2023-06-15 18:46:43 +08005775 res = snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
5776 if (os_snprintf_error(sizeof(cmd), res)) {
5777 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5778 return RETURN_ERR;
5779 }
5780
developera3511852023-06-14 14:12:59 +08005781 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08005782
developera3511852023-06-14 14:12:59 +08005783 pos = buf;
5784 if ((pos = strstr(pos, "RX packets:")) == NULL)
5785 return RETURN_ERR;
5786 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08005787
developera3511852023-06-14 14:12:59 +08005788 if ((pos = strstr(pos, "TX packets:")) == NULL)
5789 return RETURN_ERR;
5790 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
developer72fb0bb2023-01-11 09:46:29 +08005791
developera3511852023-06-14 14:12:59 +08005792 if ((pos = strstr(pos, "RX bytes:")) == NULL)
5793 return RETURN_ERR;
5794 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08005795
developera3511852023-06-14 14:12:59 +08005796 if ((pos = strstr(pos, "TX bytes:")) == NULL)
5797 return RETURN_ERR;
5798 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
developer72fb0bb2023-01-11 09:46:29 +08005799
developera3511852023-06-14 14:12:59 +08005800 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
5801 _syscmd(cmd, buf, sizeof(buf));
5802 sscanf(buf, "%lu", &output_struct->wifi_Associations);
developer72fb0bb2023-01-11 09:46:29 +08005803
developera3511852023-06-14 14:12:59 +08005804 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5805 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005806}
5807
5808INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
5809{
developera3511852023-06-14 14:12:59 +08005810 char interface_name[IF_NAME_SIZE] = {0};
5811 char interface_status[MAX_BUF_SIZE] = {0};
5812 char Value[MAX_BUF_SIZE] = {0};
5813 char buf[MAX_CMD_SIZE] = {0};
5814 char cmd[MAX_CMD_SIZE] = {0};
5815 FILE *fp = NULL;
developere40952c2023-06-15 18:46:43 +08005816 int res;
developer72fb0bb2023-01-11 09:46:29 +08005817
developera3511852023-06-14 14:12:59 +08005818 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5819 if (NULL == output_struct)
5820 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005821
developera3511852023-06-14 14:12:59 +08005822 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
developer72fb0bb2023-01-11 09:46:29 +08005823
developera3511852023-06-14 14:12:59 +08005824 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
5825 return RETURN_ERR;
5826 GetIfacestatus(interface_name, interface_status);
developer72fb0bb2023-01-11 09:46:29 +08005827
developera3511852023-06-14 14:12:59 +08005828 if(0 != strcmp(interface_status, "1"))
5829 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08005830
5831 res = snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5832 if (os_snprintf_error(sizeof(cmd), res)) {
5833 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
5834 return RETURN_ERR;
5835 }
developer72fb0bb2023-01-11 09:46:29 +08005836
developera3511852023-06-14 14:12:59 +08005837 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +08005838
developera3511852023-06-14 14:12:59 +08005839 fp = fopen("/tmp/SSID_Stats.txt", "r");
5840 if(fp == NULL)
5841 {
5842 printf("/tmp/SSID_Stats.txt not exists \n");
5843 return RETURN_ERR;
5844 }
5845 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +08005846
developera3511852023-06-14 14:12:59 +08005847 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5848 File_Reading(buf, Value);
5849 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005850
developera3511852023-06-14 14:12:59 +08005851 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5852 File_Reading(buf, Value);
5853 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005854
developera3511852023-06-14 14:12:59 +08005855 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5856 File_Reading(buf, Value);
5857 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005858
developera3511852023-06-14 14:12:59 +08005859 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5860 File_Reading(buf, Value);
5861 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08005862
developera3511852023-06-14 14:12:59 +08005863 output_struct->wifi_UnicastPacketsSent = 0;
5864 output_struct->wifi_UnicastPacketsReceived = 0;
5865 output_struct->wifi_MulticastPacketsSent = 0;
5866 output_struct->wifi_MulticastPacketsReceived = 0;
5867 output_struct->wifi_BroadcastPacketsSent = 0;
5868 output_struct->wifi_BroadcastPacketsRecevied = 0;
5869 output_struct->wifi_UnknownPacketsReceived = 0;
developer72fb0bb2023-01-11 09:46:29 +08005870
developera3511852023-06-14 14:12:59 +08005871 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5872 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005873}
5874
5875INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
5876{
developera3511852023-06-14 14:12:59 +08005877 INT status = RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005878
developera3511852023-06-14 14:12:59 +08005879 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5880 //Below values should get updated from hal
5881 output_struct->wifi_RetransCount=0;
5882 output_struct->wifi_FailedRetransCount=0;
5883 output_struct->wifi_RetryCount=0;
5884 output_struct->wifi_MultipleRetryCount=0;
5885 output_struct->wifi_ACKFailureCount=0;
5886 output_struct->wifi_AggregatedPacketCount=0;
developer72fb0bb2023-01-11 09:46:29 +08005887
developera3511852023-06-14 14:12:59 +08005888 status = RETURN_OK;
5889 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005890
developera3511852023-06-14 14:12:59 +08005891 return status;
developer72fb0bb2023-01-11 09:46:29 +08005892}
5893
5894INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
5895{
developera3511852023-06-14 14:12:59 +08005896 INT status = RETURN_ERR;
5897 UINT index;
5898 wifi_neighbor_ap_t *pt=NULL;
developer72fb0bb2023-01-11 09:46:29 +08005899
developera3511852023-06-14 14:12:59 +08005900 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5901 *output_array_size=2;
5902 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
5903 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
5904 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
5905 strcpy(pt->ap_Radio,"");
5906 strcpy(pt->ap_SSID,"");
5907 strcpy(pt->ap_BSSID,"");
5908 strcpy(pt->ap_Mode,"");
5909 pt->ap_Channel=1;
5910 pt->ap_SignalStrength=0;
5911 strcpy(pt->ap_SecurityModeEnabled,"");
5912 strcpy(pt->ap_EncryptionMode,"");
5913 strcpy(pt->ap_OperatingFrequencyBand,"");
5914 strcpy(pt->ap_SupportedStandards,"");
5915 strcpy(pt->ap_OperatingStandards,"");
5916 strcpy(pt->ap_OperatingChannelBandwidth,"");
5917 pt->ap_BeaconPeriod=1;
5918 pt->ap_Noise=0;
5919 strcpy(pt->ap_BasicDataTransferRates,"");
5920 strcpy(pt->ap_SupportedDataTransferRates,"");
5921 pt->ap_DTIMPeriod=1;
5922 pt->ap_ChannelUtilization = 1;
5923 }
developer72fb0bb2023-01-11 09:46:29 +08005924
developera3511852023-06-14 14:12:59 +08005925 status = RETURN_OK;
5926 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08005927
developera3511852023-06-14 14:12:59 +08005928 return status;
developer72fb0bb2023-01-11 09:46:29 +08005929}
5930
5931//----------------- AP HAL -------------------------------
5932
5933//>> Deprecated: used for old RDKB code.
5934INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
5935{
developera3511852023-06-14 14:12:59 +08005936 if (NULL == output_ulong || NULL == output_struct)
5937 return RETURN_ERR;
5938 *output_ulong = 0;
5939 *output_struct = NULL;
5940 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005941}
5942
5943#ifdef HAL_NETLINK_IMPL
5944static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +08005945 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5946 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5947 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
5948 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
5949 char mac_addr[20];
5950 static int count=0;
5951 int rate=0;
developer72fb0bb2023-01-11 09:46:29 +08005952
developera3511852023-06-14 14:12:59 +08005953 wifi_device_info_t *out = (wifi_device_info_t*)arg;
developer72fb0bb2023-01-11 09:46:29 +08005954
developera3511852023-06-14 14:12:59 +08005955 nla_parse(tb,
5956 NL80211_ATTR_MAX,
5957 genlmsg_attrdata(gnlh, 0),
5958 genlmsg_attrlen(gnlh, 0),
5959 NULL);
developer72fb0bb2023-01-11 09:46:29 +08005960
developera3511852023-06-14 14:12:59 +08005961 if(!tb[NL80211_ATTR_STA_INFO]) {
5962 fprintf(stderr, "sta stats missing!\n");
5963 return NL_SKIP;
5964 }
developer72fb0bb2023-01-11 09:46:29 +08005965
5966
developera3511852023-06-14 14:12:59 +08005967 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
5968 fprintf(stderr, "failed to parse nested attributes!\n");
5969 return NL_SKIP;
5970 }
developer72fb0bb2023-01-11 09:46:29 +08005971
developera3511852023-06-14 14:12:59 +08005972 //devIndex starts from 1
5973 if( ++count == out->wifi_devIndex )
5974 {
5975 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
5976 //Getting the mac addrress
5977 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
developer72fb0bb2023-01-11 09:46:29 +08005978
developera3511852023-06-14 14:12:59 +08005979 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
5980 fprintf(stderr, "failed to parse nested rate attributes!");
5981 return NL_SKIP;
5982 }
developer72fb0bb2023-01-11 09:46:29 +08005983
developera3511852023-06-14 14:12:59 +08005984 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
5985 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
5986 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5987 out->wifi_devTxRate = rate/10;
5988 }
5989 }
developer72fb0bb2023-01-11 09:46:29 +08005990
developera3511852023-06-14 14:12:59 +08005991 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
5992 fprintf(stderr, "failed to parse nested rate attributes!");
5993 return NL_SKIP;
5994 }
developer72fb0bb2023-01-11 09:46:29 +08005995
developera3511852023-06-14 14:12:59 +08005996 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
5997 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
5998 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5999 out->wifi_devRxRate = rate/10;
6000 }
6001 }
6002 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
6003 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
developer72fb0bb2023-01-11 09:46:29 +08006004
developera3511852023-06-14 14:12:59 +08006005 out->wifi_devAssociatedDeviceAuthentiationState = 1;
6006 count = 0; //starts the count for next cycle
6007 return NL_STOP;
6008 }
developer72fb0bb2023-01-11 09:46:29 +08006009
developera3511852023-06-14 14:12:59 +08006010 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08006011
6012}
6013#endif
6014
6015INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
6016{
developera3511852023-06-14 14:12:59 +08006017 Netlink nl = {0};
6018 char if_name[IF_NAME_SIZE] = {0};
6019 char interface_name[16] = {0};
developere40952c2023-06-15 18:46:43 +08006020 int res;
developer72fb0bb2023-01-11 09:46:29 +08006021
developera3511852023-06-14 14:12:59 +08006022 wifi_device_info_t info = {0};
6023 info.wifi_devIndex = devIndex;
developer72fb0bb2023-01-11 09:46:29 +08006024
developera3511852023-06-14 14:12:59 +08006025 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6026 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006027
developere40952c2023-06-15 18:46:43 +08006028 res = snprintf(if_name,sizeof(if_name),"%s", interface_name);
6029 if (os_snprintf_error(sizeof(if_name), res)) {
6030 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6031 return RETURN_ERR;
6032 }
developer72fb0bb2023-01-11 09:46:29 +08006033
developera3511852023-06-14 14:12:59 +08006034 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +08006035
developera3511852023-06-14 14:12:59 +08006036 if (nl.id < 0) {
6037 fprintf(stderr, "Error initializing netlink \n");
6038 return -1;
6039 }
developer72fb0bb2023-01-11 09:46:29 +08006040
developera3511852023-06-14 14:12:59 +08006041 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +08006042
developera3511852023-06-14 14:12:59 +08006043 if (!msg) {
6044 fprintf(stderr, "Failed to allocate netlink message.\n");
6045 nlfree(&nl);
6046 return -2;
6047 }
developer72fb0bb2023-01-11 09:46:29 +08006048
developera3511852023-06-14 14:12:59 +08006049 genlmsg_put(msg,
6050 NL_AUTO_PID,
6051 NL_AUTO_SEQ,
6052 nl.id,
6053 0,
6054 NLM_F_DUMP,
6055 NL80211_CMD_GET_STATION,
6056 0);
developer72fb0bb2023-01-11 09:46:29 +08006057
developera3511852023-06-14 14:12:59 +08006058 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
6059 nl_send_auto_complete(nl.socket, msg);
6060 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
6061 nl_recvmsgs(nl.socket, nl.cb);
6062 nlmsg_free(msg);
6063 nlfree(&nl);
developer72fb0bb2023-01-11 09:46:29 +08006064
developera3511852023-06-14 14:12:59 +08006065 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
6066 output_struct->wifi_devRxRate = info.wifi_devRxRate;
6067 output_struct->wifi_devTxRate = info.wifi_devTxRate;
6068 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
6069 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
6070 return RETURN_OK;
6071}
developer72fb0bb2023-01-11 09:46:29 +08006072
developera3511852023-06-14 14:12:59 +08006073INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
6074{
6075 if (NULL == device)
6076 return RETURN_ERR;
6077 return RETURN_OK;
6078}
6079//<<
developer72fb0bb2023-01-11 09:46:29 +08006080
developer72fb0bb2023-01-11 09:46:29 +08006081
6082//--------------wifi_ap_hal-----------------------------
6083//enables CTS protection for the radio used by this AP
6084INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
6085{
developera3511852023-06-14 14:12:59 +08006086 //save config and Apply instantly
6087 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006088}
6089
6090// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
6091INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
6092{
developera3511852023-06-14 14:12:59 +08006093 char config_file[64] = {'\0'};
6094 char config_dat_file[64] = {'\0'};
6095 char buf[64] = {'\0'};
6096 struct params list = {0};
6097 struct params dat = {0};
6098 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08006099 int res;
developer72fb0bb2023-01-11 09:46:29 +08006100
developera3511852023-06-14 14:12:59 +08006101 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6102 list.name = "ht_coex";
developere40952c2023-06-15 18:46:43 +08006103 res = snprintf(buf, sizeof(buf), "%d", enable);
6104 if (os_snprintf_error(sizeof(buf), res)) {
6105 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6106 return RETURN_ERR;
6107 }
6108
developera3511852023-06-14 14:12:59 +08006109 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08006110
developera3511852023-06-14 14:12:59 +08006111 dat.name = "HT_BSSCoexistence";
6112 dat.value = buf;
developerd1824452023-05-18 12:30:04 +08006113
developera3511852023-06-14 14:12:59 +08006114 band = wifi_index_to_band(apIndex);
developere40952c2023-06-15 18:46:43 +08006115 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6116 if (os_snprintf_error(sizeof(config_file), res)) {
6117 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6118 return RETURN_ERR;
6119 }
6120
6121 res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6122 if (os_snprintf_error(sizeof(config_dat_file), res)) {
6123 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6124 return RETURN_ERR;
6125 }
6126
developera3511852023-06-14 14:12:59 +08006127 wifi_hostapdWrite(config_file, &list, 1);
6128 wifi_datfileWrite(config_dat_file, &dat, 1);
6129 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08006130
developera3511852023-06-14 14:12:59 +08006131 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006132
developera3511852023-06-14 14:12:59 +08006133 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006134}
6135
6136//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
6137INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
6138{
developera3511852023-06-14 14:12:59 +08006139 char config_file[MAX_BUF_SIZE] = {'\0'};
6140 char buf[MAX_BUF_SIZE] = {'\0'};
6141 struct params list;
developere40952c2023-06-15 18:46:43 +08006142 int res;
developer72fb0bb2023-01-11 09:46:29 +08006143
developera3511852023-06-14 14:12:59 +08006144 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6145 if (threshold < 256 || threshold > 2346 )
6146 return RETURN_ERR;
6147 list.name = "fragm_threshold";
developere40952c2023-06-15 18:46:43 +08006148 res = snprintf(buf, sizeof(buf), "%d", threshold);
6149 if (os_snprintf_error(sizeof(buf), res)) {
6150 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6151 return RETURN_ERR;
6152 }
6153
developera3511852023-06-14 14:12:59 +08006154 list.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08006155
developere40952c2023-06-15 18:46:43 +08006156 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6157 if (os_snprintf_error(sizeof(config_file), res)) {
6158 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6159 return RETURN_ERR;
6160 }
6161
developera3511852023-06-14 14:12:59 +08006162 wifi_hostapdWrite(config_file, &list, 1);
6163 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +08006164
developera3511852023-06-14 14:12:59 +08006165 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006166
developera3511852023-06-14 14:12:59 +08006167 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006168}
6169
6170// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
6171INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
6172{
developera3511852023-06-14 14:12:59 +08006173 char config_file[64] = {'\0'};
6174 char cmd[512] = {'\0'};
6175 char buf[512] = {'\0'};
6176 char stbc_config[16] = {'\0'};
6177 wifi_band band;
6178 int iterator = 0;
6179 BOOL current_stbc = FALSE;
6180 int ant_count = 0;
6181 int ant_bitmap = 0;
6182 struct params list;
6183 char dat_file[64] = {'\0'};
developere40952c2023-06-15 18:46:43 +08006184 int res;
developer72fb0bb2023-01-11 09:46:29 +08006185
developera3511852023-06-14 14:12:59 +08006186 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006187
developera3511852023-06-14 14:12:59 +08006188 band = wifi_index_to_band(radioIndex);
6189 if (band == band_invalid)
6190 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006191
developera3511852023-06-14 14:12:59 +08006192 if (band == band_2_4)
6193 iterator = 1;
6194 else if ((band == band_5) || (band == band_6))
6195 iterator = 2;
6196 else
6197 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006198
developera3511852023-06-14 14:12:59 +08006199 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
6200 for (; ant_bitmap > 0; ant_bitmap >>= 1)
6201 ant_count += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08006202
developera3511852023-06-14 14:12:59 +08006203 if (ant_count == 1 && STBC_Enable == TRUE) {
6204 fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__);
6205 return RETURN_OK;
6206 }
developer72fb0bb2023-01-11 09:46:29 +08006207
developere40952c2023-06-15 18:46:43 +08006208 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6209 if (os_snprintf_error(sizeof(config_file), res)) {
6210 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6211 return RETURN_ERR;
6212 }
developer72fb0bb2023-01-11 09:46:29 +08006213
developera3511852023-06-14 14:12:59 +08006214 // set ht and vht config
6215 for (int i = 0; i < iterator; i++) {
6216 memset(stbc_config, 0, sizeof(stbc_config));
6217 memset(cmd, 0, sizeof(cmd));
6218 memset(buf, 0, sizeof(buf));
6219 list.name = (i == 0)?"ht_capab":"vht_capab";
developere40952c2023-06-15 18:46:43 +08006220 res = snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
6221 if (os_snprintf_error(sizeof(stbc_config), res)) {
6222 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6223 return RETURN_ERR;
6224 }
6225
6226 res = snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
6227 if (os_snprintf_error(sizeof(cmd), res)) {
6228 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6229 return RETURN_ERR;
6230 }
6231
developera3511852023-06-14 14:12:59 +08006232 _syscmd(cmd, buf, sizeof(buf));
6233 if (strlen(buf) != 0)
6234 current_stbc = TRUE;
6235 if (current_stbc == STBC_Enable)
6236 continue;
developer72fb0bb2023-01-11 09:46:29 +08006237
developera3511852023-06-14 14:12:59 +08006238 if (STBC_Enable == TRUE) {
6239 // Append the STBC flags in capab config
6240 memset(cmd, 0, sizeof(cmd));
6241 if (i == 0)
developere40952c2023-06-15 18:46:43 +08006242 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
developera3511852023-06-14 14:12:59 +08006243 else
developere40952c2023-06-15 18:46:43 +08006244 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
6245 if (os_snprintf_error(sizeof(cmd), res)) {
6246 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6247 return RETURN_ERR;
6248 }
6249
developera3511852023-06-14 14:12:59 +08006250 _syscmd(cmd, buf, sizeof(buf));
6251 } else if (STBC_Enable == FALSE) {
6252 // Remove the STBC flags and remain other flags in capab
6253 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08006254 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6255 if (os_snprintf_error(sizeof(cmd), res)) {
6256 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6257 return RETURN_ERR;
6258 }
6259
developera3511852023-06-14 14:12:59 +08006260 _syscmd(cmd, buf, sizeof(buf));
6261 memset(cmd, 0, sizeof(cmd));
developere40952c2023-06-15 18:46:43 +08006262 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
6263 if (os_snprintf_error(sizeof(cmd), res)) {
6264 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6265 return RETURN_ERR;
6266 }
6267
developera3511852023-06-14 14:12:59 +08006268 _syscmd(cmd, buf, sizeof(buf));
6269 }
6270 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
6271 list.value = buf;
6272 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
6273 }
developere40952c2023-06-15 18:46:43 +08006274 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6275 if (os_snprintf_error(sizeof(dat_file), res)) {
6276 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6277 return RETURN_ERR;
6278 }
6279
6280 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
6281 if (os_snprintf_error(sizeof(cmd), res)) {
6282 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6283 return RETURN_ERR;
6284 }
6285
developera1255e42023-05-13 17:45:02 +08006286 _syscmd(cmd, buf, sizeof(buf));
6287 if ((band == band_5) || (band == band_6)) {
developere40952c2023-06-15 18:46:43 +08006288 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
6289 if (os_snprintf_error(sizeof(cmd), res)) {
6290 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6291 return RETURN_ERR;
6292 }
6293
developera1255e42023-05-13 17:45:02 +08006294 _syscmd(cmd, buf, sizeof(buf));
6295 }
developera3511852023-06-14 14:12:59 +08006296 /*wifi_reloadAp(radioIndex);
developera1255e42023-05-13 17:45:02 +08006297 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08006298
developera3511852023-06-14 14:12:59 +08006299 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6300 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006301}
6302
6303// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
6304INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
6305{
developera3511852023-06-14 14:12:59 +08006306 char dat_file[128] = {0};
developer2c22d832023-05-18 17:46:26 +08006307 wifi_band band;
6308 char amdus_buff[8] = {'\0'};
developere40952c2023-06-15 18:46:43 +08006309 int res;
developer72fb0bb2023-01-11 09:46:29 +08006310
developer2c22d832023-05-18 17:46:26 +08006311 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006312
developer2c22d832023-05-18 17:46:26 +08006313 band = wifi_index_to_band(radioIndex);
6314 if (band == band_invalid) {
6315 printf("%s:Band Error\n", __func__);
6316 return RETURN_ERR;
6317 }
developere40952c2023-06-15 18:46:43 +08006318 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6319 if (os_snprintf_error(sizeof(dat_file), res)) {
6320 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6321 return RETURN_ERR;
6322 }
6323
developer2c22d832023-05-18 17:46:26 +08006324 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6325 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08006326 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08006327 else
6328 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006329
developer2c22d832023-05-18 17:46:26 +08006330 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6331
6332 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006333}
6334
6335// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
6336INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
6337{
developer2c22d832023-05-18 17:46:26 +08006338 char dat_file[128] = {0};
6339 BOOL enable;
6340 wifi_band band;
6341 char amdus_buff[8] = {'\0'};
6342 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08006343 int res;
developer72fb0bb2023-01-11 09:46:29 +08006344
developer2c22d832023-05-18 17:46:26 +08006345 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006346
developer2c22d832023-05-18 17:46:26 +08006347 band = wifi_index_to_band(radioIndex);
6348 if (band == band_invalid) {
6349 printf("%s:Band Error\n", __func__);
6350 return RETURN_ERR;
6351 }
developere40952c2023-06-15 18:46:43 +08006352 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6353 if (os_snprintf_error(sizeof(dat_file), res)) {
6354 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6355 return RETURN_ERR;
6356 }
6357
developer2c22d832023-05-18 17:46:26 +08006358 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6359 if (strncmp(amdus_buff, "1", 1) == 0)
developera3511852023-06-14 14:12:59 +08006360 enable = TRUE;
developer2c22d832023-05-18 17:46:26 +08006361 else
6362 enable = FALSE;
6363 if (amsduEnable == enable)
developera3511852023-06-14 14:12:59 +08006364 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006365
developer2c22d832023-05-18 17:46:26 +08006366 params.name = "HT_AMSDU";
6367 if (amsduEnable)
6368 params.value = "1";
6369 else
6370 params.value = "0";
6371 wifi_datfileWrite(dat_file, &params, 1);
6372 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006373
developer2c22d832023-05-18 17:46:26 +08006374 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006375
developera3511852023-06-14 14:12:59 +08006376 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006377}
6378
6379//P2 // outputs the number of Tx streams
6380INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
6381{
developera3511852023-06-14 14:12:59 +08006382 char buf[8] = {0};
6383 char cmd[128] = {0};
6384 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08006385 int res;
developer72fb0bb2023-01-11 09:46:29 +08006386
developera3511852023-06-14 14:12:59 +08006387 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006388
developera3511852023-06-14 14:12:59 +08006389 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08006390 res = snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
6391 if (os_snprintf_error(sizeof(cmd), res)) {
6392 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6393 return RETURN_ERR;
6394 }
6395
developera3511852023-06-14 14:12:59 +08006396 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006397
developera3511852023-06-14 14:12:59 +08006398 *output_int = (INT)strtol(buf, NULL, 16);
developer72fb0bb2023-01-11 09:46:29 +08006399
developera3511852023-06-14 14:12:59 +08006400 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006401
developera3511852023-06-14 14:12:59 +08006402 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006403}
6404
6405INT fitChainMask(INT radioIndex, int antcount)
6406{
developera3511852023-06-14 14:12:59 +08006407 char buf[128] = {0};
6408 char cmd[128] = {0};
6409 char config_file[64] = {0};
6410 wifi_band band;
6411 struct params list[2] = {0};
developere40952c2023-06-15 18:46:43 +08006412 int res;
developer72fb0bb2023-01-11 09:46:29 +08006413
developera3511852023-06-14 14:12:59 +08006414 band = wifi_index_to_band(radioIndex);
6415 if (band == band_invalid)
6416 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006417
developera3511852023-06-14 14:12:59 +08006418 list[0].name = "he_mu_beamformer";
6419 list[1].name = "he_su_beamformer";
developer72fb0bb2023-01-11 09:46:29 +08006420
developere40952c2023-06-15 18:46:43 +08006421 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6422 if (os_snprintf_error(sizeof(config_file), res)) {
6423 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6424 return RETURN_ERR;
6425 }
6426
developera3511852023-06-14 14:12:59 +08006427 if (antcount == 1) {
6428 // remove config about multiple antennas
developere40952c2023-06-15 18:46:43 +08006429 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6430 if (os_snprintf_error(sizeof(cmd), res)) {
6431 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6432 return RETURN_ERR;
6433 }
6434
developera3511852023-06-14 14:12:59 +08006435 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006436
developere40952c2023-06-15 18:46:43 +08006437 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
6438 if (os_snprintf_error(sizeof(cmd), res)) {
6439 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6440 return RETURN_ERR;
6441 }
6442
developera3511852023-06-14 14:12:59 +08006443 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006444
developere40952c2023-06-15 18:46:43 +08006445 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
6446 if (os_snprintf_error(sizeof(cmd), res)) {
6447 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6448 return RETURN_ERR;
6449 }
6450
developera3511852023-06-14 14:12:59 +08006451 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006452
developere40952c2023-06-15 18:46:43 +08006453 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
6454 if (os_snprintf_error(sizeof(cmd), res)) {
6455 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6456 return RETURN_ERR;
6457 }
6458
developera3511852023-06-14 14:12:59 +08006459 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006460
developera3511852023-06-14 14:12:59 +08006461 list[0].value = "0";
6462 list[1].value = "0";
6463 } else {
6464 // 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.
6465 if (band == band_2_4 || band == band_5) {
developere40952c2023-06-15 18:46:43 +08006466 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6467 if (os_snprintf_error(sizeof(cmd), res)) {
6468 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6469 return RETURN_ERR;
6470 }
6471
developera3511852023-06-14 14:12:59 +08006472 _syscmd(cmd, buf, sizeof(buf));
6473 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08006474 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
6475 if (os_snprintf_error(sizeof(cmd), res)) {
6476 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6477 return RETURN_ERR;
6478 }
6479
developera3511852023-06-14 14:12:59 +08006480 _syscmd(cmd, buf, sizeof(buf));
6481 }
6482 }
6483 if (band == band_5) {
developere40952c2023-06-15 18:46:43 +08006484 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6485 if (os_snprintf_error(sizeof(cmd), res)) {
6486 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6487 return RETURN_ERR;
6488 }
6489
developera3511852023-06-14 14:12:59 +08006490 _syscmd(cmd, buf, sizeof(buf));
6491 if (strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +08006492 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
6493 if (os_snprintf_error(sizeof(cmd), res)) {
6494 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6495 return RETURN_ERR;
6496 }
6497
developera3511852023-06-14 14:12:59 +08006498 _syscmd(cmd, buf, sizeof(buf));
6499 }
6500 }
developer72fb0bb2023-01-11 09:46:29 +08006501
developere40952c2023-06-15 18:46:43 +08006502 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
6503 if (os_snprintf_error(sizeof(cmd), res)) {
6504 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6505 return RETURN_ERR;
6506 }
6507
developera3511852023-06-14 14:12:59 +08006508 _syscmd(cmd, buf, sizeof(buf));
6509 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08006510 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
6511 if (os_snprintf_error(sizeof(cmd), res)) {
6512 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6513 return RETURN_ERR;
6514 }
6515
developera3511852023-06-14 14:12:59 +08006516 _syscmd(cmd, buf, sizeof(buf));
6517 }
developer72fb0bb2023-01-11 09:46:29 +08006518
developere40952c2023-06-15 18:46:43 +08006519 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
developera3511852023-06-14 14:12:59 +08006520 _syscmd(cmd, buf, sizeof(buf));
6521 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08006522 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
6523 if (os_snprintf_error(sizeof(cmd), res)) {
6524 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6525 return RETURN_ERR;
6526 }
6527
developera3511852023-06-14 14:12:59 +08006528 _syscmd(cmd, buf, sizeof(buf));
6529 }
developer72fb0bb2023-01-11 09:46:29 +08006530
developere40952c2023-06-15 18:46:43 +08006531 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
6532 if (os_snprintf_error(sizeof(cmd), res)) {
6533 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6534 return RETURN_ERR;
6535 }
6536
developera3511852023-06-14 14:12:59 +08006537 _syscmd(cmd, buf, sizeof(buf));
6538 if (strlen(buf) == 0) {
developere40952c2023-06-15 18:46:43 +08006539 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
developera3511852023-06-14 14:12:59 +08006540 } else {
developere40952c2023-06-15 18:46:43 +08006541 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
6542 }
6543 if (os_snprintf_error(sizeof(cmd), res)) {
6544 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6545 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08006546 }
developere40952c2023-06-15 18:46:43 +08006547
developera3511852023-06-14 14:12:59 +08006548 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006549
developera3511852023-06-14 14:12:59 +08006550 list[0].value = "1";
6551 list[1].value = "1";
6552 }
6553 wifi_hostapdWrite(config_file, list, 2);
developerdaf24792023-06-06 11:40:04 +08006554 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006555}
6556
6557//P2 // sets the number of Tx streams to an enviornment variable
6558INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
6559{
developera3511852023-06-14 14:12:59 +08006560 char cmd[128] = {0};
6561 char buf[128] = {0};
6562 int phyId = 0;
6563 int cur_mask = 0;
6564 int antcountmsk = 0;
developera1255e42023-05-13 17:45:02 +08006565 INT cur_nss = 0;
developer863a4a62023-06-06 16:55:59 +08006566 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +08006567 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +08006568 int res;
developer72fb0bb2023-01-11 09:46:29 +08006569
developera3511852023-06-14 14:12:59 +08006570 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006571
developera3511852023-06-14 14:12:59 +08006572 if (numStreams <= 0) {
6573 fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams);
6574 return RETURN_ERR;
6575 }
developer72fb0bb2023-01-11 09:46:29 +08006576
developera3511852023-06-14 14:12:59 +08006577 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
developera1255e42023-05-13 17:45:02 +08006578 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
6579 cur_nss += 1;
6580 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
developera3511852023-06-14 14:12:59 +08006581 if (cur_nss == numStreams)
6582 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006583
developera3511852023-06-14 14:12:59 +08006584 wifi_setRadioEnable(radioIndex, FALSE);
developer72fb0bb2023-01-11 09:46:29 +08006585
developera3511852023-06-14 14:12:59 +08006586 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08006587 //iw need mask value.
6588 for (;numStreams > 0; numStreams--)
6589 antcountmsk |= 0x1 << (numStreams - 1);
developere40952c2023-06-15 18:46:43 +08006590 res = snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
6591 if (os_snprintf_error(sizeof(cmd), res)) {
6592 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6593 return RETURN_ERR;
6594 }
6595
developera3511852023-06-14 14:12:59 +08006596 _syscmd(cmd, buf, sizeof(buf));
6597 if (strlen(buf) > 0) {
6598 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6599 return RETURN_ERR;
6600 }
6601 band = wifi_index_to_band(radioIndex);
developera1255e42023-05-13 17:45:02 +08006602 if (band == band_invalid) {
6603 printf("%s:Band Error\n", __func__);
6604 return RETURN_ERR;
6605 }
developere40952c2023-06-15 18:46:43 +08006606 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6607 if (os_snprintf_error(sizeof(dat_file), res)) {
6608 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6609 return RETURN_ERR;
6610 }
6611
6612 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
6613 if (os_snprintf_error(sizeof(cmd), res)) {
6614 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6615 return RETURN_ERR;
6616 }
6617
developera1255e42023-05-13 17:45:02 +08006618 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08006619 if (strlen(buf) > 0) {
6620 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6621 return RETURN_ERR;
6622 }
developere40952c2023-06-15 18:46:43 +08006623 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
6624 if (os_snprintf_error(sizeof(cmd), res)) {
6625 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6626 return RETURN_ERR;
6627 }
6628
developera1255e42023-05-13 17:45:02 +08006629 _syscmd(cmd, buf, sizeof(buf));
developera3511852023-06-14 14:12:59 +08006630 if (strlen(buf) > 0) {
6631 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6632 return RETURN_ERR;
6633 }
6634 fitChainMask(radioIndex, numStreams);
6635 wifi_setRadioEnable(radioIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +08006636
developera3511852023-06-14 14:12:59 +08006637 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6638 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006639}
6640
6641//P2 // outputs the number of Rx streams
6642INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
6643{
developera3511852023-06-14 14:12:59 +08006644 char buf[8] = {0};
6645 char cmd[128] = {0};
6646 int phyId = 0;
developer72fb0bb2023-01-11 09:46:29 +08006647
developera3511852023-06-14 14:12:59 +08006648 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006649
developera3511852023-06-14 14:12:59 +08006650 phyId = radio_index_to_phy(radioIndex);
6651 sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
6652 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006653
developera3511852023-06-14 14:12:59 +08006654 *output_int = (INT)strtol(buf, NULL, 16);
developer72fb0bb2023-01-11 09:46:29 +08006655
developera3511852023-06-14 14:12:59 +08006656 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006657
developera3511852023-06-14 14:12:59 +08006658 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006659}
6660
6661//P2 // sets the number of Rx streams to an enviornment variable
6662INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
6663{
developera3511852023-06-14 14:12:59 +08006664 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6665 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
6666 fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__);
6667 return RETURN_ERR;
6668 }
6669 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6670 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006671}
6672
6673//Get radio RDG enable setting
6674INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
6675{
developer47cc27a2023-05-17 23:09:58 +08006676 if (NULL == output_bool)
6677 return RETURN_ERR;
6678
6679 *output_bool = TRUE;
6680 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006681}
6682
6683//Get radio RDG enable setting
6684INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
6685{
developer47cc27a2023-05-17 23:09:58 +08006686 char rdg_status[2] = {0};
6687 char dat_file[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08006688 int res;
developer47cc27a2023-05-17 23:09:58 +08006689
6690 if (NULL == output_bool)
6691 return RETURN_ERR;
6692
6693 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08006694 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6695 if (os_snprintf_error(sizeof(dat_file), res)) {
6696 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6697 return RETURN_ERR;
6698 }
developer47cc27a2023-05-17 23:09:58 +08006699
6700 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
6701 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
6702 *output_bool = TRUE;
6703 else
6704 *output_bool = FALSE;
6705
6706 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006707}
6708
6709//Set radio RDG enable setting
6710INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
6711{
developer47cc27a2023-05-17 23:09:58 +08006712 char dat_file[MAX_CMD_SIZE] = {0};
6713 struct params params = {0};
developere40952c2023-06-15 18:46:43 +08006714 int res;
developer47cc27a2023-05-17 23:09:58 +08006715
6716 /*prepare dat file path*/
developere40952c2023-06-15 18:46:43 +08006717 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6718 if (os_snprintf_error(sizeof(dat_file), res)) {
6719 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
6720 return RETURN_ERR;
6721 }
developer47cc27a2023-05-17 23:09:58 +08006722
6723 params.name = "HT_RDG";
6724
developera3511852023-06-14 14:12:59 +08006725 if (enable) {
6726 params.value = "1";
6727 } else {
6728 params.value = "0";
6729 }
developer47cc27a2023-05-17 23:09:58 +08006730
6731 wifi_datfileWrite(dat_file, &params, 1);
6732
6733 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006734}
6735
developer5cd4c862023-05-26 09:34:42 +08006736
6737int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006738{
developer5cd4c862023-05-26 09:34:42 +08006739 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6740 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6741 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6742 unsigned char status;
6743 unsigned char *out_status = data;
6744 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08006745
developer5cd4c862023-05-26 09:34:42 +08006746 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6747 genlmsg_attrlen(gnlh, 0), NULL);
6748 if (err < 0){
6749 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6750 return err;
6751 }
developer8e6583c2023-05-23 13:36:06 +08006752
developer5cd4c862023-05-26 09:34:42 +08006753 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6754 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6755 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6756 if (err < 0){
6757 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6758 return err;
6759 }
developer8e6583c2023-05-23 13:36:06 +08006760
developer5cd4c862023-05-26 09:34:42 +08006761 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
6762 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
6763 if (status == 0) {
6764 wifi_debug(DEBUG_NOTICE, "disabled\n");
6765 } else {
6766 wifi_debug(DEBUG_NOTICE, "enabled\n");
6767 }
6768 *out_status = status;
6769 }
6770 }
developer8e6583c2023-05-23 13:36:06 +08006771
developer5cd4c862023-05-26 09:34:42 +08006772 return 0;
6773}
developer8e6583c2023-05-23 13:36:06 +08006774
developer5cd4c862023-05-26 09:34:42 +08006775int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
6776{
6777 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6778 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6779 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6780 unsigned char status;
6781 unsigned char *out_status = data;
6782 int err = 0;
6783
6784 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6785 genlmsg_attrlen(gnlh, 0), NULL);
6786 if (err < 0) {
6787 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6788 return err;
6789 }
6790
6791 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6792 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6793 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6794 if (err < 0) {
6795 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6796 return err;
6797 }
6798
6799 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
6800 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
6801 if (status == 0) {
6802 wifi_debug(DEBUG_NOTICE, "disabled\n");
6803 } else {
6804 wifi_debug(DEBUG_NOTICE, "enabled\n");
6805 }
6806 *out_status = status;
6807 }
6808 }
6809
6810 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08006811}
6812
developer5cd4c862023-05-26 09:34:42 +08006813INT mtk_wifi_get_ba_decl_auto_status(
6814 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
6815{
6816 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08006817 unsigned int if_idx = 0;
6818 int ret = -1;
6819 struct unl unl_ins;
6820 struct nl_msg *msg = NULL;
6821 struct nlattr * msg_data = NULL;
6822 struct mtk_nl80211_param param;
6823
6824 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6825 return RETURN_ERR;
6826 if_idx = if_nametoindex(inf_name);
6827 if (!if_idx) {
6828 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6829 return RETURN_ERR;
6830 }
6831 /*init mtk nl80211 vendor cmd*/
6832 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
6833 param.if_type = NL80211_ATTR_IFINDEX;
6834 param.if_idx = if_idx;
6835
6836 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6837 if (ret) {
6838 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6839 return RETURN_ERR;
6840 }
6841 /*add mtk vendor cmd data*/
6842 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
6843 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6844 nlmsg_free(msg);
6845 goto err;
6846 }
6847
6848 /*send mtk nl80211 vendor msg*/
6849 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6850 if (ret) {
6851 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6852 goto err;
6853 }
6854 /*deinit mtk nl80211 vendor msg*/
6855 mtk_nl80211_deint(&unl_ins);
6856 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
6857 return RETURN_OK;
6858err:
6859 mtk_nl80211_deint(&unl_ins);
6860 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6861 return RETURN_ERR;
6862}
developere0ff7232023-06-08 16:33:14 +08006863
6864INT mtk_wifi_set_auto_ba_en(
6865 INT apIndex, INT vendor_data_attr, BOOL enable)
6866{
6867 char inf_name[IF_NAME_SIZE] = {0};
6868 unsigned int if_idx = 0;
6869 int ret = -1;
6870 struct unl unl_ins;
6871 struct nl_msg *msg = NULL;
6872 struct nlattr * msg_data = NULL;
6873 struct mtk_nl80211_param param;
6874
6875 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6876 return RETURN_ERR;
6877 if_idx = if_nametoindex(inf_name);
6878 if (!if_idx) {
6879 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6880 return RETURN_ERR;
6881 }
6882 /*init mtk nl80211 vendor cmd*/
6883 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
6884 param.if_type = NL80211_ATTR_IFINDEX;
6885 param.if_idx = if_idx;
6886
6887 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6888 if (ret) {
6889 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6890 return RETURN_ERR;
6891 }
6892 /*add mtk vendor cmd data*/
6893 if (nla_put_u8(msg, vendor_data_attr, enable)) {
6894 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6895 nlmsg_free(msg);
6896 goto err;
6897 }
6898
6899 /*send mtk nl80211 vendor msg*/
6900 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6901 if (ret) {
6902 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6903 goto err;
6904 }
6905 /*deinit mtk nl80211 vendor msg*/
6906 mtk_nl80211_deint(&unl_ins);
6907 return RETURN_OK;
6908err:
6909 mtk_nl80211_deint(&unl_ins);
6910 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6911 return RETURN_ERR;
6912}
6913
developer5cd4c862023-05-26 09:34:42 +08006914//Get radio ADDBA enable setting
6915INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
6916{
6917 if (output_bool == NULL) {
6918 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6919 return RETURN_ERR;
6920 }
6921 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6922 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
6923 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
6924 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
6925 return RETURN_ERR;
6926 }
6927 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6928 return RETURN_OK;
6929}
6930
developer72fb0bb2023-01-11 09:46:29 +08006931//Set radio ADDBA enable setting
6932INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
6933{
developera3511852023-06-14 14:12:59 +08006934 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006935}
6936
6937//Get radio auto block ack enable setting
6938INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
6939{
developer5cd4c862023-05-26 09:34:42 +08006940 if (output_bool == NULL) {
6941 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6942 return RETURN_ERR;
6943 }
developer8e6583c2023-05-23 13:36:06 +08006944
developera3511852023-06-14 14:12:59 +08006945 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
developer5cd4c862023-05-26 09:34:42 +08006946 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
6947 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
6948 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
6949 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
6950 return RETURN_ERR;
6951 }
6952 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6953 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006954}
6955
6956//Set radio auto block ack enable setting
6957INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
6958{
developera3511852023-06-14 14:12:59 +08006959 if (mtk_wifi_set_auto_ba_en
developere0ff7232023-06-08 16:33:14 +08006960 (radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
6961 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
6962 return RETURN_ERR;
6963 }
6964 wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08006965 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006966}
6967
6968//Get radio 11n pure mode enable support
6969INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
6970{
developera3511852023-06-14 14:12:59 +08006971 if (NULL == output_bool)
6972 return RETURN_ERR;
6973 *output_bool = TRUE;
6974 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006975}
6976
6977//Get radio 11n pure mode enable setting
6978INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
6979{
developera3511852023-06-14 14:12:59 +08006980 if (NULL == output_bool)
6981 return RETURN_ERR;
6982 *output_bool = TRUE;
6983 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006984}
6985
6986//Set radio 11n pure mode enable setting
6987INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
6988{
developera3511852023-06-14 14:12:59 +08006989 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006990}
6991
developer5cd4c862023-05-26 09:34:42 +08006992
6993int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006994{
developer5cd4c862023-05-26 09:34:42 +08006995 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6996 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
6997 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6998 unsigned char status = 0, *out_status = data;
6999 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08007000
developer5cd4c862023-05-26 09:34:42 +08007001 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7002 genlmsg_attrlen(gnlh, 0), NULL);
7003 if (err < 0) {
7004 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
7005 return err;
7006 }
developer72fb0bb2023-01-11 09:46:29 +08007007
developer5cd4c862023-05-26 09:34:42 +08007008 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7009 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
7010 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7011 if (err < 0){
7012 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
7013 return err;
7014 }
developer72fb0bb2023-01-11 09:46:29 +08007015
developer5cd4c862023-05-26 09:34:42 +08007016 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
7017 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
7018 if (status == 0) {
7019 wifi_debug(DEBUG_NOTICE, "disabled\n");
7020 } else {
7021 wifi_debug(DEBUG_NOTICE, "enabled\n");
7022 }
7023 *out_status = status;
7024 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
7025 }
7026 }
7027
7028 return 0;
7029}
7030
7031INT mtk_wifi_set_igmp_en_status(
7032 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
7033 unsigned char in_en_stat, BOOL *output_bool)
7034{
7035 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08007036 unsigned int if_idx = 0;
7037 int ret = -1;
7038 struct unl unl_ins;
7039 struct nl_msg *msg = NULL;
7040 struct nlattr * msg_data = NULL;
7041 struct mtk_nl80211_param param;
7042
7043 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7044 return RETURN_ERR;
7045 if_idx = if_nametoindex(inf_name);
7046 if (!if_idx) {
7047 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
7048 return RETURN_ERR;
7049 }
7050 /*init mtk nl80211 vendor cmd*/
7051 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
7052 param.if_type = NL80211_ATTR_IFINDEX;
7053 param.if_idx = if_idx;
7054
7055 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7056 if (ret) {
7057 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7058 return RETURN_ERR;
7059 }
7060 /*add mtk vendor cmd data*/
7061 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
7062 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
7063 nlmsg_free(msg);
7064 goto err;
7065 }
7066
7067 /*send mtk nl80211 vendor msg*/
7068 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
7069 if (ret) {
7070 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7071 goto err;
7072 }
7073 /*deinit mtk nl80211 vendor msg*/
7074 mtk_nl80211_deint(&unl_ins);
7075 if (output_bool) {
7076 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
7077 } else {
7078 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
7079 }
7080 return RETURN_OK;
7081err:
7082 mtk_nl80211_deint(&unl_ins);
7083 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
7084 return RETURN_ERR;
7085}
7086
7087
7088//Get radio IGMP snooping enable setting
7089INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
7090{
7091 if (output_bool == NULL) {
7092 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
7093 return RETURN_ERR;
7094 }
developera3511852023-06-14 14:12:59 +08007095 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08007096 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
7097 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
7098 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
7099 return RETURN_ERR;
7100 }
7101 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developera3511852023-06-14 14:12:59 +08007102 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007103}
7104
7105//Set radio IGMP snooping enable setting
7106INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
7107{
developera3511852023-06-14 14:12:59 +08007108 if (mtk_wifi_set_igmp_en_status
developer5cd4c862023-05-26 09:34:42 +08007109 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
7110 NULL, enable, NULL) != RETURN_OK) {
7111 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
7112 return RETURN_ERR;
7113 }
7114 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developera3511852023-06-14 14:12:59 +08007115 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007116}
7117
7118//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08007119INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08007120{
developera3511852023-06-14 14:12:59 +08007121 if (NULL == output_int)
7122 return RETURN_ERR;
7123 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08007124
developera3511852023-06-14 14:12:59 +08007125 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007126}
7127
7128
7129//---------------------------------------------------------------------------------------------------
7130//
7131// Additional Wifi AP level APIs used for Access Point devices
7132//
7133//---------------------------------------------------------------------------------------------------
7134
7135// creates a new ap and pushes these parameters to the hardware
7136INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
7137{
developera3511852023-06-14 14:12:59 +08007138 // Deprecated when use hal version 3, use wifi_createVap() instead.
7139 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007140}
7141
7142// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
7143INT wifi_deleteAp(INT apIndex)
7144{
developer7e4a2a62023-04-06 19:56:03 +08007145 char interface_name[16] = {0};
7146 char buf[MAX_BUF_SIZE];
7147 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08007148 int res;
developer72fb0bb2023-01-11 09:46:29 +08007149
developer7e4a2a62023-04-06 19:56:03 +08007150 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7151 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08007152
developere40952c2023-06-15 18:46:43 +08007153 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
7154 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
7155 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7156 return RETURN_ERR;
7157 }
developer7e4a2a62023-04-06 19:56:03 +08007158 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007159
developer7e4a2a62023-04-06 19:56:03 +08007160 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007161
developer7e4a2a62023-04-06 19:56:03 +08007162 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007163}
7164
7165// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
7166INT wifi_getApName(INT apIndex, CHAR *output_string)
7167{
developer7e4a2a62023-04-06 19:56:03 +08007168 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08007169 int radio_idx = 0;
7170 int bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08007171 int res;
developer72fb0bb2023-01-11 09:46:29 +08007172
developer7e4a2a62023-04-06 19:56:03 +08007173 if(!output_string)
7174 return RETURN_ERR;
7175
7176 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
7177 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
7178
developere40952c2023-06-15 18:46:43 +08007179 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 +08007180 } else
developere40952c2023-06-15 18:46:43 +08007181 res = snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
7182
7183 if (os_snprintf_error(IF_NAME_SIZE, res)) {
7184 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7185 return RETURN_ERR;
7186 }
developer7e4a2a62023-04-06 19:56:03 +08007187
7188 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007189}
7190
7191// Outputs the index number in that corresponds to the SSID string
7192INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
7193{
developer7e4a2a62023-04-06 19:56:03 +08007194 char cmd [128] = {0};
7195 char buf[32] = {0};
7196 char ap_idx = 0;
7197 char *apIndex_str = NULL;
7198 char radio_idx = 0;
7199 char bss_idx = 0;
developere40952c2023-06-15 18:46:43 +08007200 int res;
developer72fb0bb2023-01-11 09:46:29 +08007201
developere40952c2023-06-15 18:46:43 +08007202 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 +08007203 inputSsidString);
developere40952c2023-06-15 18:46:43 +08007204
7205 if (os_snprintf_error(sizeof(cmd), res)) {
7206 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7207 return RETURN_ERR;
7208 }
7209
developer7e4a2a62023-04-06 19:56:03 +08007210 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007211
developer7e4a2a62023-04-06 19:56:03 +08007212 if (strlen(buf)) {
7213 apIndex_str = strtok(buf, "\n");
7214 *output_int = strtoul(apIndex_str, NULL, 10);
7215 return RETURN_OK;
7216 }
developer72fb0bb2023-01-11 09:46:29 +08007217
developer7e4a2a62023-04-06 19:56:03 +08007218 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
7219 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
7220 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
7221 radio_idx = 2;
7222 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
7223 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
7224 radio_idx = 1;
7225 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
7226 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
7227 radio_idx = 0;
7228 } else {
7229 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
7230 __func__, inputSsidString, ap_idx);
developera3511852023-06-14 14:12:59 +08007231 *output_int = -1;
7232 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007233 }
7234
7235 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
7236
7237 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
7238 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
7239 __func__, inputSsidString, ap_idx);
7240 *output_int = ap_idx;
7241 return RETURN_OK;
7242 }
7243
7244 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007245}
7246
7247INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
7248{
developera3511852023-06-14 14:12:59 +08007249 return wifi_getIndexFromName(inputSsidString, output_int);
developer72fb0bb2023-01-11 09:46:29 +08007250}
7251
7252// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
7253INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
7254{
developera3511852023-06-14 14:12:59 +08007255 char buf[MAX_BUF_SIZE] = {0};
7256 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08007257 int res;
developer72fb0bb2023-01-11 09:46:29 +08007258
developera3511852023-06-14 14:12:59 +08007259 if(NULL == output_string)
7260 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007261
developera3511852023-06-14 14:12:59 +08007262 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7263 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
7264 if((strcmp(buf,"3")==0))
developere40952c2023-06-15 18:46:43 +08007265 res = snprintf(output_string, 32, "WPAand11i");
developera3511852023-06-14 14:12:59 +08007266 else if((strcmp(buf,"2")==0))
developere40952c2023-06-15 18:46:43 +08007267 res = snprintf(output_string, 32, "11i");
developera3511852023-06-14 14:12:59 +08007268 else if((strcmp(buf,"1")==0))
developere40952c2023-06-15 18:46:43 +08007269 res = snprintf(output_string, 32, "WPA");
developera3511852023-06-14 14:12:59 +08007270 else
developere40952c2023-06-15 18:46:43 +08007271 res = snprintf(output_string, 32, "None");
7272 if (os_snprintf_error(32, res)) {
7273 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7274 return RETURN_ERR;
7275 }
developer72fb0bb2023-01-11 09:46:29 +08007276
developera3511852023-06-14 14:12:59 +08007277 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007278}
7279
7280// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
7281INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
7282{
developera3511852023-06-14 14:12:59 +08007283 char config_file[MAX_BUF_SIZE] = {0};
7284 struct params list;
developer72fb0bb2023-01-11 09:46:29 +08007285
developera3511852023-06-14 14:12:59 +08007286 if (NULL == beaconTypeString)
7287 return RETURN_ERR;
7288 list.name = "wpa";
7289 list.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08007290
developera3511852023-06-14 14:12:59 +08007291 if((strcmp(beaconTypeString,"WPAand11i")==0))
7292 list.value="3";
7293 else if((strcmp(beaconTypeString,"11i")==0))
7294 list.value="2";
7295 else if((strcmp(beaconTypeString,"WPA")==0))
7296 list.value="1";
developer72fb0bb2023-01-11 09:46:29 +08007297
developera3511852023-06-14 14:12:59 +08007298 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7299 wifi_hostapdWrite(config_file, &list, 1);
7300 wifi_hostapdProcessUpdate(apIndex, &list, 1);
7301 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
7302 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007303}
7304
7305// sets the beacon interval on the hardware for this AP
7306INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
7307{
developera3511852023-06-14 14:12:59 +08007308 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7309 struct params params={'\0'};
7310 char buf[MAX_BUF_SIZE] = {'\0'};
7311 char config_file[MAX_BUF_SIZE] = {'\0'};
developere40952c2023-06-15 18:46:43 +08007312 int res;
developer72fb0bb2023-01-11 09:46:29 +08007313
developera3511852023-06-14 14:12:59 +08007314 params.name = "beacon_int";
developere40952c2023-06-15 18:46:43 +08007315 res = snprintf(buf, sizeof(buf), "%u", beaconInterval);
7316 if (os_snprintf_error(sizeof(buf), res)) {
7317 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7318 return RETURN_ERR;
7319 }
developera3511852023-06-14 14:12:59 +08007320 params.value = buf;
developer72fb0bb2023-01-11 09:46:29 +08007321
developera3511852023-06-14 14:12:59 +08007322 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7323 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08007324
developera3511852023-06-14 14:12:59 +08007325 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7326 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7327 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007328}
7329
7330INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
7331{
developera3511852023-06-14 14:12:59 +08007332 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
7333 return RETURN_ERR;
7334 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007335}
7336
7337// Get the packet size threshold supported.
7338INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
7339{
developera3511852023-06-14 14:12:59 +08007340 //save config and apply instantly
7341 if (NULL == output_bool)
7342 return RETURN_ERR;
7343 *output_bool = TRUE;
7344 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007345}
7346
7347// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
7348INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
7349{
developera3511852023-06-14 14:12:59 +08007350 char buf[16] = {0};
7351 char config_file[128] = {0};
7352 struct params param = {0};
developere40952c2023-06-15 18:46:43 +08007353 int res;
developer72fb0bb2023-01-11 09:46:29 +08007354
developera3511852023-06-14 14:12:59 +08007355 if (threshold > 65535) {
7356 fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold);
7357 return RETURN_ERR;
7358 }
developer72fb0bb2023-01-11 09:46:29 +08007359
developere40952c2023-06-15 18:46:43 +08007360 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7361 if (os_snprintf_error(sizeof(config_file), res)) {
7362 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7363 return RETURN_ERR;
7364 }
7365
7366 res = snprintf(buf, sizeof(buf), "%u", threshold);
7367 if (os_snprintf_error(sizeof(buf), res)) {
7368 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7369 return RETURN_ERR;
7370 }
developera3511852023-06-14 14:12:59 +08007371 param.name = "rts_threshold";
7372 param.value = buf;
7373 wifi_hostapdWrite(config_file, &param, 1);
7374 wifi_hostapdProcessUpdate(apIndex, &param, 1);
7375 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007376
developera3511852023-06-14 14:12:59 +08007377 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007378}
7379
7380// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7381INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
7382{
developere40952c2023-06-15 18:46:43 +08007383 int res;
7384
developera3511852023-06-14 14:12:59 +08007385 if (NULL == output_string)
7386 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08007387 res = snprintf(output_string, 32, "TKIPandAESEncryption");
7388 if (os_snprintf_error(32, res)) {
7389 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7390 return RETURN_ERR;
7391 }
developera3511852023-06-14 14:12:59 +08007392 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007393
7394}
7395
7396// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7397INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
7398{
developera3511852023-06-14 14:12:59 +08007399 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7400 char *param_name = NULL;
7401 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
developerc79e9172023-06-06 19:48:03 +08007402 unsigned int len;
developere40952c2023-06-15 18:46:43 +08007403 int res;
developer72fb0bb2023-01-11 09:46:29 +08007404
developera3511852023-06-14 14:12:59 +08007405 if(NULL == output_string)
7406 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007407
developera3511852023-06-14 14:12:59 +08007408 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7409 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007410
developera3511852023-06-14 14:12:59 +08007411 if(strcmp(buf,"0")==0)
7412 {
7413 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
developere40952c2023-06-15 18:46:43 +08007414 res = snprintf(output_string, 32, "None");
7415 if (os_snprintf_error(32, res)) {
7416 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7417 return RETURN_ERR;
7418 }
developera3511852023-06-14 14:12:59 +08007419 return RETURN_OK;
7420 }
7421 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
7422 param_name = "rsn_pairwise";
7423 else if((strcmp(buf,"1")==0))
7424 param_name = "wpa_pairwise";
7425 else
7426 return RETURN_ERR;
7427 memset(output_string,'\0',32);
7428 wifi_hostapdRead(config_file,param_name,output_string,32);
7429 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
7430 param_name = "wpa_pairwise";
7431 memset(output_string, '\0', 32);
7432 wifi_hostapdRead(config_file, param_name, output_string, 32);
7433 }
7434 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
developer72fb0bb2023-01-11 09:46:29 +08007435
developera3511852023-06-14 14:12:59 +08007436 if(strcmp(output_string,"TKIP CCMP") == 0) {
developerc79e9172023-06-06 19:48:03 +08007437 len = strlen("TKIPandAESEncryption");
7438 memcpy(output_string,"TKIPandAESEncryption", len);
7439 output_string[len] = '\0';
7440 } else if(strcmp(output_string,"TKIP") == 0) {
7441 len = strlen("TKIPEncryption");
7442 memcpy(output_string,"TKIPEncryption", len);
7443 output_string[len] = '\0';
7444 } else if(strcmp(output_string,"CCMP") == 0) {
7445 len = strlen("AESEncryption");
7446 memcpy(output_string,"AESEncryption", len);
7447 output_string[len] = '\0';
7448 }
developer72fb0bb2023-01-11 09:46:29 +08007449
developera3511852023-06-14 14:12:59 +08007450 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7451 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007452}
7453
7454// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7455INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
7456{
developera3511852023-06-14 14:12:59 +08007457 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7458 struct params params={'\0'};
7459 char output_string[32];
7460 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007461
developera3511852023-06-14 14:12:59 +08007462 memset(output_string,'\0',32);
7463 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08007464
developera3511852023-06-14 14:12:59 +08007465 if(strcmp(encMode, "TKIPEncryption") == 0)
7466 params.value = "TKIP";
7467 else if(strcmp(encMode,"AESEncryption") == 0)
7468 params.value = "CCMP";
7469 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
7470 params.value = "TKIP CCMP";
developer72fb0bb2023-01-11 09:46:29 +08007471
developera3511852023-06-14 14:12:59 +08007472 if((strcmp(output_string,"WPAand11i")==0))
7473 {
7474 params.name = "wpa_pairwise";
7475 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7476 wifi_hostapdWrite(config_file, &params, 1);
7477 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08007478
developera3511852023-06-14 14:12:59 +08007479 params.name = "rsn_pairwise";
7480 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7481 wifi_hostapdWrite(config_file, &params, 1);
7482 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +08007483
developera3511852023-06-14 14:12:59 +08007484 return RETURN_OK;
7485 }
7486 else if((strcmp(output_string,"11i")==0))
7487 {
7488 params.name = "rsn_pairwise";
7489 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7490 wifi_hostapdWrite(config_file, &params, 1);
7491 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7492 return RETURN_OK;
7493 }
7494 else if((strcmp(output_string,"WPA")==0))
7495 {
7496 params.name = "wpa_pairwise";
7497 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7498 wifi_hostapdWrite(config_file, &params, 1);
7499 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7500 return RETURN_OK;
7501 }
developer72fb0bb2023-01-11 09:46:29 +08007502
developera3511852023-06-14 14:12:59 +08007503 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7504 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007505}
7506
7507// deletes internal security varable settings for this ap
7508INT wifi_removeApSecVaribles(INT apIndex)
7509{
developera3511852023-06-14 14:12:59 +08007510 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007511}
7512
7513// changes the hardware settings to disable encryption on this ap
7514INT wifi_disableApEncryption(INT apIndex)
7515{
developera3511852023-06-14 14:12:59 +08007516 //Apply instantly
7517 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007518}
7519
7520// set the authorization mode on this ap
7521// mode mapping as: 1: open, 2: shared, 4:auto
7522INT wifi_setApAuthMode(INT apIndex, INT mode)
7523{
developera3511852023-06-14 14:12:59 +08007524 struct params params={0};
7525 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007526
developera3511852023-06-14 14:12:59 +08007527 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007528
developera3511852023-06-14 14:12:59 +08007529 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
7530 params.name = "auth_algs";
developer72fb0bb2023-01-11 09:46:29 +08007531
developere5750452023-05-15 16:46:42 +08007532 if ((mode & 1 && mode & 2) || mode & 4)
developera3511852023-06-14 14:12:59 +08007533 params.value = "3";
7534 else if (mode & 2)
7535 params.value = "2";
7536 else if (mode & 1)
7537 params.value = "1";
7538 else
7539 params.value = "0";
developer72fb0bb2023-01-11 09:46:29 +08007540
developera3511852023-06-14 14:12:59 +08007541 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7542 wifi_hostapdWrite(config_file, &params, 1);
7543 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08007544 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +08007545 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007546
developera3511852023-06-14 14:12:59 +08007547 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007548}
7549
7550// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7551INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7552{
developera3511852023-06-14 14:12:59 +08007553 //save to wifi config, and wait for wifi restart to apply
7554 struct params params={'\0'};
7555 char config_file[MAX_BUF_SIZE] = {0};
7556 int ret;
developer72fb0bb2023-01-11 09:46:29 +08007557
developera3511852023-06-14 14:12:59 +08007558 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7559 if(authMode == NULL)
7560 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007561
developera3511852023-06-14 14:12:59 +08007562 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
7563 params.name = "wpa_key_mgmt";
developer72fb0bb2023-01-11 09:46:29 +08007564
developera3511852023-06-14 14:12:59 +08007565 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
7566 params.value = "WPA-PSK";
7567 else if(strcmp(authMode,"EAPAuthentication") == 0)
7568 params.value = "WPA-EAP";
7569 else if (strcmp(authMode, "SAEAuthentication") == 0)
7570 params.value = "SAE";
7571 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
7572 params.value = "WPA-EAP-SUITE-B-192";
7573 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
7574 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
7575 else if (strcmp(authMode, "Enhanced_Open") == 0)
7576 params.value = "OWE";
7577 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
7578 return RETURN_OK; //This is taken careof in beaconType
developer72fb0bb2023-01-11 09:46:29 +08007579
developera3511852023-06-14 14:12:59 +08007580 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7581 ret=wifi_hostapdWrite(config_file,&params,1);
7582 if(!ret)
7583 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
7584 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08007585
developera3511852023-06-14 14:12:59 +08007586 return ret;
developer72fb0bb2023-01-11 09:46:29 +08007587}
7588
7589// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7590INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7591{
developera3511852023-06-14 14:12:59 +08007592 //save to wifi config, and wait for wifi restart to apply
7593 char BeaconType[50] = {0};
7594 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007595
developera3511852023-06-14 14:12:59 +08007596 *authMode = 0;
7597 wifi_getApBeaconType(apIndex,BeaconType);
7598 printf("%s____%s \n",__FUNCTION__,BeaconType);
developer72fb0bb2023-01-11 09:46:29 +08007599
developera3511852023-06-14 14:12:59 +08007600 if(strcmp(BeaconType,"None") == 0)
7601 strcpy(authMode,"None");
7602 else
7603 {
7604 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7605 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
7606 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
7607 if(strcmp(authMode,"WPA-PSK") == 0)
7608 strcpy(authMode,"SharedAuthentication");
7609 else if(strcmp(authMode,"WPA-EAP") == 0)
7610 strcpy(authMode,"EAPAuthentication");
7611 }
developer72fb0bb2023-01-11 09:46:29 +08007612
developera3511852023-06-14 14:12:59 +08007613 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007614}
7615
7616// Outputs the number of stations associated per AP
7617INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
7618{
developera3511852023-06-14 14:12:59 +08007619 char interface_name[16] = {0};
7620 char cmd[128]={0};
7621 char buf[128]={0};
7622 BOOL status = false;
developer72fb0bb2023-01-11 09:46:29 +08007623
developera3511852023-06-14 14:12:59 +08007624 if(apIndex > MAX_APS)
7625 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007626
developera3511852023-06-14 14:12:59 +08007627 wifi_getApEnable(apIndex,&status);
7628 if (!status)
7629 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007630
developera3511852023-06-14 14:12:59 +08007631 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
7632 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7633 return RETURN_ERR;
7634 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name);
7635 _syscmd(cmd, buf, sizeof(buf));
7636 sscanf(buf,"%lu", output_ulong);
developer72fb0bb2023-01-11 09:46:29 +08007637
developera3511852023-06-14 14:12:59 +08007638 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007639}
7640
7641// manually removes any active wi-fi association with the device specified on this ap
7642INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
7643{
developera3511852023-06-14 14:12:59 +08007644 char inf_name[16] = {0};
7645 char cmd[MAX_CMD_SIZE] = {0};
7646 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08007647 int res;
developer72fb0bb2023-01-11 09:46:29 +08007648
developera3511852023-06-14 14:12:59 +08007649 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7650 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08007651
7652 res = snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
7653 if (os_snprintf_error(sizeof(cmd), res)) {
7654 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7655 return RETURN_ERR;
7656 }
developer7e4a2a62023-04-06 19:56:03 +08007657
developera3511852023-06-14 14:12:59 +08007658 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007659
developera3511852023-06-14 14:12:59 +08007660 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007661}
7662
7663// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
7664INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
7665{
developer7e4a2a62023-04-06 19:56:03 +08007666 int max_radio_num = 0;
7667
7668 if(NULL == output_int)
7669 return RETURN_ERR;
7670
7671 wifi_getMaxRadioNumber(&max_radio_num);
7672 *output_int = apIndex % max_radio_num;
7673
7674 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007675}
7676
7677// sets the radio index for the specific ap
7678INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
7679{
developera3511852023-06-14 14:12:59 +08007680 //set to config only and wait for wifi reset to apply settings
7681 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007682}
7683
developer121a8e72023-05-22 09:19:39 +08007684
7685#define MAX_ACL_DUMP_LEN 4096
7686int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
7687{
7688 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7689 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
7690 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7691 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08007692 int err = 0;
developer121a8e72023-05-22 09:19:39 +08007693 unsigned short acl_result_len = 0;
7694 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08007695 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08007696 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08007697 return NL_SKIP;
7698 }
developer121a8e72023-05-22 09:19:39 +08007699 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7700 genlmsg_attrlen(gnlh, 0), NULL);
7701 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08007702 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08007703 return NL_SKIP;
7704 }
developer121a8e72023-05-22 09:19:39 +08007705 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7706 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
7707 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7708 if (err < 0)
7709 return NL_SKIP;
7710 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
7711 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7712 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7713 if (acl_result_len > MAX_ACL_DUMP_LEN) {
7714 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
7715 return NL_SKIP;
7716 } else if (*(show_str + acl_result_len - 1) != '\0') {
7717 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
7718 *(show_str + acl_result_len - 1) = '\0';
7719 }
7720 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08007721
7722 if (cb_data->out_len >= acl_result_len) {
7723 memset(cb_data->out_buf, 0, cb_data->out_len);
7724 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
7725 memmove(cb_data->out_buf, show_str, acl_result_len);
7726 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
7727 } else {
7728 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08007729 }
developer121a8e72023-05-22 09:19:39 +08007730 } else
7731 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
7732 } else
7733 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
7734 return NL_OK;
7735}
developer72fb0bb2023-01-11 09:46:29 +08007736// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08007737INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08007738{
developer7e4a2a62023-04-06 19:56:03 +08007739 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08007740 unsigned int if_idx = 0;
7741 int ret = -1;
7742 struct unl unl_ins;
7743 struct nl_msg *msg = NULL;
7744 struct nlattr * msg_data = NULL;
7745 struct mtk_nl80211_param param;
7746 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08007747 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7748 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08007749 if_idx = if_nametoindex(inf_name);
7750 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08007751 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08007752 return RETURN_ERR;
7753 }
7754 /*init mtk nl80211 vendor cmd*/
7755 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7756 param.if_type = NL80211_ATTR_IFINDEX;
7757 param.if_idx = if_idx;
7758
7759 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7760 if (ret) {
7761 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7762 return RETURN_ERR;
7763 }
developer121a8e72023-05-22 09:19:39 +08007764 /*add mtk vendor cmd data*/
7765 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08007766 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08007767 nlmsg_free(msg);
7768 goto err;
7769 }
developer72fb0bb2023-01-11 09:46:29 +08007770
developer121a8e72023-05-22 09:19:39 +08007771 /*send mtk nl80211 vendor msg*/
7772 cb_data.out_buf = macArray;
7773 cb_data.out_len = buf_size;
7774
7775 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
7776 if (ret) {
7777 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7778 goto err;
7779 }
7780 /*deinit mtk nl80211 vendor msg*/
7781 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007782 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developera3511852023-06-14 14:12:59 +08007783 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08007784err:
7785 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007786 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08007787 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007788}
7789
developer2edaf012023-05-24 14:24:53 +08007790INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7791{
7792 char *mac_arry_buf = NULL;
7793
7794 mac_arry_buf = malloc(buf_size);
7795 if (!mac_arry_buf) {
7796 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
7797 return RETURN_ERR;
7798 }
7799 memset(mac_arry_buf, 0, buf_size);
7800 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
7801 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
7802 free(mac_arry_buf);
7803 mac_arry_buf = NULL;
7804 return RETURN_ERR;
7805 }
7806 /*
7807 mtk format to wifi hal format:
7808 "policy=1
7809 00:11:22:33:44:55
7810 00:11:22:33:44:66
7811 "
7812 -->
7813 "00:11:22:33:44:55
7814 00:11:22:33:44:66
7815 "
7816 */
7817 memset(macArray, 0, buf_size);
7818 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
7819 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
7820 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
7821 }
7822 free(mac_arry_buf);
7823 mac_arry_buf = NULL;
7824 return RETURN_OK;
7825}
7826
developer72fb0bb2023-01-11 09:46:29 +08007827INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7828{
developer72fb0bb2023-01-11 09:46:29 +08007829
developer7e4a2a62023-04-06 19:56:03 +08007830 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08007831
developera3511852023-06-14 14:12:59 +08007832 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007833}
7834
7835
7836// Get the list of stations associated per AP
7837INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
7838{
developer7e4a2a62023-04-06 19:56:03 +08007839 char interface_name[IF_NAME_SIZE] = {0};
7840 char cmd[MAX_CMD_SIZE];
developere40952c2023-06-15 18:46:43 +08007841 int res;
developer72fb0bb2023-01-11 09:46:29 +08007842
developer7e4a2a62023-04-06 19:56:03 +08007843 if(apIndex > 3) //Currently supporting apIndex upto 3
developera3511852023-06-14 14:12:59 +08007844 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007845
developer7e4a2a62023-04-06 19:56:03 +08007846 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08007847 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007848
developere40952c2023-06-15 18:46:43 +08007849 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
7850 if (os_snprintf_error(sizeof(cmd), res)) {
7851 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
7852 return RETURN_ERR;
7853 }
developer7e4a2a62023-04-06 19:56:03 +08007854 _syscmd(cmd, macArray, buf_size);
7855 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007856}
7857
developer8dd72532023-05-17 19:58:35 +08007858int hex2num(char c)
7859{
7860 if (c >= '0' && c <= '9')
7861 return c - '0';
7862 if (c >= 'a' && c <= 'f')
7863 return c - 'a' + 10;
7864 if (c >= 'A' && c <= 'F')
7865 return c - 'A' + 10;
7866 return -1;
7867}
7868
7869/**
7870 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
7871 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
7872 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
7873 * Returns: Characters used (> 0) on success, -1 on failure
7874 */
7875int hwaddr_aton2(const char *txt, unsigned char *addr)
7876{
7877 int i;
7878 const char *pos = txt;
7879
7880 for (i = 0; i < 6; i++) {
7881 int a, b;
7882
7883 while (*pos == ':' || *pos == '.' || *pos == '-')
7884 pos++;
7885
7886 a = hex2num(*pos++);
7887 if (a < 0)
7888 return -1;
7889 b = hex2num(*pos++);
7890 if (b < 0)
7891 return -1;
7892 *addr++ = (a << 4) | b;
7893 }
7894
7895 return pos - txt;
7896}
7897
developer72fb0bb2023-01-11 09:46:29 +08007898// adds the mac address to the filter list
7899//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7900INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7901{
developer7e4a2a62023-04-06 19:56:03 +08007902 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08007903 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08007904 struct nl_msg *msg = NULL;
7905 struct nlattr * msg_data = NULL;
7906 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08007907 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
7908 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08007909 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7910 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007911 if (!DeviceMacAddress)
7912 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08007913 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08007914 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08007915 return RETURN_ERR;
7916 }
developer8dd72532023-05-17 19:58:35 +08007917 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08007918 if (!if_idx) {
7919 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7920 return RETURN_ERR;
7921 }
developer49b17232023-05-19 16:35:19 +08007922 /*init mtk nl80211 vendor cmd*/
7923 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7924 param.if_type = NL80211_ATTR_IFINDEX;
7925 param.if_idx = if_idx;
7926 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7927 if (ret) {
7928 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007929 return RETURN_ERR;
7930 }
developer49b17232023-05-19 16:35:19 +08007931 /*add mtk vendor cmd data*/
7932 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08007933 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08007934 nlmsg_free(msg);
7935 goto err;
7936 }
developer49b17232023-05-19 16:35:19 +08007937 /*send mtk nl80211 vendor msg*/
7938 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7939 if (ret) {
7940 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007941 goto err;
7942 }
developer49b17232023-05-19 16:35:19 +08007943 /*deinit mtk nl80211 vendor msg*/
7944 mtk_nl80211_deint(&unl_ins);
7945 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08007946 return RETURN_OK;
7947err:
developer49b17232023-05-19 16:35:19 +08007948 mtk_nl80211_deint(&unl_ins);
7949 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08007950 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007951}
7952
7953// deletes the mac address from the filter list
7954//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7955INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7956{
developer2edaf012023-05-24 14:24:53 +08007957 struct unl unl_ins;
7958 int if_idx = 0, ret = 0;
7959 struct nl_msg *msg = NULL;
7960 struct nlattr * msg_data = NULL;
7961 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08007962 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007963 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007964
developer7e4a2a62023-04-06 19:56:03 +08007965 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7966 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007967
developer7e4a2a62023-04-06 19:56:03 +08007968 if (!DeviceMacAddress)
7969 return RETURN_ERR;
7970
developer2edaf012023-05-24 14:24:53 +08007971 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
7972 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
7973 return RETURN_ERR;
7974 }
developer72fb0bb2023-01-11 09:46:29 +08007975
developer2edaf012023-05-24 14:24:53 +08007976 if_idx = if_nametoindex(inf_name);
7977 if (!if_idx) {
7978 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7979 return RETURN_ERR;
7980 }
7981 /*init mtk nl80211 vendor cmd*/
7982 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7983 param.if_type = NL80211_ATTR_IFINDEX;
7984 param.if_idx = if_idx;
7985 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7986 if (ret) {
7987 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7988 return RETURN_ERR;
7989 }
7990 /*add mtk vendor cmd data*/
7991 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
7992 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7993 nlmsg_free(msg);
7994 goto err;
7995 }
7996 /*send mtk nl80211 vendor msg*/
7997 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7998 if (ret) {
7999 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8000 goto err;
8001 }
8002 /*deinit mtk nl80211 vendor msg*/
8003 mtk_nl80211_deint(&unl_ins);
8004 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
8005 return RETURN_OK;
8006err:
8007 mtk_nl80211_deint(&unl_ins);
8008 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8009 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008010}
8011
8012// outputs the number of devices in the filter list
8013INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
8014{
developer2edaf012023-05-24 14:24:53 +08008015 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
8016 UINT buf_size = 1024;
8017 UINT sta_num = 0;
8018 unsigned char mac[ETH_ALEN] = {0};
developera3511852023-06-14 14:12:59 +08008019 if(output_uint == NULL)
developerdaf24792023-06-06 11:40:04 +08008020 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008021
developer2edaf012023-05-24 14:24:53 +08008022 mac_arry = (char *)malloc(buf_size);
8023 if (mac_arry == NULL) {
8024 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08008025 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08008026 }
developerdaf24792023-06-06 11:40:04 +08008027 memset(mac_arry, 0, buf_size);
developer2edaf012023-05-24 14:24:53 +08008028 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
8029 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
8030 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
8031 return RETURN_ERR;
8032 }
8033 /*count the acl str nums:*/
8034 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08008035
developer2edaf012023-05-24 14:24:53 +08008036 /*mac addr string format:
8037 exp1: 00:11:22:33:44:55\0
8038 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
8039 */
8040 ptr = mac_arry;
8041 while (sscanf(ptr, "%17s", mac_str) == 1) {
8042 if (hwaddr_aton2(mac_str, mac) >= 0)
8043 sta_num++;
8044 ptr = strstr(ptr, mac_str) + strlen(mac_str);
8045 }
8046 *output_uint = sta_num;
8047 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
8048 free(mac_arry);
8049 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08008050 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008051}
8052
8053INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
8054{
developera3511852023-06-14 14:12:59 +08008055 char buf[128]={'\0'};
developer72fb0bb2023-01-11 09:46:29 +08008056
developera3511852023-06-14 14:12:59 +08008057 if(strcmp(action,"DENY")==0)
8058 {
8059 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
8060 system(buf);
8061 return RETURN_OK;
8062 }
developer72fb0bb2023-01-11 09:46:29 +08008063
developera3511852023-06-14 14:12:59 +08008064 if(strcmp(action,"ALLOW")==0)
8065 {
8066 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
8067 system(buf);
8068 return RETURN_OK;
8069 }
developer72fb0bb2023-01-11 09:46:29 +08008070
developera3511852023-06-14 14:12:59 +08008071 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008072
8073}
8074
8075// enable kick for devices on acl black list
8076INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
8077{
developera3511852023-06-14 14:12:59 +08008078 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
8079 char assocArray[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008080
developera3511852023-06-14 14:12:59 +08008081 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
8082 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
developer72fb0bb2023-01-11 09:46:29 +08008083
developera3511852023-06-14 14:12:59 +08008084 /* if there are no devices connected there is nothing to do */
8085 if (strlen(assocArray) < 17)
8086 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008087
developera3511852023-06-14 14:12:59 +08008088 if (enable == TRUE) {
8089 /* kick off the MAC which is in ACL array (deny list) */
8090 acl = strtok(aclArray, "\n");
8091 while (acl != NULL) {
8092 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
8093 wifi_kickApAssociatedDevice(apIndex, acl);
developer72fb0bb2023-01-11 09:46:29 +08008094
developera3511852023-06-14 14:12:59 +08008095 acl = strtok(NULL, "\n");
8096 }
developer72fb0bb2023-01-11 09:46:29 +08008097 wifi_setApMacAddressControlMode(apIndex, 2);
developera3511852023-06-14 14:12:59 +08008098 } else
developer72fb0bb2023-01-11 09:46:29 +08008099 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08008100
developera3511852023-06-14 14:12:59 +08008101 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008102}
8103
8104INT wifi_setPreferPrivateConnection(BOOL enable)
8105{
developera3511852023-06-14 14:12:59 +08008106 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008107}
8108
8109// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
8110INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
8111{
developer2edaf012023-05-24 14:24:53 +08008112 int if_idx = 0, ret = 0;
8113 struct unl unl_ins;
8114 struct nl_msg *msg = NULL;
8115 struct nlattr * msg_data = NULL;
8116 struct mtk_nl80211_param param;
8117 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08008118 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008119
developer7e4a2a62023-04-06 19:56:03 +08008120 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
8121 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08008122 if_idx = if_nametoindex(inf_name);
8123 if (!if_idx) {
8124 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
8125 return RETURN_ERR;
8126 }
8127 /*init mtk nl80211 vendor cmd*/
8128 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
8129 param.if_type = NL80211_ATTR_IFINDEX;
8130 param.if_idx = if_idx;
8131 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8132 if (ret) {
8133 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8134 return RETURN_ERR;
8135 }
8136 /*add mtk vendor cmd data*/
8137 if (filterMode == 0) {
8138 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
8139 } else if (filterMode == 1) {
8140 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
8141 } else if (filterMode == 2) {
8142 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
8143 } else {
8144 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
8145 nlmsg_free(msg);
8146 goto err;
8147 }
8148 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
8149 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8150 nlmsg_free(msg);
8151 goto err;
8152 }
8153 /*send mtk nl80211 vendor msg*/
8154 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8155 if (ret) {
8156 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
8157 goto err;
8158 }
8159 /*deinit mtk nl80211 vendor msg*/
8160 mtk_nl80211_deint(&unl_ins);
8161 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08008162 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08008163err:
8164 mtk_nl80211_deint(&unl_ins);
8165 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8166 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008167}
8168
8169// 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.
8170INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
8171{
developera3511852023-06-14 14:12:59 +08008172 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008173}
8174
8175// gets the vlan ID for this ap from an internal enviornment variable
8176INT wifi_getApVlanID(INT apIndex, INT *output_int)
8177{
developera3511852023-06-14 14:12:59 +08008178 if(apIndex==0)
8179 {
8180 *output_int=100;
8181 return RETURN_OK;
8182 }
developer72fb0bb2023-01-11 09:46:29 +08008183
developera3511852023-06-14 14:12:59 +08008184 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008185}
8186
8187// sets the vlan ID for this ap to an internal enviornment variable
8188INT wifi_setApVlanID(INT apIndex, INT vlanId)
8189{
developera3511852023-06-14 14:12:59 +08008190 //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)
8191 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008192}
8193
developercc5cbfb2023-06-13 18:29:52 +08008194char br_name[IFNAMSIZ] = "brlan0";
8195
developer72fb0bb2023-01-11 09:46:29 +08008196// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
8197INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
8198{
developercc5cbfb2023-06-13 18:29:52 +08008199 int sock = socket(AF_INET, SOCK_DGRAM, 0);
8200 struct ifreq ifr;
8201 struct sockaddr_in *sin;
8202
8203 memcpy(bridgeName, br_name, strlen(br_name));
8204
8205 if (sock == -1) {
8206 wifi_debug(DEBUG_ERROR, "socket failed");
8207 return RETURN_ERR;
8208 }
8209
8210 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
8211 ifr.ifr_addr.sa_family = AF_INET;
8212 if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
8213 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFADDR) failed, %s, bridge_name=%s\n",
8214 strerror(errno), br_name);
8215 return RETURN_ERR;
8216 }
8217
8218 sin = (struct sockaddr_in *)&ifr.ifr_addr;
8219 wifi_debug(DEBUG_ERROR, "Bridge device %s has IP address: %s\n", br_name, inet_ntoa(sin->sin_addr));
8220 memcpy(IP, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
8221
8222 if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0) {
8223 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFNETMASK) failed, %s", strerror(errno));
8224 return RETURN_ERR;
8225 }
8226
8227 wifi_debug(DEBUG_ERROR, "Bridge device %s has subnet mask: %s\n", br_name, inet_ntoa(sin->sin_addr));
8228 memcpy(subnet, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
8229 close(sock);
developer72fb0bb2023-01-11 09:46:29 +08008230
developera3511852023-06-14 14:12:59 +08008231 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008232}
8233
8234//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
8235INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
8236{
developera3511852023-06-14 14:12:59 +08008237 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
developercc5cbfb2023-06-13 18:29:52 +08008238 struct ifreq ifr;
8239 struct sockaddr_in sin;
8240 int sock = socket(AF_INET, SOCK_DGRAM, 0);
8241
8242 if (strlen(bridgeName) >= IFNAMSIZ) {
8243 wifi_debug(DEBUG_ERROR, "invalide bridgeName length=%ld\n", strlen(bridgeName));
8244 return RETURN_ERR;
8245 }
8246
8247 if (strlen(br_name) >= IFNAMSIZ) {
8248 wifi_debug(DEBUG_ERROR, "invalide br_name length=%ld in strorage\n", strlen(br_name));
8249 return RETURN_ERR;
8250 }
8251
8252 if (sock == -1) {
developera3511852023-06-14 14:12:59 +08008253 wifi_debug(DEBUG_ERROR, "socket failed");
developercc5cbfb2023-06-13 18:29:52 +08008254 return RETURN_ERR;
8255 }
8256
8257 memset(&ifr, 0, sizeof(ifr));
8258 strncpy(ifr.ifr_name, br_name, strlen(br_name));
8259 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
8260 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
8261 return RETURN_ERR;
8262 }
8263
8264 ifr.ifr_flags = (short)(ifr.ifr_flags & ~IFF_UP);
8265 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
8266 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
8267 return RETURN_ERR;
8268 }
8269
8270 memset(&ifr, 0, sizeof(ifr));
8271 strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
8272 strncpy(ifr.ifr_newname, bridgeName, IFNAMSIZ);
8273 if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
8274 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNAME) failed, %s", strerror(errno));
developera3511852023-06-14 14:12:59 +08008275 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08008276 }
8277
8278 memset(br_name, 0, sizeof(br_name));
8279 memcpy(br_name, bridgeName, strlen(bridgeName));
8280
8281 memset(&ifr, 0, sizeof(ifr));
8282 strncpy(ifr.ifr_name, bridgeName, IFNAMSIZ);
8283 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
8284 wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
developera3511852023-06-14 14:12:59 +08008285 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08008286 }
8287 ifr.ifr_flags = (short)(ifr.ifr_flags | IFF_UP);
8288 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
8289 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
developera3511852023-06-14 14:12:59 +08008290 return RETURN_ERR;
developercc5cbfb2023-06-13 18:29:52 +08008291 }
8292
8293 memset(&ifr, 0, sizeof(ifr));
8294 memcpy(ifr.ifr_name, bridgeName, strlen(bridgeName));
8295
8296 memset(&sin, 0, sizeof(struct sockaddr_in));
8297 sin.sin_family = AF_INET;
8298 if (inet_aton(IP, &(sin.sin_addr)) == 0) {
8299 wifi_debug(DEBUG_ERROR, "inet_aton failed");
8300 return RETURN_ERR;
8301 }
8302 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in));
8303 if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
8304 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFADDR) failed, %s", strerror(errno));
8305 return RETURN_ERR;
8306 }
8307
8308 if (inet_aton(subnet, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr) == 0) {
8309 wifi_debug(DEBUG_ERROR, "inet_aton failed");
8310 return RETURN_ERR;
8311 }
8312 if (ioctl(sock, SIOCSIFNETMASK, &ifr) < -1) {
8313 wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNETMASK) failed, %s", strerror(errno));
8314 return RETURN_ERR;
8315 }
8316
8317 close(sock);
developera3511852023-06-14 14:12:59 +08008318 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008319}
8320
8321// reset the vlan configuration for this ap
8322INT wifi_resetApVlanCfg(INT apIndex)
8323{
developera1255e42023-05-13 17:45:02 +08008324 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08008325 int if_idx, ret = 0;
8326 struct nl_msg *msg = NULL;
8327 struct nlattr * msg_data = NULL;
8328 struct mtk_nl80211_param param;
8329 struct unl unl_ins;
8330 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08008331
developer2202b332023-05-24 16:23:22 +08008332 if (apIndex > MAX_APS) {
8333 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8334 return RETURN_ERR;
8335 }
developer72fb0bb2023-01-11 09:46:29 +08008336
developer2202b332023-05-24 16:23:22 +08008337 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8338 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8339 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008340
developer2202b332023-05-24 16:23:22 +08008341 /*step 1. mwctl dev %s set vlan_tag 0*/
8342 if_idx = if_nametoindex(interface_name);
8343 /*init mtk nl80211 vendor cmd*/
8344 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
8345 param.if_type = NL80211_ATTR_IFINDEX;
8346 param.if_idx = if_idx;
8347 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08008348
developer2202b332023-05-24 16:23:22 +08008349 if (ret) {
8350 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8351 return RETURN_ERR;
8352 }
developer72fb0bb2023-01-11 09:46:29 +08008353
developer2202b332023-05-24 16:23:22 +08008354 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
8355 printf("Nla put attribute error\n");
8356 nlmsg_free(msg);
8357 goto err;
8358 }
developer72fb0bb2023-01-11 09:46:29 +08008359
developer2202b332023-05-24 16:23:22 +08008360 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8361 if (ret) {
8362 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8363 goto err;
8364 }
8365 mtk_nl80211_deint(&unl_ins);
8366 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08008367
developer2202b332023-05-24 16:23:22 +08008368 /*step 2. mwctl dev %s set vlan_priority 0*/
8369 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8370 if (ret) {
8371 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8372 return RETURN_ERR;
8373 }
developer72fb0bb2023-01-11 09:46:29 +08008374
developer2202b332023-05-24 16:23:22 +08008375 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
8376 printf("Nla put attribute error\n");
8377 nlmsg_free(msg);
8378 goto err;
8379 }
developer72fb0bb2023-01-11 09:46:29 +08008380
developer2202b332023-05-24 16:23:22 +08008381 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8382 if (ret) {
8383 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8384 goto err;
8385 }
8386 mtk_nl80211_deint(&unl_ins);
8387 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
8388
8389 /*step 3. mwctl dev %s set vlan_id 0*/
8390 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8391 if (ret) {
8392 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08008393 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08008394 }
developer72fb0bb2023-01-11 09:46:29 +08008395
developer2202b332023-05-24 16:23:22 +08008396 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
8397 printf("Nla put attribute error\n");
8398 nlmsg_free(msg);
8399 goto err;
8400 }
8401
8402 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8403 if (ret) {
8404 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8405 goto err;
8406 }
8407 mtk_nl80211_deint(&unl_ins);
8408 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
8409
8410 /*step 4. mwctl dev %s set vlan_en 0*/
8411 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8412 if (ret) {
8413 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8414 return RETURN_ERR;
8415 }
8416
8417 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
8418 printf("Nla put attribute error\n");
8419 nlmsg_free(msg);
8420 goto err;
8421 }
8422
8423 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8424 if (ret) {
8425 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8426 goto err;
8427 }
8428 mtk_nl80211_deint(&unl_ins);
8429 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
8430
8431 /*step 5. mwctl dev %s set vlan_policy 0:4*/
8432 vlan_param.direction = 0;
8433 vlan_param.policy = 4;
8434 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8435 if (ret) {
8436 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8437 return RETURN_ERR;
8438 }
8439 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
8440 printf("Nla put attribute error\n");
8441 nlmsg_free(msg);
8442 goto err;
8443 }
8444
8445 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8446 if (ret) {
8447 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8448 goto err;
8449 }
8450 mtk_nl80211_deint(&unl_ins);
8451 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
8452
8453 /*step 6. mwctl dev %s set vlan_policy 1:0*/
8454 vlan_param.direction = 1;
8455 vlan_param.policy = 0;
8456 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8457 if (ret) {
8458 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8459 return RETURN_ERR;
8460 }
8461
8462 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
8463 printf("Nla put attribute error\n");
8464 nlmsg_free(msg);
8465 goto err;
8466 }
8467
8468 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8469 if (ret) {
8470 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8471 goto err;
8472 }
8473 /*deinit mtk nl80211 vendor msg*/
8474 mtk_nl80211_deint(&unl_ins);
8475 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
8476
8477 /*TODO need to modify VLAN config in dat file*/
8478 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8479
8480 return RETURN_OK;
8481err:
8482 mtk_nl80211_deint(&unl_ins);
8483 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8484 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008485}
8486
8487// 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.
8488INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
8489{
developera3511852023-06-14 14:12:59 +08008490 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008491}
8492
8493// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
8494INT wifi_startHostApd()
8495{
developera3511852023-06-14 14:12:59 +08008496 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8497 system("systemctl start hostapd.service");
8498 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8499 return RETURN_OK;
8500 //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 +08008501}
8502
8503// stops hostapd
developer69b61b02023-03-07 17:17:44 +08008504INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08008505{
developera3511852023-06-14 14:12:59 +08008506 char cmd[128] = {0};
8507 char buf[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008508
developera3511852023-06-14 14:12:59 +08008509 sprintf(cmd,"systemctl stop hostapd");
8510 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008511
developera3511852023-06-14 14:12:59 +08008512 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008513}
8514
8515// restart hostapd dummy function
8516INT wifi_restartHostApd()
8517{
developera3511852023-06-14 14:12:59 +08008518 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8519 system("systemctl restart hostapd-global");
8520 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008521
developera3511852023-06-14 14:12:59 +08008522 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008523}
8524
8525// sets the AP enable status variable for the specified ap.
8526INT wifi_setApEnable(INT apIndex, BOOL enable)
8527{
developer7e4a2a62023-04-06 19:56:03 +08008528 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +08008529 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +08008530 char cmd[MAX_CMD_SIZE] = {0};
8531 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008532 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08008533 int max_radio_num = 0;
8534 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08008535 int res;
developer72fb0bb2023-01-11 09:46:29 +08008536
developer7e4a2a62023-04-06 19:56:03 +08008537 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08008538
developer7e4a2a62023-04-06 19:56:03 +08008539 wifi_getMaxRadioNumber(&max_radio_num);
8540 if (enable == status)
8541 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008542
developer7e4a2a62023-04-06 19:56:03 +08008543 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8544 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008545
developer7e4a2a62023-04-06 19:56:03 +08008546 if (enable == TRUE) {
8547 int radioIndex = apIndex % max_radio_num;
8548 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08008549 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
8550 if (os_snprintf_error(sizeof(cmd), res)) {
8551 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8552 return RETURN_ERR;
8553 }
developerf3c7d292023-05-29 17:57:16 +08008554 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08008555
developere40952c2023-06-15 18:46:43 +08008556 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
8557 if (os_snprintf_error(MAX_BUF_SIZE, res)) {
8558 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8559 return RETURN_ERR;
8560 }
8561 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
8562 if (os_snprintf_error(sizeof(cmd), res)) {
8563 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8564 return RETURN_ERR;
8565 }
developer7e4a2a62023-04-06 19:56:03 +08008566 _syscmd(cmd, buf, sizeof(buf));
8567 } else {
developere40952c2023-06-15 18:46:43 +08008568 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8569 if (os_snprintf_error(sizeof(cmd), res)) {
8570 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8571 return RETURN_ERR;
8572 }
developer7e4a2a62023-04-06 19:56:03 +08008573 _syscmd(cmd, buf, sizeof(buf));
developere40952c2023-06-15 18:46:43 +08008574 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
8575 if (os_snprintf_error(sizeof(cmd), res)) {
8576 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8577 return RETURN_ERR;
8578 }
developerf3c7d292023-05-29 17:57:16 +08008579 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +08008580 }
developere40952c2023-06-15 18:46:43 +08008581 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer7e4a2a62023-04-06 19:56:03 +08008582 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +08008583 if (os_snprintf_error(sizeof(cmd), res)) {
8584 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8585 return RETURN_ERR;
8586 }
developer7e4a2a62023-04-06 19:56:03 +08008587 _syscmd(cmd, buf, sizeof(buf));
8588 //Wait for wifi up/down to apply
8589 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008590}
8591
8592// Outputs the setting of the internal variable that is set by wifi_setApEnable().
8593INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
8594{
developer7e4a2a62023-04-06 19:56:03 +08008595 char interface_name[IF_NAME_SIZE] = {0};
8596 char cmd[MAX_CMD_SIZE] = {0};
developerc1aa6532023-06-09 09:37:01 +08008597 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008598
developer7e4a2a62023-04-06 19:56:03 +08008599 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
8600 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008601
developer7e4a2a62023-04-06 19:56:03 +08008602 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08008603
developer7e4a2a62023-04-06 19:56:03 +08008604 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
8605 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8606 *output_bool = FALSE;
8607 return RETURN_OK;
8608 }
developerc1aa6532023-06-09 09:37:01 +08008609
8610 sprintf(cmd, "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
8611 _syscmd(cmd, buf, sizeof(buf));
8612
8613 if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 ||
8614 strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) {
8615 *output_bool = TRUE;
8616 }
developer7e4a2a62023-04-06 19:56:03 +08008617 }
developer72fb0bb2023-01-11 09:46:29 +08008618
developer7e4a2a62023-04-06 19:56:03 +08008619 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008620}
8621
developer69b61b02023-03-07 17:17:44 +08008622// Outputs the AP "Enabled" "Disabled" status from driver
8623INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08008624{
developer7e4a2a62023-04-06 19:56:03 +08008625 BOOL output_bool;
developere40952c2023-06-15 18:46:43 +08008626 int res;
developer72fb0bb2023-01-11 09:46:29 +08008627
developer7e4a2a62023-04-06 19:56:03 +08008628 if (!output_string) {
8629 printf("%s: null pointer!", __func__);
8630 return RETURN_ERR;
8631 }
developer72fb0bb2023-01-11 09:46:29 +08008632
developer7e4a2a62023-04-06 19:56:03 +08008633 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08008634
developer7e4a2a62023-04-06 19:56:03 +08008635 if(output_bool == 1)
developere40952c2023-06-15 18:46:43 +08008636 res = snprintf(output_string, 32, "Up");
developer7e4a2a62023-04-06 19:56:03 +08008637 else
developere40952c2023-06-15 18:46:43 +08008638 res = snprintf(output_string, 32, "Disable");
8639 if (os_snprintf_error(32, res)) {
8640 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8641 return RETURN_ERR;
8642 }
developer7e4a2a62023-04-06 19:56:03 +08008643
8644 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008645}
8646
8647//Indicates whether or not beacons include the SSID name.
8648// outputs a 1 if SSID on the AP is enabled, else outputs 0
8649INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
8650{
developera3511852023-06-14 14:12:59 +08008651 //get the running status
8652 char config_file[MAX_BUF_SIZE] = {0};
8653 char buf[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008654
developera3511852023-06-14 14:12:59 +08008655 if (!output)
8656 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008657
developera3511852023-06-14 14:12:59 +08008658 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8659 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
8660 // default is enable
8661 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
8662 *output = TRUE;
developer72fb0bb2023-01-11 09:46:29 +08008663
developera3511852023-06-14 14:12:59 +08008664 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008665}
8666
8667// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
8668INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
8669{
developera3511852023-06-14 14:12:59 +08008670 //store the config, apply instantly
8671 char config_file[MAX_BUF_SIZE] = {0};
8672 struct params list;
developer72fb0bb2023-01-11 09:46:29 +08008673
developera3511852023-06-14 14:12:59 +08008674 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8675 list.name = "ignore_broadcast_ssid";
8676 list.value = enable?"0":"1";
developer72fb0bb2023-01-11 09:46:29 +08008677
developera3511852023-06-14 14:12:59 +08008678 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8679 wifi_hostapdWrite(config_file, &list, 1);
8680 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8681 //TODO: call hostapd_cli for dynamic_config_control
8682 wifi_reloadAp(apIndex);
8683 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008684
developera3511852023-06-14 14:12:59 +08008685 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008686}
8687
8688//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
8689INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
8690{
developer47cc27a2023-05-17 23:09:58 +08008691 /* get the running status */
8692 if(!output_uint)
developera3511852023-06-14 14:12:59 +08008693 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08008694
8695 *output_uint = 15;
8696 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008697}
8698
developer47cc27a2023-05-17 23:09:58 +08008699/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +08008700INT wifi_setApRetryLimit(INT apIndex, UINT number)
8701{
developer47cc27a2023-05-17 23:09:58 +08008702 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008703}
8704
developer95c045d2023-05-24 19:26:28 +08008705int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
8706{
8707 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8708 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
8709 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developer2f79c922023-06-02 17:33:42 +08008710 unsigned char *status = (unsigned char *)data;
developer95c045d2023-05-24 19:26:28 +08008711 int err = 0;
developer95c045d2023-05-24 19:26:28 +08008712
8713 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8714 genlmsg_attrlen(gnlh, 0), NULL);
8715 if (err < 0)
8716 return err;
8717
8718 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8719 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
8720 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8721 if (err < 0)
8722 return err;
8723
8724 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
developer95c045d2023-05-24 19:26:28 +08008725 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
8726 }
8727 }
8728
8729 return 0;
8730}
8731
developer72fb0bb2023-01-11 09:46:29 +08008732//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
8733INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
8734{
developer95c045d2023-05-24 19:26:28 +08008735 int if_idx, ret = 0;
developera3511852023-06-14 14:12:59 +08008736 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08008737 unsigned char status = 0;
8738 struct nl_msg *msg = NULL;
8739 struct nlattr * msg_data = NULL;
8740 struct mtk_nl80211_param param;
8741 struct unl unl_ins;
developer8e6583c2023-05-23 13:36:06 +08008742
developera3511852023-06-14 14:12:59 +08008743 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8744 if(!output)
developerdaf24792023-06-06 11:40:04 +08008745 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008746
developer95c045d2023-05-24 19:26:28 +08008747 if (apIndex > MAX_APS) {
8748 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8749 return RETURN_ERR;
8750 }
8751
developera3511852023-06-14 14:12:59 +08008752 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developerdaf24792023-06-06 11:40:04 +08008753 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +08008754
8755 if_idx = if_nametoindex(interface_name);
8756 /*init mtk nl80211 vendor cmd*/
8757 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8758 param.if_type = NL80211_ATTR_IFINDEX;
8759 param.if_idx = if_idx;
8760 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8761
8762 if (ret) {
8763 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8764 return RETURN_ERR;
8765 }
8766
8767 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
8768 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8769 nlmsg_free(msg);
8770 goto err;
8771 }
8772
8773 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
8774 (void *)&status);
8775 if (ret) {
8776 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8777 goto err;
8778 }
8779 mtk_nl80211_deint(&unl_ins);
8780
8781 *output = status == 0 ? FALSE : TRUE;
8782 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +08008783
developera3511852023-06-14 14:12:59 +08008784 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8785 return RETURN_OK;
8786err:
developer95c045d2023-05-24 19:26:28 +08008787 mtk_nl80211_deint(&unl_ins);
8788 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8789 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008790}
8791
8792//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
8793INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
8794{
developera3511852023-06-14 14:12:59 +08008795 //get the running status from driver
8796 char cmd[128] = {0};
8797 char buf[128] = {0};
8798 int max_radio_num = 0, radioIndex = 0;
8799 int phyId = 0;
developere40952c2023-06-15 18:46:43 +08008800 int res;
developer72fb0bb2023-01-11 09:46:29 +08008801
developera3511852023-06-14 14:12:59 +08008802 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008803
developera3511852023-06-14 14:12:59 +08008804 wifi_getMaxRadioNumber(&max_radio_num);
8805 radioIndex = apIndex % max_radio_num;
8806 phyId = radio_index_to_phy(radioIndex);
developere40952c2023-06-15 18:46:43 +08008807 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
8808 if (os_snprintf_error(sizeof(cmd), res)) {
8809 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8810 return RETURN_ERR;
8811 }
developera3511852023-06-14 14:12:59 +08008812 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008813
developera3511852023-06-14 14:12:59 +08008814 if (strlen(buf) > 0)
8815 *output = true;
developer72fb0bb2023-01-11 09:46:29 +08008816
developera3511852023-06-14 14:12:59 +08008817 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008818
developera3511852023-06-14 14:12:59 +08008819 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008820}
8821
8822//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
8823INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
8824{
developera3511852023-06-14 14:12:59 +08008825 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +08008826}
8827
8828// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
8829INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
8830{
developer95c045d2023-05-24 19:26:28 +08008831 int if_idx, ret = 0;
8832 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08008833 struct nl_msg *msg = NULL;
8834 struct nlattr * msg_data = NULL;
8835 struct mtk_nl80211_param param;
8836 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +08008837
developer95c045d2023-05-24 19:26:28 +08008838 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008839
developer95c045d2023-05-24 19:26:28 +08008840 if (apIndex > MAX_APS) {
8841 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8842 return RETURN_ERR;
8843 }
developer72fb0bb2023-01-11 09:46:29 +08008844
developer95c045d2023-05-24 19:26:28 +08008845 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8846 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008847
developer95c045d2023-05-24 19:26:28 +08008848 if_idx = if_nametoindex(interface_name);
8849 /*init mtk nl80211 vendor cmd*/
8850 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8851 param.if_type = NL80211_ATTR_IFINDEX;
8852 param.if_idx = if_idx;
8853 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8854
8855 if (ret) {
8856 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8857 return RETURN_ERR;
8858 }
8859
8860 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
8861 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8862 nlmsg_free(msg);
8863 goto err;
8864 }
8865
8866 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8867 if (ret) {
8868 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8869 goto err;
8870 }
8871 mtk_nl80211_deint(&unl_ins);
8872
8873 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8874 return RETURN_OK;
8875err:
8876 mtk_nl80211_deint(&unl_ins);
8877 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8878 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008879}
8880
developer95c045d2023-05-24 19:26:28 +08008881
developer72fb0bb2023-01-11 09:46:29 +08008882//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.
8883INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
8884{
developera3511852023-06-14 14:12:59 +08008885 //get the running status from driver
8886 if(!output)
8887 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008888
developera3511852023-06-14 14:12:59 +08008889 char config_file[128] = {0};
8890 char buf[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008891
developera3511852023-06-14 14:12:59 +08008892 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8893 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
8894 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
8895 *output = TRUE;
8896 else
8897 *output = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08008898
developera3511852023-06-14 14:12:59 +08008899 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008900}
8901
8902// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
8903INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
8904{
developera3511852023-06-14 14:12:59 +08008905 //save config and apply instantly.
8906 char config_file[MAX_BUF_SIZE] = {0};
8907 struct params list;
developer72fb0bb2023-01-11 09:46:29 +08008908
developera3511852023-06-14 14:12:59 +08008909 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8910 list.name = "uapsd_advertisement_enabled";
8911 list.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +08008912
developera3511852023-06-14 14:12:59 +08008913 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8914 wifi_hostapdWrite(config_file, &list, 1);
8915 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8916 wifi_quick_reload_ap(apIndex);
8917 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008918
developera3511852023-06-14 14:12:59 +08008919 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008920}
8921
8922// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
8923INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
8924{
developera3511852023-06-14 14:12:59 +08008925 char interface_name[16] = {0};
8926 // assume class 0->BE, 1->BK, 2->VI, 3->VO
8927 char cmd[MAX_CMD_SIZE] = {0};
8928 char buf[128] = {0};
8929 char ack_filepath[128] = {0};
8930 uint16_t bitmap = 0;
8931 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
8932 FILE *f = NULL;
developere40952c2023-06-15 18:46:43 +08008933 int res;
developer72fb0bb2023-01-11 09:46:29 +08008934
developera3511852023-06-14 14:12:59 +08008935 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008936
developera3511852023-06-14 14:12:59 +08008937 // Get current setting
developere40952c2023-06-15 18:46:43 +08008938 res = snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
8939 if (os_snprintf_error(sizeof(ack_filepath), res)) {
8940 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8941 return RETURN_ERR;
8942 }
8943 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
8944 if (os_snprintf_error(sizeof(cmd), res)) {
8945 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8946 return RETURN_ERR;
8947 }
developera3511852023-06-14 14:12:59 +08008948 _syscmd(cmd, buf, sizeof(buf));
8949 if (strlen(buf) > 0)
8950 bitmap = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08008951
developera3511852023-06-14 14:12:59 +08008952 bitmap = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08008953
developera3511852023-06-14 14:12:59 +08008954 if (ackPolicy == TRUE) { // True, unset this class
8955 bitmap &= ~class_map[class];
8956 } else { // False, set this class
8957 bitmap |= class_map[class];
8958 }
developer72fb0bb2023-01-11 09:46:29 +08008959
developera3511852023-06-14 14:12:59 +08008960 f = fopen(ack_filepath, "w");
8961 if (f == NULL) {
8962 fprintf(stderr, "%s: fopen failed\n", __func__);
8963 return RETURN_ERR;
8964 }
8965 fprintf(f, "%hu", bitmap);
8966 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08008967
developera3511852023-06-14 14:12:59 +08008968 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8969 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08008970 res = snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
8971 if (os_snprintf_error(sizeof(cmd), res)) {
8972 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
8973 return RETURN_ERR;
8974 }
developera3511852023-06-14 14:12:59 +08008975 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08008976
developera3511852023-06-14 14:12:59 +08008977 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
8978 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008979}
8980
8981//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.
8982INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
8983{
developera3511852023-06-14 14:12:59 +08008984 //get the running status from driver
8985 if(!output_uint)
8986 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008987
developera3511852023-06-14 14:12:59 +08008988 char output[16]={'\0'};
8989 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008990
developera3511852023-06-14 14:12:59 +08008991 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8992 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
8993 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
8994 else {
8995 int device_num = atoi(output);
8996 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
8997 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
8998 return RETURN_ERR;
8999 }
9000 else {
9001 *output_uint = device_num;
9002 }
9003 }
developer72fb0bb2023-01-11 09:46:29 +08009004
developera3511852023-06-14 14:12:59 +08009005 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009006}
9007
9008INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
9009{
developera3511852023-06-14 14:12:59 +08009010 //store to wifi config, apply instantly
9011 char str[MAX_BUF_SIZE]={'\0'};
9012 struct params params;
9013 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009014
developera3511852023-06-14 14:12:59 +08009015 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9016 if (number > MAX_ASSOCIATED_STA_NUM) {
9017 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
9018 return RETURN_ERR;
9019 }
9020 sprintf(str, "%d", number);
9021 params.name = "max_num_sta";
9022 params.value = str;
developer72fb0bb2023-01-11 09:46:29 +08009023
developera3511852023-06-14 14:12:59 +08009024 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
9025 int ret = wifi_hostapdWrite(config_file, &params, 1);
9026 if (ret) {
9027 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
9028 ,__func__, ret);
9029 }
developer72fb0bb2023-01-11 09:46:29 +08009030
developera3511852023-06-14 14:12:59 +08009031 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
9032 if (ret) {
9033 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
9034 ,__func__, ret);
9035 }
9036 wifi_reloadAp(apIndex);
9037 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009038
developera3511852023-06-14 14:12:59 +08009039 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009040}
9041
9042//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.
9043INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
9044{
developera3511852023-06-14 14:12:59 +08009045 //get the current threshold
9046 if(!output_uint)
9047 return RETURN_ERR;
9048 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
9049 if (*output_uint == 0)
9050 *output_uint = 50;
9051 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009052}
9053
9054INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
9055{
developera3511852023-06-14 14:12:59 +08009056 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
9057 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
9058 return RETURN_OK;
9059 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009060}
9061
9062//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.
9063INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
9064{
developera3511852023-06-14 14:12:59 +08009065 if(!output_uint)
9066 return RETURN_ERR;
9067 *output_uint = 3;
9068 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009069}
9070
9071//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
9072INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
9073{
developera3511852023-06-14 14:12:59 +08009074 if(!output_uint)
9075 return RETURN_ERR;
9076 *output_uint = 3;
9077 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009078}
9079
9080//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.
9081INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
9082{
developera3511852023-06-14 14:12:59 +08009083 if(!output_in_seconds)
9084 return RETURN_ERR;
9085 *output_in_seconds = 0;
9086 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009087}
9088
9089//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
9090INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
9091{
developere40952c2023-06-15 18:46:43 +08009092 int res;
9093
developera3511852023-06-14 14:12:59 +08009094 if(!output || apIndex>=MAX_APS)
9095 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009096 //res = snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
9097 res = snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
9098 if (os_snprintf_error(128, res)) {
9099 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9100 return RETURN_ERR;
9101 }
developera3511852023-06-14 14:12:59 +08009102 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08009103}
developer72fb0bb2023-01-11 09:46:29 +08009104
9105//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
9106INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
9107{
developera3511852023-06-14 14:12:59 +08009108 char config_file[128] = {0};
9109 char wpa[16] = {0};
9110 char key_mgmt[64] = {0};
developere40952c2023-06-15 18:46:43 +08009111 int res;
9112
developera3511852023-06-14 14:12:59 +08009113 if (!output)
9114 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009115
developera3511852023-06-14 14:12:59 +08009116 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
9117 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
developer72fb0bb2023-01-11 09:46:29 +08009118
developera3511852023-06-14 14:12:59 +08009119 strcpy(output, "None");//Copying "None" to output string for default case
9120 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
9121 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
9122 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +08009123 res = snprintf(output, 32, "WPA-Personal");
developera3511852023-06-14 14:12:59 +08009124 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +08009125 res = snprintf(output, 32, "WPA2-Personal");
developera3511852023-06-14 14:12:59 +08009126 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +08009127 res = snprintf(output, 32, "WPA-WPA2-Personal");
developer72fb0bb2023-01-11 09:46:29 +08009128
developera3511852023-06-14 14:12:59 +08009129 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
developere40952c2023-06-15 18:46:43 +08009130 res = snprintf(output, 32, "WPA3-Enterprise");
developera3511852023-06-14 14:12:59 +08009131 } else if (strstr(key_mgmt, "WPA-EAP")) {
9132 if (!strcmp(wpa, "1"))
developere40952c2023-06-15 18:46:43 +08009133 res = snprintf(output, 32, "WPA-Enterprise");
developera3511852023-06-14 14:12:59 +08009134 else if (!strcmp(wpa, "2"))
developere40952c2023-06-15 18:46:43 +08009135 res = snprintf(output, 32, "WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +08009136 else if (!strcmp(wpa, "3"))
developere40952c2023-06-15 18:46:43 +08009137 res = snprintf(output, 32, "WPA-WPA2-Enterprise");
developera3511852023-06-14 14:12:59 +08009138 } else if (strstr(key_mgmt, "SAE")) {
9139 if (strstr(key_mgmt, "WPA-PSK") == NULL)
developere40952c2023-06-15 18:46:43 +08009140 res = snprintf(output, 32, "WPA3-Personal");
developera3511852023-06-14 14:12:59 +08009141 else
developere40952c2023-06-15 18:46:43 +08009142 res = snprintf(output, 32, "WPA3-Personal-Transition");
9143 }
9144 if (os_snprintf_error(32, res)) {
9145 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9146 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +08009147 }
developer72fb0bb2023-01-11 09:46:29 +08009148
developera3511852023-06-14 14:12:59 +08009149 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
9150 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009151}
developer69b61b02023-03-07 17:17:44 +08009152
developer72fb0bb2023-01-11 09:46:29 +08009153INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
9154{
developera3511852023-06-14 14:12:59 +08009155 char securityType[32];
9156 char authMode[32];
developer72fb0bb2023-01-11 09:46:29 +08009157
developera3511852023-06-14 14:12:59 +08009158 //store settings and wait for wifi up to apply
9159 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9160 if(!encMode)
9161 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009162
developera3511852023-06-14 14:12:59 +08009163 if (strcmp(encMode, "None")==0)
9164 {
9165 strcpy(securityType,"None");
9166 strcpy(authMode,"None");
9167 }
9168 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
9169 {
9170 strcpy(securityType,"WPAand11i");
9171 strcpy(authMode,"PSKAuthentication");
9172 }
9173 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
9174 {
9175 strcpy(securityType,"WPAand11i");
9176 strcpy(authMode,"EAPAuthentication");
9177 }
9178 else if (strcmp(encMode, "WPA-Personal")==0)
9179 {
9180 strcpy(securityType,"WPA");
9181 strcpy(authMode,"PSKAuthentication");
9182 }
9183 else if (strcmp(encMode, "WPA-Enterprise")==0)
9184 {
9185 strcpy(securityType,"WPA");
9186 strcpy(authMode,"EAPAuthentication");
9187 }
9188 else if (strcmp(encMode, "WPA2-Personal")==0)
9189 {
9190 strcpy(securityType,"11i");
9191 strcpy(authMode,"PSKAuthentication");
9192 }
9193 else if (strcmp(encMode, "WPA2-Enterprise")==0)
9194 {
9195 strcpy(securityType,"11i");
9196 strcpy(authMode,"EAPAuthentication");
9197 }
9198 else if (strcmp(encMode, "WPA3-Personal") == 0)
9199 {
9200 strcpy(securityType,"11i");
9201 strcpy(authMode,"SAEAuthentication");
9202 }
9203 else if (strcmp(encMode, "WPA3-Personal-Transition") == 0)
9204 {
9205 strcpy(securityType, "11i");
9206 strcpy(authMode, "PSK-SAEAuthentication");
9207 }
9208 else if (strcmp(encMode, "WPA3-Enterprise") == 0)
9209 {
9210 strcpy(securityType,"11i");
9211 strcpy(authMode,"EAP_192-bit_Authentication");
9212 }
9213 else if (strcmp(encMode, "OWE") == 0)
9214 {
9215 strcpy(securityType,"11i");
9216 strcpy(authMode,"Enhanced_Open");
9217 }
9218 else
9219 {
9220 strcpy(securityType,"None");
9221 strcpy(authMode,"None");
9222 }
9223 wifi_setApBeaconType(apIndex, securityType);
9224 wifi_setApBasicAuthenticationMode(apIndex, authMode);
9225 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009226
developera3511852023-06-14 14:12:59 +08009227 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08009228}
developer72fb0bb2023-01-11 09:46:29 +08009229
9230
9231//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
9232// output_string must be pre-allocated as 64 character string by caller
9233// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
9234INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
9235{
developera3511852023-06-14 14:12:59 +08009236 char buf[16] = {0};
9237 char config_file[MAX_BUF_SIZE] = {0};
9238 int res;
developer72fb0bb2023-01-11 09:46:29 +08009239
developera3511852023-06-14 14:12:59 +08009240 if(output_string==NULL)
9241 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009242
developera3511852023-06-14 14:12:59 +08009243 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
9244 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +08009245 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9246 return RETURN_ERR;
9247 }
developera3511852023-06-14 14:12:59 +08009248 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009249
developera3511852023-06-14 14:12:59 +08009250 if(strcmp(buf,"0")==0)
9251 {
9252 printf("wpa_mode is %s ......... \n",buf);
9253 return RETURN_ERR;
9254 }
developer72fb0bb2023-01-11 09:46:29 +08009255
developera3511852023-06-14 14:12:59 +08009256 wifi_dbg_printf("\nFunc=%s\n",__func__);
9257 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
9258 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +08009259 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9260 return RETURN_ERR;
9261 }
developere5750452023-05-15 16:46:42 +08009262 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developera3511852023-06-14 14:12:59 +08009263 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +08009264
developera3511852023-06-14 14:12:59 +08009265 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009266}
9267
9268// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
9269// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
9270INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
9271{
developera3511852023-06-14 14:12:59 +08009272 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
9273 struct params params={'\0'};
9274 int ret;
9275 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009276
developera3511852023-06-14 14:12:59 +08009277 if(NULL == preSharedKey)
9278 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009279
developera3511852023-06-14 14:12:59 +08009280 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +08009281
developera3511852023-06-14 14:12:59 +08009282 if(strlen(preSharedKey) != 64)
9283 {
9284 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
9285 return RETURN_ERR;
9286 }
9287 params.value = preSharedKey;
9288 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
9289 ret = wifi_hostapdWrite(config_file, &params, 1);
9290 if(!ret) {
9291 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
9292 wifi_reloadAp(apIndex);
9293 }
9294 return ret;
9295 //TODO: call hostapd_cli for dynamic_config_control
developer72fb0bb2023-01-11 09:46:29 +08009296}
9297
9298//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
9299// outputs the passphrase, maximum 63 characters
9300INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
9301{
developera3511852023-06-14 14:12:59 +08009302 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009303
developera3511852023-06-14 14:12:59 +08009304 wifi_dbg_printf("\nFunc=%s\n",__func__);
9305 if (NULL == output_string)
9306 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009307
developera3511852023-06-14 14:12:59 +08009308 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
9309 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
9310 if(strcmp(buf,"0")==0)
9311 {
9312 printf("wpa_mode is %s ......... \n",buf);
9313 return RETURN_ERR;
9314 }
developer72fb0bb2023-01-11 09:46:29 +08009315
developera3511852023-06-14 14:12:59 +08009316 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
9317 wifi_dbg_printf("\noutput_string=%s\n",output_string);
developer72fb0bb2023-01-11 09:46:29 +08009318
developera3511852023-06-14 14:12:59 +08009319 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009320}
9321
9322// sets the passphrase enviornment variable, max 63 characters
9323INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
9324{
developera3511852023-06-14 14:12:59 +08009325 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
9326 struct params params={'\0'};
9327 char config_file[MAX_BUF_SIZE] = {0};
9328 int ret;
developer72fb0bb2023-01-11 09:46:29 +08009329
developera3511852023-06-14 14:12:59 +08009330 if(NULL == passPhrase)
9331 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009332
developera3511852023-06-14 14:12:59 +08009333 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
9334 {
9335 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
9336 return RETURN_ERR;
9337 }
9338 params.name = "wpa_passphrase";
9339 params.value = passPhrase;
9340 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
9341 ret=wifi_hostapdWrite(config_file,&params,1);
9342 if(!ret) {
9343 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08009344 wifi_reloadAp(apIndex);
developera3511852023-06-14 14:12:59 +08009345 }
developer72fb0bb2023-01-11 09:46:29 +08009346
developera3511852023-06-14 14:12:59 +08009347 return ret;
developer72fb0bb2023-01-11 09:46:29 +08009348}
9349
9350//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.
9351INT wifi_setApSecurityReset(INT apIndex)
9352{
developera3511852023-06-14 14:12:59 +08009353 char original_config_file[64] = {0};
9354 char current_config_file[64] = {0};
9355 char buf[64] = {0};
9356 char cmd[64] = {0};
9357 char wpa[4] = {0};
9358 char wpa_psk[64] = {0};
9359 char wpa_passphrase[64] = {0};
9360 char wpa_psk_file[128] = {0};
9361 char wpa_key_mgmt[64] = {0};
9362 char wpa_pairwise[32] = {0};
9363 wifi_band band;
9364 struct params list[6];
developere40952c2023-06-15 18:46:43 +08009365 int res;
developer72fb0bb2023-01-11 09:46:29 +08009366
developera3511852023-06-14 14:12:59 +08009367 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009368
developera3511852023-06-14 14:12:59 +08009369 band = wifi_index_to_band(apIndex);
9370 if (band == band_2_4)
9371 sprintf(original_config_file, "/etc/hostapd-2G.conf");
9372 else if (band == band_5)
9373 sprintf(original_config_file, "/etc/hostapd-5G.conf");
9374 else if (band == band_6)
9375 sprintf(original_config_file, "/etc/hostapd-6G.conf");
9376 else
9377 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009378
developera3511852023-06-14 14:12:59 +08009379 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
9380 list[0].name = "wpa";
9381 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +08009382
developera3511852023-06-14 14:12:59 +08009383 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
9384 list[1].name = "wpa_psk";
9385 list[1].value = wpa_psk;
developer72fb0bb2023-01-11 09:46:29 +08009386
developera3511852023-06-14 14:12:59 +08009387 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
9388 list[2].name = "wpa_passphrase";
9389 list[2].value = wpa_passphrase;
developer72fb0bb2023-01-11 09:46:29 +08009390
developera3511852023-06-14 14:12:59 +08009391 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
developer72fb0bb2023-01-11 09:46:29 +08009392
developera3511852023-06-14 14:12:59 +08009393 if (strlen(wpa_psk_file) == 0)
9394 strcpy(wpa_psk_file, PSK_FILE);
developer72fb0bb2023-01-11 09:46:29 +08009395
developera3511852023-06-14 14:12:59 +08009396 if (access(wpa_psk_file, F_OK) != 0) {
developere40952c2023-06-15 18:46:43 +08009397 res = snprintf(cmd, MAX_CMD_SIZE, "touch %s", wpa_psk_file);
9398 if (os_snprintf_error(sizeof(cmd), res)) {
9399 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9400 return RETURN_ERR;
9401 }
developera3511852023-06-14 14:12:59 +08009402 _syscmd(cmd, buf, sizeof(buf));
9403 }
9404 list[3].name = "wpa_psk_file";
9405 list[3].value = wpa_psk_file;
developer72fb0bb2023-01-11 09:46:29 +08009406
developera3511852023-06-14 14:12:59 +08009407 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
9408 list[4].name = "wpa_key_mgmt";
9409 list[4].value = wpa_key_mgmt;
developer72fb0bb2023-01-11 09:46:29 +08009410
developera3511852023-06-14 14:12:59 +08009411 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
9412 list[5].name = "wpa_pairwise";
9413 list[5].value = wpa_pairwise;
developer72fb0bb2023-01-11 09:46:29 +08009414
developera3511852023-06-14 14:12:59 +08009415 sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
9416 wifi_hostapdWrite(current_config_file, list, 6);
developer72fb0bb2023-01-11 09:46:29 +08009417
developera3511852023-06-14 14:12:59 +08009418 wifi_setApEnable(apIndex, FALSE);
9419 wifi_setApEnable(apIndex, TRUE);
developer72fb0bb2023-01-11 09:46:29 +08009420
developera3511852023-06-14 14:12:59 +08009421 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9422 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009423}
9424
9425//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).
9426INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
9427{
developera3511852023-06-14 14:12:59 +08009428 char config_file[64] = {0};
9429 char buf[64] = {0};
9430 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +08009431 int res;
developer72fb0bb2023-01-11 09:46:29 +08009432
developera3511852023-06-14 14:12:59 +08009433 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009434
developera3511852023-06-14 14:12:59 +08009435 if(!IP_output || !Port_output || !RadiusSecret_output)
9436 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009437
developera3511852023-06-14 14:12:59 +08009438 // Read the first matched config
developere40952c2023-06-15 18:46:43 +08009439 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9440 if (os_snprintf_error(sizeof(config_file), res)) {
9441 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9442 return RETURN_ERR;
9443 }
developera3511852023-06-14 14:12:59 +08009444 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9445 _syscmd(cmd, buf, sizeof(buf));
9446 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +08009447
developera3511852023-06-14 14:12:59 +08009448 memset(buf, 0, sizeof(buf));
9449 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9450 _syscmd(cmd, buf, sizeof(buf));
9451 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08009452
developera3511852023-06-14 14:12:59 +08009453 memset(buf, 0, sizeof(buf));
9454 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9455 _syscmd(cmd, buf, sizeof(buf));
9456 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +08009457
developera3511852023-06-14 14:12:59 +08009458 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9459 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009460}
9461
9462INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
9463{
developera3511852023-06-14 14:12:59 +08009464 char config_file[64] = {0};
9465 char port_str[8] = {0};
9466 char cmd[256] = {0};
9467 char buf[128] = {0};
9468 int res;
developer72fb0bb2023-01-11 09:46:29 +08009469
developera3511852023-06-14 14:12:59 +08009470 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009471
developere5750452023-05-15 16:46:42 +08009472 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08009473 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +08009474
developera3511852023-06-14 14:12:59 +08009475 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
9476 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +08009477
developera3511852023-06-14 14:12:59 +08009478 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9479 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +08009480 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9481 return RETURN_ERR;
9482 }
developer72fb0bb2023-01-11 09:46:29 +08009483
developera3511852023-06-14 14:12:59 +08009484 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
9485 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +08009486 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9487 return RETURN_ERR;
9488 }
developera3511852023-06-14 14:12:59 +08009489 _syscmd(cmd, buf, sizeof(buf));
9490 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +08009491
developere40952c2023-06-15 18:46:43 +08009492 res = snprintf(port_str, sizeof(port_str), "%d", port);
developera3511852023-06-14 14:12:59 +08009493 if (strlen(buf) == 0) {
9494 // Append
9495 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
9496 "auth_server_addr=%s\\n"
9497 "auth_server_port=%s\\n"
9498 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
9499 if (os_snprintf_error(sizeof(cmd), res)) {
9500 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9501 return RETURN_ERR;
9502 }
9503 } else {
9504 // Delete the three lines setting after the "# radius 1" comment
9505 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
9506 if (os_snprintf_error(sizeof(cmd), res)) {
9507 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9508 return RETURN_ERR;
9509 }
9510 _syscmd(cmd, buf, sizeof(buf));
9511 memset(cmd, 0, sizeof(cmd));
9512 // Use "# radius 1" comment to find the location to insert the radius setting
9513 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
9514 "# radius 1\\n"
9515 "auth_server_addr=%s\\n"
9516 "auth_server_port=%s\\n"
9517 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9518 if (os_snprintf_error(sizeof(cmd), res)) {
9519 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9520 return RETURN_ERR;
9521 }
9522 }
9523 if(_syscmd(cmd, buf, sizeof(buf))) {
9524 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9525 return RETURN_ERR;
9526 }
developer72fb0bb2023-01-11 09:46:29 +08009527
developera3511852023-06-14 14:12:59 +08009528 wifi_reloadAp(apIndex);
9529 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9530 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009531}
9532
9533INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
9534{
developera3511852023-06-14 14:12:59 +08009535 char config_file[64] = {0};
9536 char buf[64] = {0};
9537 char cmd[256] = {0};
developere40952c2023-06-15 18:46:43 +08009538 int res;
developer72fb0bb2023-01-11 09:46:29 +08009539
developera3511852023-06-14 14:12:59 +08009540 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009541
developera3511852023-06-14 14:12:59 +08009542 if(!IP_output || !Port_output || !RadiusSecret_output)
9543 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009544
developera3511852023-06-14 14:12:59 +08009545 // Read the second matched config
developere40952c2023-06-15 18:46:43 +08009546 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9547 if (os_snprintf_error(sizeof(config_file), res)) {
9548 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9549 return RETURN_ERR;
9550 }
9551
developera3511852023-06-14 14:12:59 +08009552 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9553 _syscmd(cmd, buf, sizeof(buf));
9554 strncpy(IP_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +08009555
developera3511852023-06-14 14:12:59 +08009556 memset(buf, 0, sizeof(buf));
9557 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9558 _syscmd(cmd, buf, sizeof(buf));
9559 *Port_output = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08009560
developera3511852023-06-14 14:12:59 +08009561 memset(buf, 0, sizeof(buf));
9562 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9563 _syscmd(cmd, buf, sizeof(buf));
9564 strncpy(RadiusSecret_output, buf, 64);
developer72fb0bb2023-01-11 09:46:29 +08009565
developera3511852023-06-14 14:12:59 +08009566 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9567 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009568}
9569
9570INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
9571{
developera3511852023-06-14 14:12:59 +08009572 char config_file[64] = {0};
9573 char port_str[8] = {0};
9574 char cmd[256] = {0};
9575 char buf[128] = {0};
9576 int res;
developer72fb0bb2023-01-11 09:46:29 +08009577
developera3511852023-06-14 14:12:59 +08009578 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009579
developere5750452023-05-15 16:46:42 +08009580 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
developera3511852023-06-14 14:12:59 +08009581 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +08009582
developera3511852023-06-14 14:12:59 +08009583 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
9584 return RETURN_ERR;
developere5750452023-05-15 16:46:42 +08009585
developera3511852023-06-14 14:12:59 +08009586 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9587 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +08009588 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9589 return RETURN_ERR;
9590 }
developer72fb0bb2023-01-11 09:46:29 +08009591
developera3511852023-06-14 14:12:59 +08009592 res = snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
9593 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +08009594 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9595 return RETURN_ERR;
9596 }
developera3511852023-06-14 14:12:59 +08009597 _syscmd(cmd, buf, sizeof(buf));
9598 memset(cmd, 0, sizeof(cmd));
developer72fb0bb2023-01-11 09:46:29 +08009599
developera3511852023-06-14 14:12:59 +08009600 res = snprintf(port_str, sizeof(port_str), "%d", port);
9601 if (os_snprintf_error(sizeof(port_str), res)) {
developer46506162023-06-12 10:09:39 +08009602 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9603 return RETURN_ERR;
9604 }
developera3511852023-06-14 14:12:59 +08009605 if (strlen(buf) == 0) {
9606 // Append
9607 res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
9608 "auth_server_addr=%s\\n"
9609 "auth_server_port=%s\\n"
9610 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
9611 if (os_snprintf_error(sizeof(cmd), res)) {
9612 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9613 return RETURN_ERR;
9614 }
9615 } else {
9616 // Delete the three lines setting after the "# radius 2" comment
9617 res = snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
9618 if (os_snprintf_error(sizeof(cmd), res)) {
9619 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9620 return RETURN_ERR;
9621 }
9622 _syscmd(cmd, buf, sizeof(buf));
9623 memset(cmd, 0, sizeof(cmd));
9624 // Use "# radius 2" comment to find the location to insert the radius setting
9625 res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
9626 "# radius 2\\n"
9627 "auth_server_addr=%s\\n"
9628 "auth_server_port=%s\\n"
9629 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9630 if (os_snprintf_error(sizeof(cmd), res)) {
9631 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9632 return RETURN_ERR;
9633 }
9634 }
9635 if(_syscmd(cmd, buf, sizeof(buf))) {
9636 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9637 return RETURN_ERR;
9638 }
developer72fb0bb2023-01-11 09:46:29 +08009639
developera3511852023-06-14 14:12:59 +08009640 wifi_reloadAp(apIndex);
9641 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9642 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009643}
9644
9645//RadiusSettings
9646INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
9647{
developera3511852023-06-14 14:12:59 +08009648 if(!output)
9649 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009650
developera3511852023-06-14 14:12:59 +08009651 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
9652 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
9653 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
9654 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
9655 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
9656 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.
9657 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
9658 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
9659 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 +08009660 //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 +08009661
developera3511852023-06-14 14:12:59 +08009662 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009663}
9664
9665INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
9666{
developera3511852023-06-14 14:12:59 +08009667 //store the paramters, and apply instantly
9668 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009669}
9670
9671//Device.WiFi.AccessPoint.{i}.WPS.Enable
9672//Enables or disables WPS functionality for this access point.
9673// outputs the WPS enable state of this ap in output_bool
9674INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
9675{
developera3511852023-06-14 14:12:59 +08009676 char interface_name[16] = {0};
9677 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0};
9678 if(!output_bool)
9679 return RETURN_ERR;
9680 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9681 return RETURN_ERR;
9682 sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name);
9683 _syscmd(cmd, buf, sizeof(buf));
9684 if(strstr(buf, "configured"))
9685 *output_bool=TRUE;
9686 else
9687 *output_bool=FALSE;
developer72fb0bb2023-01-11 09:46:29 +08009688
developera3511852023-06-14 14:12:59 +08009689 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08009690}
developer72fb0bb2023-01-11 09:46:29 +08009691
9692//Device.WiFi.AccessPoint.{i}.WPS.Enable
9693// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
9694INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
9695{
developera3511852023-06-14 14:12:59 +08009696 char config_file[MAX_BUF_SIZE] = {0};
9697 char buf[128] = {0};
9698 struct params params;
developere40952c2023-06-15 18:46:43 +08009699 int res;
developer72fb0bb2023-01-11 09:46:29 +08009700
developera3511852023-06-14 14:12:59 +08009701 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9702 //store the paramters, and wait for wifi up to apply
9703 params.name = "wps_state";
9704 if (enable == TRUE) {
9705 wifi_getApBeaconType(apIndex, buf);
9706 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
9707 params.value = "1";
9708 else // If ap set encryption
9709 params.value = "2";
9710 } else {
9711 params.value = "0";
9712 }
developer72fb0bb2023-01-11 09:46:29 +08009713
developere40952c2023-06-15 18:46:43 +08009714 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9715 if (os_snprintf_error(sizeof(config_file), res)) {
9716 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9717 return RETURN_ERR;
9718 }
developera3511852023-06-14 14:12:59 +08009719 wifi_hostapdWrite(config_file, &params, 1);
9720 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9721 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08009722
developera3511852023-06-14 14:12:59 +08009723 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9724 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009725}
9726
9727//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
9728INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
9729{
developere40952c2023-06-15 18:46:43 +08009730 int res;
developera3511852023-06-14 14:12:59 +08009731 if(!output)
9732 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009733 res = snprintf(output, 128, "PushButton,PIN");
9734 if (os_snprintf_error(128, res)) {
9735 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9736 return RETURN_ERR;
9737 }
9738
developera3511852023-06-14 14:12:59 +08009739 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009740}
9741
9742//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9743//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.
9744// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
9745INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
9746{
developere40952c2023-06-15 18:46:43 +08009747 int res;
developera3511852023-06-14 14:12:59 +08009748 if(!output)
9749 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009750 res = snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
9751 if (os_snprintf_error(64, res)) {
9752 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9753 return RETURN_ERR;
9754 }
developer72fb0bb2023-01-11 09:46:29 +08009755
developera3511852023-06-14 14:12:59 +08009756 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009757}
9758
9759//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9760// 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
9761INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
9762{
developera3511852023-06-14 14:12:59 +08009763 //apply instantly. No setting need to be stored.
9764 char methods[MAX_BUF_SIZE], *token, *next_token;
9765 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
9766 struct params params;
developere40952c2023-06-15 18:46:43 +08009767 int res;
developer72fb0bb2023-01-11 09:46:29 +08009768
developera3511852023-06-14 14:12:59 +08009769 if(!methodString)
9770 return RETURN_ERR;
9771 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9772 //store the paramters, and wait for wifi up to apply
developer72fb0bb2023-01-11 09:46:29 +08009773
developere40952c2023-06-15 18:46:43 +08009774 res = snprintf(methods, sizeof(methods), "%s", methodString);
9775 if (os_snprintf_error(sizeof(methods), res)) {
9776 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9777 return RETURN_ERR;
9778 }
developera3511852023-06-14 14:12:59 +08009779 for(token=methods; *token; token=next_token) {
9780 strtok_r(token, ",", &next_token);
9781 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
developere40952c2023-06-15 18:46:43 +08009782 res = snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
developera3511852023-06-14 14:12:59 +08009783 else if(*token=='E')
9784 {
9785 if(!strcmp(methods, "Ethernet"))
developere40952c2023-06-15 18:46:43 +08009786 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
developera3511852023-06-14 14:12:59 +08009787 else if(!strcmp(methods, "ExternalNFCToken"))
developere40952c2023-06-15 18:46:43 +08009788 res = snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
developera3511852023-06-14 14:12:59 +08009789 else
9790 printf("%s: Unknown WpsConfigMethod\n", __func__);
9791 }
9792 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
developere40952c2023-06-15 18:46:43 +08009793 res = snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
developera3511852023-06-14 14:12:59 +08009794 else if(*token=='N' && !strcmp(token, "NFCInterface"))
developere40952c2023-06-15 18:46:43 +08009795 res = snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
developera3511852023-06-14 14:12:59 +08009796 else if(*token=='P' )
9797 {
9798 if(!strcmp(token, "PushButton"))
developere40952c2023-06-15 18:46:43 +08009799 res = snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developera3511852023-06-14 14:12:59 +08009800 else if(!strcmp(token, "PIN"))
developere40952c2023-06-15 18:46:43 +08009801 res = snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
developera3511852023-06-14 14:12:59 +08009802 else
9803 printf("%s: Unknown WpsConfigMethod\n", __func__);
9804 }
9805 else
9806 printf("%s: Unknown WpsConfigMethod\n", __func__);
9807 }
developere40952c2023-06-15 18:46:43 +08009808 if (os_snprintf_error(sizeof(config_methods), res)) {
9809 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9810 return RETURN_ERR;
9811 }
9812
developera3511852023-06-14 14:12:59 +08009813 params.name = "config_methods";
9814 params.value = config_methods;
developere40952c2023-06-15 18:46:43 +08009815 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9816 if (os_snprintf_error(sizeof(config_file), res)) {
9817 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9818 return RETURN_ERR;
9819 }
developera3511852023-06-14 14:12:59 +08009820 wifi_hostapdWrite(config_file, &params, 1);
9821 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9822 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009823
developera3511852023-06-14 14:12:59 +08009824 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009825}
9826
9827// outputs the pin value, ulong_pin must be allocated by the caller
9828INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
9829{
developera3511852023-06-14 14:12:59 +08009830 char buf[MAX_BUF_SIZE] = {0};
9831 char cmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +08009832 int res;
developer72fb0bb2023-01-11 09:46:29 +08009833
developera3511852023-06-14 14:12:59 +08009834 if(!output_ulong)
9835 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009836 res = snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
9837 if (os_snprintf_error(sizeof(cmd), res)) {
9838 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9839 return RETURN_ERR;
9840 }
developera3511852023-06-14 14:12:59 +08009841 _syscmd(cmd, buf, sizeof(buf));
9842 if(strlen(buf) > 0)
9843 *output_ulong=strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +08009844
developera3511852023-06-14 14:12:59 +08009845 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009846}
9847
9848// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
9849INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
9850{
developera3511852023-06-14 14:12:59 +08009851 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
9852 char ap_pin[16] = {0};
9853 char config_file[MAX_BUF_SIZE] = {0};
9854 struct params params;
developere40952c2023-06-15 18:46:43 +08009855 int res;
developer72fb0bb2023-01-11 09:46:29 +08009856
developera3511852023-06-14 14:12:59 +08009857 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +08009858 res = snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
9859 if (os_snprintf_error(sizeof(ap_pin), res)) {
9860 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9861 return RETURN_ERR;
9862 }
developera3511852023-06-14 14:12:59 +08009863 params.name = "ap_pin";
9864 params.value = ap_pin;
developere40952c2023-06-15 18:46:43 +08009865 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9866 if (os_snprintf_error(sizeof(config_file), res)) {
9867 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9868 return RETURN_ERR;
9869 }
developera3511852023-06-14 14:12:59 +08009870 wifi_hostapdWrite(config_file, &params, 1);
9871 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9872 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009873
developera3511852023-06-14 14:12:59 +08009874 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009875}
9876
9877// Output string is either Not configured or Configured, max 32 characters
9878INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
9879{
developera3511852023-06-14 14:12:59 +08009880 char interface_name[16] = {0};
9881 char cmd[MAX_CMD_SIZE];
9882 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +08009883 int res;
developer72fb0bb2023-01-11 09:46:29 +08009884
developera3511852023-06-14 14:12:59 +08009885 if(!output_string)
9886 return RETURN_ERR;
9887 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developere40952c2023-06-15 18:46:43 +08009888 res = snprintf(output_string, 32, "Not configured");
9889 if (os_snprintf_error(32, res)) {
9890 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9891 return RETURN_ERR;
9892 }
developera3511852023-06-14 14:12:59 +08009893 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9894 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009895 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
9896 if (os_snprintf_error(sizeof(cmd), res)) {
9897 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9898 return RETURN_ERR;
9899 }
developera3511852023-06-14 14:12:59 +08009900 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009901
developera3511852023-06-14 14:12:59 +08009902 if(!strncmp(buf, "configured", 10))
developere40952c2023-06-15 18:46:43 +08009903 res = snprintf(output_string, 32, "Configured");
developera3511852023-06-14 14:12:59 +08009904 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009905
developera3511852023-06-14 14:12:59 +08009906 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009907}
9908
9909// sets the WPS pin for this AP
9910INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
9911{
developera3511852023-06-14 14:12:59 +08009912 char interface_name[16] = {0};
9913 char cmd[MAX_CMD_SIZE];
9914 char buf[MAX_BUF_SIZE]={0};
9915 BOOL enable;
developere40952c2023-06-15 18:46:43 +08009916 int res;
developer72fb0bb2023-01-11 09:46:29 +08009917
developera3511852023-06-14 14:12:59 +08009918 wifi_getApEnable(apIndex, &enable);
9919 if (!enable)
9920 return RETURN_ERR;
9921 wifi_getApWpsEnable(apIndex, &enable);
9922 if (!enable)
9923 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009924
developera3511852023-06-14 14:12:59 +08009925 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9926 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009927 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
9928 if (os_snprintf_error(sizeof(cmd), res)) {
9929 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9930 return RETURN_ERR;
9931 }
developera3511852023-06-14 14:12:59 +08009932 _syscmd(cmd, buf, sizeof(buf));
9933 if((strstr(buf, "OK"))!=NULL)
9934 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009935
developera3511852023-06-14 14:12:59 +08009936 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009937}
9938
9939// This function is called when the WPS push button has been pressed for this AP
9940INT wifi_setApWpsButtonPush(INT apIndex)
9941{
developera3511852023-06-14 14:12:59 +08009942 char cmd[MAX_CMD_SIZE];
9943 char buf[MAX_BUF_SIZE]={0};
9944 char interface_name[16] = {0};
9945 BOOL enable=FALSE;
developere40952c2023-06-15 18:46:43 +08009946 int res;
developer72fb0bb2023-01-11 09:46:29 +08009947
developera3511852023-06-14 14:12:59 +08009948 wifi_getApEnable(apIndex, &enable);
9949 if (!enable)
9950 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009951
developera3511852023-06-14 14:12:59 +08009952 wifi_getApWpsEnable(apIndex, &enable);
9953 if (!enable)
9954 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009955
developera3511852023-06-14 14:12:59 +08009956 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9957 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009958
developere40952c2023-06-15 18:46:43 +08009959 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
9960 if (os_snprintf_error(sizeof(cmd), res)) {
9961 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9962 return RETURN_ERR;
9963 }
developera3511852023-06-14 14:12:59 +08009964 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009965
developera3511852023-06-14 14:12:59 +08009966 if((strstr(buf, "OK"))!=NULL)
9967 return RETURN_OK;
9968 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009969}
9970
9971// cancels WPS mode for this AP
9972INT wifi_cancelApWPS(INT apIndex)
9973{
developera3511852023-06-14 14:12:59 +08009974 char interface_name[16] = {0};
9975 char cmd[MAX_CMD_SIZE];
9976 char buf[MAX_BUF_SIZE]={0};
developere40952c2023-06-15 18:46:43 +08009977 int res;
developer72fb0bb2023-01-11 09:46:29 +08009978
developera3511852023-06-14 14:12:59 +08009979 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9980 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +08009981 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
9982 if (os_snprintf_error(sizeof(cmd), res)) {
9983 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
9984 return RETURN_ERR;
9985 }
developera3511852023-06-14 14:12:59 +08009986 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08009987
developera3511852023-06-14 14:12:59 +08009988 if((strstr(buf, "OK"))!=NULL)
9989 return RETURN_OK;
9990 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08009991}
9992
9993//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
9994//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
9995INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
9996{
developera3511852023-06-14 14:12:59 +08009997 char interface_name[16] = {0};
9998 FILE *f = NULL;
9999 int read_flag=0, auth_temp=0, mac_temp=0;
10000 char cmd[256] = {0}, buf[2048] = {0};
10001 char *param = NULL, *value = NULL, *line=NULL;
10002 size_t len = 0;
10003 wifi_associated_dev_t *dev=NULL;
10004 int res;
developer72fb0bb2023-01-11 09:46:29 +080010005
developera3511852023-06-14 14:12:59 +080010006 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10007 *associated_dev_array = NULL;
10008 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10009 return RETURN_ERR;
10010 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
10011 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080010012 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10013 return RETURN_ERR;
10014 }
developera3511852023-06-14 14:12:59 +080010015 _syscmd(cmd,buf,sizeof(buf));
10016 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080010017
developera3511852023-06-14 14:12:59 +080010018 if (*output_array_size <= 0)
10019 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010020
developera3511852023-06-14 14:12:59 +080010021 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
10022 *associated_dev_array = dev;
10023 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
10024 if (os_snprintf_error(sizeof(cmd), res)) {
developer46506162023-06-12 10:09:39 +080010025 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10026 return RETURN_ERR;
10027 }
developera3511852023-06-14 14:12:59 +080010028 _syscmd(cmd,buf,sizeof(buf));
10029 f = fopen("/tmp/connected_devices.txt", "r");
10030 if (f==NULL)
10031 {
10032 *output_array_size=0;
10033 return RETURN_ERR;
10034 }
10035 while ((getline(&line, &len, f)) != -1)
10036 {
10037 param = strtok(line,"=");
10038 value = strtok(NULL,"=");
developer72fb0bb2023-01-11 09:46:29 +080010039
developera3511852023-06-14 14:12:59 +080010040 if( strcmp("flags",param) == 0 )
10041 {
10042 value[strlen(value)-1]='\0';
10043 if(strstr (value,"AUTHORIZED") != NULL )
10044 {
10045 dev[auth_temp].cli_AuthenticationState = 1;
10046 dev[auth_temp].cli_Active = 1;
10047 auth_temp++;
10048 read_flag=1;
10049 }
10050 }
10051 if(read_flag==1)
10052 {
10053 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
10054 {
10055 value[strlen(value)-1]='\0';
10056 sscanf(value, "%x:%x:%x:%x:%x:%x",
10057 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
10058 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
10059 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
10060 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
10061 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
10062 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
10063 mac_temp++;
10064 read_flag=0;
10065 }
10066 }
10067 }
10068 *output_array_size = auth_temp;
10069 auth_temp=0;
10070 mac_temp=0;
10071 free(line);
10072 fclose(f);
10073 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10074 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010075}
10076
10077#define MACADDRESS_SIZE 6
10078
10079INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10080{
developera3511852023-06-14 14:12:59 +080010081 FILE *fp = NULL;
10082 char str[MAX_BUF_SIZE] = {0};
10083 int wificlientindex = 0 ;
10084 int count = 0;
10085 int signalstrength = 0;
10086 int arr[MACADDRESS_SIZE] = {0};
10087 unsigned char mac[MACADDRESS_SIZE] = {0};
10088 UINT wifi_count = 0;
10089 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080010090 int res;
developer72fb0bb2023-01-11 09:46:29 +080010091
developera3511852023-06-14 14:12:59 +080010092 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10093 *output_array_size = 0;
10094 *associated_dev_array = NULL;
developer72fb0bb2023-01-11 09:46:29 +080010095
developera3511852023-06-14 14:12:59 +080010096 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
10097 fp = popen(pipeCmd, "r");
10098 if (fp == NULL)
10099 {
10100 printf("Failed to run command inside function %s\n",__FUNCTION__ );
10101 return RETURN_ERR;
10102 }
developer72fb0bb2023-01-11 09:46:29 +080010103
developera3511852023-06-14 14:12:59 +080010104 /* Read the output a line at a time - output it. */
10105 fgets(str, sizeof(str)-1, fp);
10106 wifi_count = (unsigned int) atoi ( str );
10107 *output_array_size = wifi_count;
10108 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
10109 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080010110
developera3511852023-06-14 14:12:59 +080010111 if(wifi_count == 0)
10112 {
10113 return RETURN_OK;
10114 }
10115 else
10116 {
10117 wifi_associated_dev3_t* temp = NULL;
10118 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
10119 if(temp == NULL)
10120 {
10121 printf("Error Statement. Insufficient memory \n");
10122 return RETURN_ERR;
10123 }
developer72fb0bb2023-01-11 09:46:29 +080010124
developere40952c2023-06-15 18:46:43 +080010125 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
10126 if (os_snprintf_error(sizeof(pipeCmd), res)) {
10127 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10128 return RETURN_ERR;
10129 }
developera3511852023-06-14 14:12:59 +080010130 system(pipeCmd);
10131 memset(pipeCmd,0,sizeof(pipeCmd));
10132 if(apIndex == 0)
developere40952c2023-06-15 18:46:43 +080010133 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 +080010134 else if(apIndex == 1)
developere40952c2023-06-15 18:46:43 +080010135 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
10136 if (os_snprintf_error(sizeof(pipeCmd), res)) {
10137 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10138 return RETURN_ERR;
10139 }
developera3511852023-06-14 14:12:59 +080010140 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080010141
developera3511852023-06-14 14:12:59 +080010142 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
10143 if(fp == NULL)
10144 {
10145 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
10146 free(temp);
10147 return RETURN_ERR;
10148 }
10149 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080010150
developera3511852023-06-14 14:12:59 +080010151 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
10152 fp = popen(pipeCmd, "r");
10153 if(fp)
10154 {
10155 for(count =0 ; count < wifi_count; count++)
10156 {
10157 fgets(str, MAX_BUF_SIZE, fp);
10158 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10159 {
10160 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10161 {
10162 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080010163
developera3511852023-06-14 14:12:59 +080010164 }
10165 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10166 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]);
10167 }
10168 temp[count].cli_AuthenticationState = 1; //TODO
10169 temp[count].cli_Active = 1; //TODO
10170 }
10171 pclose(fp);
10172 }
developer72fb0bb2023-01-11 09:46:29 +080010173
developera3511852023-06-14 14:12:59 +080010174 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
10175 fp = popen(pipeCmd, "r");
10176 if(fp)
10177 {
10178 pclose(fp);
10179 }
10180 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
10181 if(fp)
10182 {
10183 for(count =0 ; count < wifi_count ;count++)
10184 {
10185 fgets(str, MAX_BUF_SIZE, fp);
10186 signalstrength = atoi(str);
10187 temp[count].cli_SignalStrength = signalstrength;
10188 temp[count].cli_RSSI = signalstrength;
10189 temp[count].cli_SNR = signalstrength + 95;
10190 }
10191 pclose(fp);
10192 }
developer72fb0bb2023-01-11 09:46:29 +080010193
10194
developera3511852023-06-14 14:12:59 +080010195 if((apIndex == 0) || (apIndex == 4))
10196 {
10197 for(count =0 ; count < wifi_count ;count++)
10198 {
10199 strcpy(temp[count].cli_OperatingStandard,"g");
10200 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
10201 }
developer72fb0bb2023-01-11 09:46:29 +080010202
developera3511852023-06-14 14:12:59 +080010203 //BytesSent
10204 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
10205 fp = popen(pipeCmd, "r");
10206 if(fp)
10207 {
10208 pclose(fp);
10209 }
10210 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
10211 if(fp)
10212 {
10213 for (count = 0; count < wifi_count; count++)
10214 {
10215 fgets(str, MAX_BUF_SIZE, fp);
10216 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
10217 }
10218 pclose(fp);
10219 }
developer72fb0bb2023-01-11 09:46:29 +080010220
developera3511852023-06-14 14:12:59 +080010221 //BytesReceived
10222 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
10223 fp = popen(pipeCmd, "r");
10224 if (fp)
10225 {
10226 pclose(fp);
10227 }
10228 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
10229 if (fp)
10230 {
10231 for (count = 0; count < wifi_count; count++)
10232 {
10233 fgets(str, MAX_BUF_SIZE, fp);
10234 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
10235 }
10236 pclose(fp);
10237 }
developer72fb0bb2023-01-11 09:46:29 +080010238
developera3511852023-06-14 14:12:59 +080010239 //PacketsSent
10240 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
10241 fp = popen(pipeCmd, "r");
10242 if (fp)
10243 {
10244 pclose(fp);
10245 }
developer72fb0bb2023-01-11 09:46:29 +080010246
developera3511852023-06-14 14:12:59 +080010247 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
10248 if (fp)
10249 {
10250 for (count = 0; count < wifi_count; count++)
10251 {
10252 fgets(str, MAX_BUF_SIZE, fp);
10253 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
10254 }
10255 pclose(fp);
10256 }
developer72fb0bb2023-01-11 09:46:29 +080010257
developera3511852023-06-14 14:12:59 +080010258 //PacketsReceived
10259 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
10260 fp = popen(pipeCmd, "r");
10261 if (fp)
10262 {
10263 pclose(fp);
10264 }
10265 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
10266 if (fp)
10267 {
10268 for (count = 0; count < wifi_count; count++)
10269 {
10270 fgets(str, MAX_BUF_SIZE, fp);
10271 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
10272 }
10273 pclose(fp);
10274 }
developer72fb0bb2023-01-11 09:46:29 +080010275
developera3511852023-06-14 14:12:59 +080010276 //ErrorsSent
10277 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
10278 fp = popen(pipeCmd, "r");
10279 if (fp)
10280 {
10281 pclose(fp);
10282 }
10283 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
10284 if (fp)
10285 {
10286 for (count = 0; count < wifi_count; count++)
10287 {
10288 fgets(str, MAX_BUF_SIZE, fp);
10289 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
10290 }
10291 pclose(fp);
10292 }
developer72fb0bb2023-01-11 09:46:29 +080010293
developera3511852023-06-14 14:12:59 +080010294 //ErrorsSent
10295 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
10296 fp = popen(pipeCmd, "r");
10297 if (fp)
10298 {
10299 pclose(fp);
10300 }
10301 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
10302 if (fp)
10303 {
10304 for (count = 0; count < wifi_count; count++)
10305 {
10306 fgets(str, MAX_BUF_SIZE, fp);
10307 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
10308 }
10309 pclose(fp);
10310 }
developer72fb0bb2023-01-11 09:46:29 +080010311
developera3511852023-06-14 14:12:59 +080010312 //LastDataDownlinkRate
10313 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
10314 fp = popen(pipeCmd, "r");
10315 if (fp)
10316 {
10317 pclose(fp);
10318 }
10319 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
10320 if (fp)
10321 {
10322 for (count = 0; count < wifi_count; count++)
10323 {
10324 fgets(str, MAX_BUF_SIZE, fp);
10325 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
10326 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
10327 }
10328 pclose(fp);
10329 }
developer72fb0bb2023-01-11 09:46:29 +080010330
developera3511852023-06-14 14:12:59 +080010331 //LastDataUplinkRate
10332 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
10333 fp = popen(pipeCmd, "r");
10334 if (fp)
10335 {
10336 pclose(fp);
10337 }
10338 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
10339 if (fp)
10340 {
10341 for (count = 0; count < wifi_count; count++)
10342 {
10343 fgets(str, MAX_BUF_SIZE, fp);
10344 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
10345 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
10346 }
10347 pclose(fp);
10348 }
developer72fb0bb2023-01-11 09:46:29 +080010349
developera3511852023-06-14 14:12:59 +080010350 }
10351 else if ((apIndex == 1) || (apIndex == 5))
10352 {
10353 for (count = 0; count < wifi_count; count++)
10354 {
10355 strcpy(temp[count].cli_OperatingStandard, "a");
10356 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
10357 temp[count].cli_BytesSent = 0;
10358 temp[count].cli_BytesReceived = 0;
10359 temp[count].cli_LastDataUplinkRate = 0;
10360 temp[count].cli_LastDataDownlinkRate = 0;
10361 temp[count].cli_PacketsSent = 0;
10362 temp[count].cli_PacketsReceived = 0;
10363 temp[count].cli_ErrorsSent = 0;
10364 }
10365 }
developer72fb0bb2023-01-11 09:46:29 +080010366
developera3511852023-06-14 14:12:59 +080010367 for (count = 0; count < wifi_count; count++)
10368 {
10369 temp[count].cli_Retransmissions = 0;
10370 temp[count].cli_DataFramesSentAck = 0;
10371 temp[count].cli_DataFramesSentNoAck = 0;
10372 temp[count].cli_MinRSSI = 0;
10373 temp[count].cli_MaxRSSI = 0;
10374 strncpy(temp[count].cli_InterferenceSources, "", 64);
10375 memset(temp[count].cli_IPAddress, 0, 64);
10376 temp[count].cli_RetransCount = 0;
10377 temp[count].cli_FailedRetransCount = 0;
10378 temp[count].cli_RetryCount = 0;
10379 temp[count].cli_MultipleRetryCount = 0;
10380 }
10381 *associated_dev_array = temp;
10382 }
10383 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10384 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010385}
10386
developer7e4a2a62023-04-06 19:56:03 +080010387int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +080010388{
developera3511852023-06-14 14:12:59 +080010389 char cmd[MAX_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +080010390 char buf[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080010391 int res;
developer72fb0bb2023-01-11 09:46:29 +080010392
developera3511852023-06-14 14:12:59 +080010393 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080010394
developere40952c2023-06-15 18:46:43 +080010395 res = snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
developer7e4a2a62023-04-06 19:56:03 +080010396 interface_name);
developere40952c2023-06-15 18:46:43 +080010397 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
10398 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10399 return RETURN_ERR;
10400 }
10401
developera3511852023-06-14 14:12:59 +080010402 _syscmd(cmd, buf, MAX_BUF_SIZE);
developer7e4a2a62023-04-06 19:56:03 +080010403
developera3511852023-06-14 14:12:59 +080010404 strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */
developer72fb0bb2023-01-11 09:46:29 +080010405
developera3511852023-06-14 14:12:59 +080010406 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10407 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010408}
10409
developer72fb0bb2023-01-11 09:46:29 +080010410static const char *get_line_from_str_buf(const char *buf, char *line)
10411{
developera3511852023-06-14 14:12:59 +080010412 int i;
10413 int n = strlen(buf);
developer72fb0bb2023-01-11 09:46:29 +080010414
developera3511852023-06-14 14:12:59 +080010415 for (i = 0; i < n; i++) {
10416 line[i] = buf[i];
10417 if (buf[i] == '\n') {
10418 line[i] = '\0';
10419 return &buf[i + 1];
10420 }
10421 }
developer72fb0bb2023-01-11 09:46:29 +080010422
developera3511852023-06-14 14:12:59 +080010423 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080010424}
10425
10426INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10427{
developera3511852023-06-14 14:12:59 +080010428 char interface_name[16] = {0};
10429 FILE *f = NULL;
10430 int auth_temp= -1;
10431 char cmd[256] = {0}, buf[2048] = {0};
10432 char *param = NULL, *value = NULL, *line=NULL;
10433 size_t len = 0;
10434 wifi_associated_dev3_t *dev=NULL;
developer72fb0bb2023-01-11 09:46:29 +080010435
developera3511852023-06-14 14:12:59 +080010436 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10437 *associated_dev_array = NULL;
10438 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10439 return RETURN_ERR;
10440 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
10441 _syscmd(cmd, buf, sizeof(buf));
10442 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080010443
developera3511852023-06-14 14:12:59 +080010444 if (*output_array_size <= 0)
10445 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010446
developera3511852023-06-14 14:12:59 +080010447 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10448 *associated_dev_array = dev;
10449 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
10450 _syscmd(cmd,buf,sizeof(buf));
10451 f = fopen("/tmp/diagnostic3_devices.txt", "r");
10452 if (f == NULL)
10453 {
10454 *output_array_size=0;
10455 return RETURN_ERR;
10456 }
10457 while ((getline(&line, &len, f)) != -1)
10458 {
10459 param = strtok(line, "=");
10460 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +080010461
developera3511852023-06-14 14:12:59 +080010462 if( strcmp("flags",param) == 0 )
10463 {
10464 value[strlen(value)-1]='\0';
10465 if(strstr (value,"AUTHORIZED") != NULL )
10466 {
10467 auth_temp++;
10468 dev[auth_temp].cli_AuthenticationState = 1;
10469 dev[auth_temp].cli_Active = 1;
10470 }
10471 } else if (auth_temp < 0) {
10472 continue;
10473 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
10474 {
10475 value[strlen(value)-1]='\0';
10476 sscanf(value, "%x:%x:%x:%x:%x:%x",
10477 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
10478 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
10479 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
10480 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
10481 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
10482 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
10483 } else if (strcmp("signal", param) == 0) {
10484 value[strlen(value)-1]='\0';
10485 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
10486 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
10487 }
10488 }
developer0d26f2c2023-05-25 19:46:36 +080010489 if (line)
developera3511852023-06-14 14:12:59 +080010490 free(line);
10491 fclose(f);
10492 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10493 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010494}
developer72fb0bb2023-01-11 09:46:29 +080010495
10496/* getIPAddress function */
10497/**
10498* @description Returning IpAddress of the Matched String
10499*
developer69b61b02023-03-07 17:17:44 +080010500* @param
developer72fb0bb2023-01-11 09:46:29 +080010501* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080010502* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080010503* @return The status of the operation
10504* @retval RETURN_OK if successful
10505* @retval RETURN_ERR if any error is detected
10506*
10507*/
10508
10509INT getIPAddress(char *str,char *ipaddr)
10510{
developera3511852023-06-14 14:12:59 +080010511 FILE *fp = NULL;
10512 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
10513 int LeaseTime = 0,ret = 0;
10514 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
10515 {
10516 return RETURN_ERR;
10517 }
developer72fb0bb2023-01-11 09:46:29 +080010518
developera3511852023-06-14 14:12:59 +080010519 while ( fgets(buf, sizeof(buf), fp)!= NULL )
10520 {
10521 /*
10522 Sample:sss
10523 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
10524 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
10525 */
10526 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
10527 &(LeaseTime),
10528 phyAddr,
10529 ipAddr,
10530 hostName
10531 );
10532 if(ret != 4)
10533 continue;
10534 if(strcmp(str,phyAddr) == 0)
10535 strcpy(ipaddr,ipAddr);
10536 }
10537 fclose(fp);
10538 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010539}
10540
10541/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
10542/**
10543* @description Returning Inactive wireless connected clients informations
10544*
developer69b61b02023-03-07 17:17:44 +080010545* @param
developer72fb0bb2023-01-11 09:46:29 +080010546* @filename Holding private_wifi 2g/5g content files
10547* @associated_dev_array Having inactiv wireless clients informations
10548* @output_array_size Returning Inactive wireless counts
10549* @return The status of the operation
10550* @retval RETURN_OK if successful
10551* @retval RETURN_ERR if any error is detected
10552*
10553*/
10554
10555INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10556{
developera3511852023-06-14 14:12:59 +080010557 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10558 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
10559 FILE *fp = NULL;
10560 int arr[MACADDRESS_SIZE] = {0};
10561 unsigned char mac[MACADDRESS_SIZE] = {0};
10562 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
10563 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
10564 fp = popen(buf,"r");
10565 if(fp == NULL)
10566 return RETURN_ERR;
10567 else
10568 {
10569 fgets(path,sizeof(path),fp);
10570 maccount = atoi(path);
10571 }
10572 pclose(fp);
10573 *output_array_size = maccount;
10574 wifi_associated_dev3_t* temp = NULL;
10575 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10576 *associated_dev_array = temp;
10577 if(temp == NULL)
10578 {
10579 printf("Error Statement. Insufficient memory \n");
10580 return RETURN_ERR;
10581 }
10582 memset(buf,0,sizeof(buf));
10583 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
10584 fp = popen(buf,"r");
10585 if (fp == NULL) {
10586 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
10587 return RETURN_ERR;
10588 }
10589 for(count = 0; count < maccount ; count++)
10590 {
10591 fgets(path,sizeof(path),fp);
10592 for(i = 0; path[i]!='\n';i++)
10593 str[i]=path[i];
10594 str[i]='\0';
10595 getIPAddress(str,ipaddr);
10596 memset(buf,0,sizeof(buf));
10597 if(strlen(ipaddr) > 0)
10598 {
10599 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
10600 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
10601 {
10602 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10603 {
10604 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10605 {
10606 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080010607
developera3511852023-06-14 14:12:59 +080010608 }
10609 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10610 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]);
10611 }
10612 temp[count].cli_AuthenticationState = 0; //TODO
10613 temp[count].cli_Active = 0; //TODO
10614 temp[count].cli_SignalStrength = 0;
10615 }
10616 else //Active wireless clients info
10617 {
10618 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10619 {
10620 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10621 {
10622 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080010623
developera3511852023-06-14 14:12:59 +080010624 }
10625 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10626 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]);
10627 }
10628 temp[count].cli_Active = 1;
10629 }
10630 }
10631 memset(ipaddr,0,sizeof(ipaddr));
10632 }
10633 pclose(fp);
10634 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10635 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010636}
10637//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
10638//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
10639//To get Band Steering Capability
10640INT wifi_getBandSteeringCapability(BOOL *support)
10641{
developera3511852023-06-14 14:12:59 +080010642 *support = FALSE;
10643 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010644}
10645
10646
10647//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
10648//To get Band Steering enable status
10649INT wifi_getBandSteeringEnable(BOOL *enable)
10650{
developera3511852023-06-14 14:12:59 +080010651 *enable = FALSE;
10652 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010653}
10654
10655//To turn on/off Band steering
10656INT wifi_setBandSteeringEnable(BOOL enable)
10657{
developera3511852023-06-14 14:12:59 +080010658 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010659}
10660
10661//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
10662//To get Band Steering AP group
10663INT wifi_getBandSteeringApGroup(char *output_ApGroup)
10664{
developera3511852023-06-14 14:12:59 +080010665 if (NULL == output_ApGroup)
10666 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010667
developera3511852023-06-14 14:12:59 +080010668 strcpy(output_ApGroup, "1,2");
10669 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010670}
10671
10672//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
10673//to set and read the band steering BandUtilizationThreshold parameters
10674INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
10675{
developera3511852023-06-14 14:12:59 +080010676 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010677}
10678
10679INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
10680{
developera3511852023-06-14 14:12:59 +080010681 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010682}
10683
10684//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
10685//to set and read the band steering RSSIThreshold parameters
10686INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
10687{
developera3511852023-06-14 14:12:59 +080010688 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010689}
10690
10691INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
10692{
developera3511852023-06-14 14:12:59 +080010693 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010694}
10695
10696
10697//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
10698//to set and read the band steering physical modulation rate threshold parameters
10699INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
10700{
developera3511852023-06-14 14:12:59 +080010701 //If chip is not support, return -1
10702 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010703}
10704
10705INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
10706{
developera3511852023-06-14 14:12:59 +080010707 //If chip is not support, return -1
10708 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010709}
10710
10711//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
10712//to set and read the inactivity time (in seconds) for steering under overload condition
10713INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
10714{
developera3511852023-06-14 14:12:59 +080010715 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010716}
10717
10718INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
10719{
developera3511852023-06-14 14:12:59 +080010720 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010721}
10722
10723//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
10724//to set and read the inactivity time (in seconds) for steering under Idle condition
10725INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
10726{
developera3511852023-06-14 14:12:59 +080010727 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010728}
10729
10730INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
10731{
developera3511852023-06-14 14:12:59 +080010732 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010733}
10734
10735//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
10736//pClientMAC[64]
10737//pSourceSSIDIndex[64]
10738//pDestSSIDIndex[64]
10739//pSteeringReason[256]
10740INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
10741{
developera3511852023-06-14 14:12:59 +080010742 //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
10743 *pSteeringTime=time(NULL);
10744 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
10745 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010746}
10747
10748INT wifi_ifConfigDown(INT apIndex)
10749{
developera3511852023-06-14 14:12:59 +080010750 INT status = RETURN_OK;
10751 char cmd[64];
developere40952c2023-06-15 18:46:43 +080010752 int res;
developer72fb0bb2023-01-11 09:46:29 +080010753
developere40952c2023-06-15 18:46:43 +080010754 res = snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
10755 if (os_snprintf_error(sizeof(cmd), res)) {
10756 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10757 return RETURN_ERR;
10758 }
developera3511852023-06-14 14:12:59 +080010759 printf("%s: %s\n", __func__, cmd);
10760 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080010761
developera3511852023-06-14 14:12:59 +080010762 return status;
developer72fb0bb2023-01-11 09:46:29 +080010763}
10764
10765INT wifi_ifConfigUp(INT apIndex)
10766{
developera3511852023-06-14 14:12:59 +080010767 char interface_name[16] = {0};
10768 char cmd[128];
10769 char buf[1024];
developere40952c2023-06-15 18:46:43 +080010770 int res;
developer72fb0bb2023-01-11 09:46:29 +080010771
developera3511852023-06-14 14:12:59 +080010772 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10773 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010774 res = snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
10775 if (os_snprintf_error(sizeof(cmd), res)) {
10776 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10777 return RETURN_ERR;
10778 }
developera3511852023-06-14 14:12:59 +080010779 _syscmd(cmd, buf, sizeof(buf));
10780 return 0;
developer72fb0bb2023-01-11 09:46:29 +080010781}
10782
10783//>> Deprecated. Replace with wifi_applyRadioSettings
10784INT wifi_pushBridgeInfo(INT apIndex)
10785{
developerb2977562023-05-24 17:54:12 +080010786 char ip[32] = {0};
10787 char subnet[32] = {0};
10788 char bridge[32] = {0};
10789 char cmd[128] = {0};
10790 char buf[1024] = {0};
developere40952c2023-06-15 18:46:43 +080010791 int res;
developer72fb0bb2023-01-11 09:46:29 +080010792
developerb2977562023-05-24 17:54:12 +080010793 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080010794
developere40952c2023-06-15 18:46:43 +080010795 res = snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
10796 if (os_snprintf_error(sizeof(cmd), res)) {
10797 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10798 return RETURN_ERR;
10799 }
developerb2977562023-05-24 17:54:12 +080010800 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010801
developerb2977562023-05-24 17:54:12 +080010802 return 0;
developer72fb0bb2023-01-11 09:46:29 +080010803}
10804
10805INT wifi_pushChannel(INT radioIndex, UINT channel)
10806{
developera3511852023-06-14 14:12:59 +080010807 char interface_name[16] = {0};
10808 char cmd[128];
10809 char buf[1024];
developere40952c2023-06-15 18:46:43 +080010810 int res;
developer72fb0bb2023-01-11 09:46:29 +080010811
developera3511852023-06-14 14:12:59 +080010812 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10813 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080010814 res = snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
10815 if (os_snprintf_error(sizeof(cmd), res)) {
10816 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10817 return RETURN_ERR;
10818 }
developera3511852023-06-14 14:12:59 +080010819 _syscmd(cmd,buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010820
developera3511852023-06-14 14:12:59 +080010821 return 0;
developer72fb0bb2023-01-11 09:46:29 +080010822}
10823
10824INT wifi_pushChannelMode(INT radioIndex)
10825{
developera3511852023-06-14 14:12:59 +080010826 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
10827 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010828}
10829
10830INT wifi_pushDefaultValues(INT radioIndex)
10831{
developera3511852023-06-14 14:12:59 +080010832 //Apply Comcast specified default radio settings instantly
10833 //AMPDU=1
10834 //AMPDUFrames=32
10835 //AMPDULim=50000
10836 //txqueuelen=1000
developer72fb0bb2023-01-11 09:46:29 +080010837
developera3511852023-06-14 14:12:59 +080010838 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010839}
10840
10841INT wifi_pushTxChainMask(INT radioIndex)
10842{
developera3511852023-06-14 14:12:59 +080010843 //Apply default TxChainMask instantly
10844 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010845}
10846
10847INT wifi_pushRxChainMask(INT radioIndex)
10848{
developera3511852023-06-14 14:12:59 +080010849 //Apply default RxChainMask instantly
10850 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010851}
10852
10853INT wifi_pushSSID(INT apIndex, CHAR *ssid)
10854{
developer7e4a2a62023-04-06 19:56:03 +080010855 INT status;
developer72fb0bb2023-01-11 09:46:29 +080010856
developer7e4a2a62023-04-06 19:56:03 +080010857 status = wifi_setSSIDName(apIndex, ssid);
10858 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010859
developer7e4a2a62023-04-06 19:56:03 +080010860 return status;
developer72fb0bb2023-01-11 09:46:29 +080010861}
10862
10863INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
10864{
developera3511852023-06-14 14:12:59 +080010865 int ret;
developerc1aa6532023-06-09 09:37:01 +080010866 ret = wifi_setApSsidAdvertisementEnable(apIndex, enable);
10867
10868 return ret;
developer72fb0bb2023-01-11 09:46:29 +080010869}
10870
10871INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
10872{
developera3511852023-06-14 14:12:59 +080010873 time_t now;
developere82c0ca2023-05-10 16:25:35 +080010874
10875 time(&now);
10876 if (now > radio_up_time[radioIndex])
10877 *output = now - radio_up_time[radioIndex];
10878 else {
10879 *output = 0;
10880 return RETURN_ERR;
10881 }
10882
developera3511852023-06-14 14:12:59 +080010883 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010884}
10885
10886INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
10887{
developera3511852023-06-14 14:12:59 +080010888 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010889}
10890
10891INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
10892{
developera3511852023-06-14 14:12:59 +080010893 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010894}
10895
10896//To-do
10897INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
10898{
developera3511852023-06-14 14:12:59 +080010899 char output[16]={'\0'};
10900 char config_file[MAX_BUF_SIZE] = {0};
10901 int res;
developer72fb0bb2023-01-11 09:46:29 +080010902
developera3511852023-06-14 14:12:59 +080010903 if (!output_string)
10904 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010905
developera3511852023-06-14 14:12:59 +080010906 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
10907 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080010908 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10909 return RETURN_ERR;
10910 }
developera3511852023-06-14 14:12:59 +080010911 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080010912
developera3511852023-06-14 14:12:59 +080010913 if (strlen(output) == 0)
developere40952c2023-06-15 18:46:43 +080010914 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080010915 else if (strncmp(output, "0", 1) == 0)
developere40952c2023-06-15 18:46:43 +080010916 res = snprintf(output_string, 64, "Disabled");
developera3511852023-06-14 14:12:59 +080010917 else if (strncmp(output, "1", 1) == 0)
developere40952c2023-06-15 18:46:43 +080010918 res = snprintf(output_string, 64, "Optional");
developera3511852023-06-14 14:12:59 +080010919 else if (strncmp(output, "2", 1) == 0)
developere40952c2023-06-15 18:46:43 +080010920 res = snprintf(output_string, 64, "Required");
developera3511852023-06-14 14:12:59 +080010921 else {
10922 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
10923 return RETURN_ERR;
10924 }
developere40952c2023-06-15 18:46:43 +080010925 if (os_snprintf_error(64, res)) {
10926 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10927 return RETURN_ERR;
10928 }
developer72fb0bb2023-01-11 09:46:29 +080010929
developera3511852023-06-14 14:12:59 +080010930 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
10931 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010932}
10933INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
10934{
developera3511852023-06-14 14:12:59 +080010935 struct params params;
10936 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010937
developera3511852023-06-14 14:12:59 +080010938 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10939 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
10940 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080010941
developera3511852023-06-14 14:12:59 +080010942 params.name = "ieee80211w";
10943 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
10944 params.value = "0";
10945 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
10946 params.value = "1";
10947 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
10948 params.value = "2";
10949 else{
10950 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
10951 return RETURN_ERR;
10952 }
10953 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10954 wifi_hostapdWrite(config_file, &params, 1);
10955 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10956 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010957}
10958INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
10959{
developera3511852023-06-14 14:12:59 +080010960 char output[16]={'\0'};
10961 char config_file[MAX_BUF_SIZE] = {0};
10962 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080010963 int res;
developer72fb0bb2023-01-11 09:46:29 +080010964
developera3511852023-06-14 14:12:59 +080010965 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10966 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080010967 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
10968 if (os_snprintf_error(sizeof(config_file), res)) {
10969 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
10970 return RETURN_ERR;
10971 }
developera3511852023-06-14 14:12:59 +080010972 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080010973
developera3511852023-06-14 14:12:59 +080010974 if (strncmp(output, "0", 1) == 0)
10975 *output_bool = FALSE;
10976 else if (strncmp(output, "1", 1) == 0)
10977 *output_bool = TRUE;
10978 else if (strncmp(output, "2", 1) == 0)
10979 *output_bool = TRUE;
10980 else if (strncmp(output, "3", 1) == 0)
10981 *output_bool = TRUE;
10982 else
10983 *output_bool = FALSE;
10984 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010985
developera3511852023-06-14 14:12:59 +080010986 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010987}
10988
10989INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
10990{
developera3511852023-06-14 14:12:59 +080010991 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010992}
10993
10994INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
10995{
developera3511852023-06-14 14:12:59 +080010996 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010997}
10998
10999INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
11000{
developera3511852023-06-14 14:12:59 +080011001 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011002}
11003
11004INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
11005{
developera3511852023-06-14 14:12:59 +080011006 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11007 char config_file[MAX_BUF_SIZE] = {0};
11008 int res;
developer72fb0bb2023-01-11 09:46:29 +080011009
developera3511852023-06-14 14:12:59 +080011010 if (NULL == output)
11011 return RETURN_ERR;
11012 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
11013 if (os_snprintf_error(sizeof(config_file), res)) {
developer46506162023-06-12 10:09:39 +080011014 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11015 return RETURN_ERR;
11016 }
developera3511852023-06-14 14:12:59 +080011017 wifi_hostapdRead(config_file,"hw_mode",output,64);
developer72fb0bb2023-01-11 09:46:29 +080011018
developera3511852023-06-14 14:12:59 +080011019 if(strcmp(output,"b")==0)
11020 sprintf(output, "%s", "1,2,5.5,11");
11021 else if (strcmp(output,"a")==0)
11022 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
11023 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
11024 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
developer72fb0bb2023-01-11 09:46:29 +080011025
developera3511852023-06-14 14:12:59 +080011026 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11027 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011028}
11029
11030INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
11031{
developera3511852023-06-14 14:12:59 +080011032 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11033 char *temp;
11034 char temp_output[128];
11035 char temp_TransmitRates[128];
11036 char config_file[MAX_BUF_SIZE] = {0};
11037 int res;
developer72fb0bb2023-01-11 09:46:29 +080011038
developera3511852023-06-14 14:12:59 +080011039 if (NULL == output)
11040 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011041
developera3511852023-06-14 14:12:59 +080011042 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
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 }
developera3511852023-06-14 14:12:59 +080011047 wifi_hostapdRead(config_file,"supported_rates",output,64);
developer72fb0bb2023-01-11 09:46:29 +080011048
developera3511852023-06-14 14:12:59 +080011049 if (strlen(output) == 0) {
11050 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
11051 return RETURN_OK;
11052 }
11053 strcpy(temp_TransmitRates,output);
11054 strcpy(temp_output,"");
11055 temp = strtok(temp_TransmitRates," ");
11056 while(temp!=NULL)
11057 {
11058 temp[strlen(temp)-1]=0;
11059 if((temp[0]=='5') && (temp[1]=='\0'))
11060 {
11061 temp="5.5";
11062 }
11063 strcat(temp_output,temp);
11064 temp = strtok(NULL," ");
11065 if(temp!=NULL)
11066 {
11067 strcat(temp_output,",");
11068 }
11069 }
11070 strcpy(output,temp_output);
11071 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011072
developera3511852023-06-14 14:12:59 +080011073 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011074}
11075
11076INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
11077{
developera3511852023-06-14 14:12:59 +080011078 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011079}
11080
11081
11082INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
11083{
developera3511852023-06-14 14:12:59 +080011084 int i=0;
11085 char *temp;
11086 char temp1[128] = {0};
11087 char temp_output[128] = {0};
11088 char temp_TransmitRates[128] = {0};
11089 struct params params={'\0'};
11090 char config_file[MAX_BUF_SIZE] = {0};
11091 wifi_band band = wifi_index_to_band(wlanIndex);
developer72fb0bb2023-01-11 09:46:29 +080011092
developera3511852023-06-14 14:12:59 +080011093 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11094 if(NULL == output)
11095 return RETURN_ERR;
11096 strcpy(temp_TransmitRates,output);
developer72fb0bb2023-01-11 09:46:29 +080011097
developera3511852023-06-14 14:12:59 +080011098 for(i=0;i<strlen(temp_TransmitRates);i++)
11099 {
11100 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
11101 {
11102 continue;
11103 }
11104 else
11105 {
11106 return RETURN_ERR;
11107 }
11108 }
11109 strcpy(temp_output,"");
11110 temp = strtok(temp_TransmitRates,",");
11111 while(temp!=NULL)
11112 {
11113 strcpy(temp1,temp);
11114 if(band == band_5)
11115 {
11116 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
11117 {
11118 return RETURN_ERR;
11119 }
11120 }
developer72fb0bb2023-01-11 09:46:29 +080011121
developera3511852023-06-14 14:12:59 +080011122 if(strcmp(temp,"5.5")==0)
11123 {
11124 strcpy(temp1,"55");
11125 }
11126 else
11127 {
11128 strcat(temp1,"0");
11129 }
11130 strcat(temp_output,temp1);
11131 temp = strtok(NULL,",");
11132 if(temp!=NULL)
11133 {
11134 strcat(temp_output," ");
11135 }
11136 }
11137 strcpy(output,temp_output);
developer72fb0bb2023-01-11 09:46:29 +080011138
developera3511852023-06-14 14:12:59 +080011139 params.name = "supported_rates";
11140 params.value = output;
developer72fb0bb2023-01-11 09:46:29 +080011141
developera3511852023-06-14 14:12:59 +080011142 wifi_dbg_printf("\n%s:",__func__);
11143 wifi_dbg_printf("params.value=%s\n",params.value);
11144 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
11145 wifi_hostapdWrite(config_file,&params,1);
11146 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011147
developera3511852023-06-14 14:12:59 +080011148 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011149}
11150
11151
11152static char *sncopy(char *dst, int dst_sz, const char *src)
11153{
developera3511852023-06-14 14:12:59 +080011154 if (src && dst && dst_sz > 0) {
11155 strncpy(dst, src, dst_sz);
11156 dst[dst_sz - 1] = '\0';
11157 }
11158 return dst;
developer72fb0bb2023-01-11 09:46:29 +080011159}
11160
11161static int util_get_sec_chan_offset(int channel, const char* ht_mode)
11162{
developera3511852023-06-14 14:12:59 +080011163 if (0 == strcmp(ht_mode, "HT40") ||
11164 0 == strcmp(ht_mode, "HT80") ||
11165 0 == strcmp(ht_mode, "HT160")) {
11166 switch (channel) {
11167 case 1 ... 7:
11168 case 36:
11169 case 44:
11170 case 52:
11171 case 60:
11172 case 100:
11173 case 108:
11174 case 116:
11175 case 124:
11176 case 132:
11177 case 140:
11178 case 149:
11179 case 157:
11180 return 1;
11181 case 8 ... 13:
11182 case 40:
11183 case 48:
11184 case 56:
11185 case 64:
11186 case 104:
11187 case 112:
11188 case 120:
11189 case 128:
11190 case 136:
11191 case 144:
11192 case 153:
11193 case 161:
11194 return -1;
11195 default:
11196 return -EINVAL;
11197 }
11198 }
developer72fb0bb2023-01-11 09:46:29 +080011199
developera3511852023-06-14 14:12:59 +080011200 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080011201}
11202
11203static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
11204{
developera3511852023-06-14 14:12:59 +080011205 int idx = channel%8;
11206 if (0 == strcmp(ht_mode, "HT40") ||
11207 0 == strcmp(ht_mode, "HT80") ||
11208 0 == strcmp(ht_mode, "HT160")) {
11209 switch (idx) {
11210 case 1:
11211 return 1;
11212 case 5:
11213 return -1;
11214 default:
11215 return -EINVAL;
11216 }
11217 }
developer72fb0bb2023-01-11 09:46:29 +080011218
developera3511852023-06-14 14:12:59 +080011219 return -EINVAL;
developer72fb0bb2023-01-11 09:46:29 +080011220}
11221static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
11222{
developera3511852023-06-14 14:12:59 +080011223 if (NULL == hw_mode) return;
developer72fb0bb2023-01-11 09:46:29 +080011224
developera3511852023-06-14 14:12:59 +080011225 if (0 == strcmp(hw_mode, "ac"))
11226 sncopy(bw_mode, bw_mode_len, "ht vht");
developer72fb0bb2023-01-11 09:46:29 +080011227
developera3511852023-06-14 14:12:59 +080011228 if (0 == strcmp(hw_mode, "n"))
11229 sncopy(bw_mode, bw_mode_len, "ht");
developer72fb0bb2023-01-11 09:46:29 +080011230
developera3511852023-06-14 14:12:59 +080011231 return;
developer72fb0bb2023-01-11 09:46:29 +080011232}
11233
11234static int util_chan_to_freq(int chan)
11235{
developera3511852023-06-14 14:12:59 +080011236 if (chan == 14)
11237 return 2484;
11238 else if (chan < 14)
11239 return 2407 + chan * 5;
11240 else if (chan >= 182 && chan <= 196)
11241 return 4000 + chan * 5;
11242 else
11243 return 5000 + chan * 5;
11244 return 0;
developer72fb0bb2023-01-11 09:46:29 +080011245}
11246
11247static int util_6G_chan_to_freq(int chan)
11248{
developera3511852023-06-14 14:12:59 +080011249 if (chan)
11250 return 5950 + chan * 5;
11251 else
11252 return 0;
developer69b61b02023-03-07 17:17:44 +080011253
developer72fb0bb2023-01-11 09:46:29 +080011254}
11255const int *util_unii_5g_chan2list(int chan, int width)
11256{
developera3511852023-06-14 14:12:59 +080011257 static const int lists[] = {
11258 // <width>, <chan1>, <chan2>..., 0,
11259 20, 36, 0,
11260 20, 40, 0,
11261 20, 44, 0,
11262 20, 48, 0,
11263 20, 52, 0,
11264 20, 56, 0,
11265 20, 60, 0,
11266 20, 64, 0,
11267 20, 100, 0,
11268 20, 104, 0,
11269 20, 108, 0,
11270 20, 112, 0,
11271 20, 116, 0,
11272 20, 120, 0,
11273 20, 124, 0,
11274 20, 128, 0,
11275 20, 132, 0,
11276 20, 136, 0,
11277 20, 140, 0,
11278 20, 144, 0,
11279 20, 149, 0,
11280 20, 153, 0,
11281 20, 157, 0,
11282 20, 161, 0,
11283 20, 165, 0,
11284 40, 36, 40, 0,
11285 40, 44, 48, 0,
11286 40, 52, 56, 0,
11287 40, 60, 64, 0,
11288 40, 100, 104, 0,
11289 40, 108, 112, 0,
11290 40, 116, 120, 0,
11291 40, 124, 128, 0,
11292 40, 132, 136, 0,
11293 40, 140, 144, 0,
11294 40, 149, 153, 0,
11295 40, 157, 161, 0,
11296 80, 36, 40, 44, 48, 0,
11297 80, 52, 56, 60, 64, 0,
11298 80, 100, 104, 108, 112, 0,
11299 80, 116, 120, 124, 128, 0,
11300 80, 132, 136, 140, 144, 0,
11301 80, 149, 153, 157, 161, 0,
11302 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
11303 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
11304 -1 // final delimiter
11305 };
11306 const int *start;
11307 const int *p;
developer72fb0bb2023-01-11 09:46:29 +080011308
developera3511852023-06-14 14:12:59 +080011309 for (p = lists; *p != -1; p++) {
11310 if (*p == width) {
11311 for (start = ++p; *p != 0; p++) {
11312 if (*p == chan)
11313 return start;
11314 }
11315 }
11316 // move to the end of channel list of given width
11317 while (*p != 0) {
11318 p++;
11319 }
11320 }
developer72fb0bb2023-01-11 09:46:29 +080011321
developera3511852023-06-14 14:12:59 +080011322 return NULL;
developer72fb0bb2023-01-11 09:46:29 +080011323}
11324
11325static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
11326{
developera3511852023-06-14 14:12:59 +080011327 if (NULL == ht_mode)
11328 return 0;
developer72fb0bb2023-01-11 09:46:29 +080011329
developera3511852023-06-14 14:12:59 +080011330 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
11331 const int *chans = util_unii_5g_chan2list(channel, width);
11332 int sum = 0;
11333 int cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080011334
developera3511852023-06-14 14:12:59 +080011335 if (NULL == chans)
11336 return 0;
developer72fb0bb2023-01-11 09:46:29 +080011337
developera3511852023-06-14 14:12:59 +080011338 while (*chans) {
11339 sum += *chans;
11340 cnt++;
11341 chans++;
11342 }
11343 if (cnt == 0)
11344 return 0;
11345 return sum / cnt;
developer72fb0bb2023-01-11 09:46:29 +080011346}
11347
11348static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
11349{
developera3511852023-06-14 14:12:59 +080011350 if (NULL == ht_mode)
11351 return 0;
developer72fb0bb2023-01-11 09:46:29 +080011352
developera3511852023-06-14 14:12:59 +080011353 int width = strtol((ht_mode + 2), NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080011354
developera3511852023-06-14 14:12:59 +080011355 int idx = 0 ;
11356 int centerchan = 0;
11357 int chan_ofs = 1;
developer72fb0bb2023-01-11 09:46:29 +080011358
developera3511852023-06-14 14:12:59 +080011359 if (width == 40){
11360 idx = ((channel/4) + chan_ofs)%2;
11361 switch (idx) {
11362 case 0:
11363 centerchan = (channel - 2);
11364 break;
11365 case 1:
11366 centerchan = (channel + 2);
11367 break;
11368 default:
11369 return -EINVAL;
11370 }
11371 }else if (width == 80){
11372 idx = ((channel/4) + chan_ofs)%4;
11373 switch (idx) {
11374 case 0:
11375 centerchan = (channel - 6);
11376 break;
11377 case 1:
11378 centerchan = (channel + 6);
11379 break;
11380 case 2:
11381 centerchan = (channel + 2);
11382 break;
11383 case 3:
11384 centerchan = (channel - 2);
11385 break;
11386 default:
11387 return -EINVAL;
11388 }
11389 }else if (width == 160){
11390 switch (channel) {
11391 case 1 ... 29:
11392 centerchan = 15;
11393 break;
11394 case 33 ... 61:
11395 centerchan = 47;
11396 break;
11397 case 65 ... 93:
11398 centerchan = 79;
11399 break;
11400 case 97 ... 125:
11401 centerchan = 111;
11402 break;
11403 case 129 ... 157:
11404 centerchan = 143;
11405 break;
11406 case 161 ... 189:
11407 centerchan = 175;
11408 break;
11409 case 193 ... 221:
11410 centerchan = 207;
11411 break;
11412 default:
11413 return -EINVAL;
11414 }
11415 }
11416 return centerchan;
developer72fb0bb2023-01-11 09:46:29 +080011417}
11418static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
11419{
developera3511852023-06-14 14:12:59 +080011420 BOOL onlyG, onlyN, onlyA;
11421 CHAR tmp[64];
11422 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
11423 if (ret == RETURN_OK) {
11424 sncopy(hw_mode, hw_mode_size, tmp);
11425 }
11426 return ret;
developer72fb0bb2023-01-11 09:46:29 +080011427}
11428
11429INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
11430{
developera3511852023-06-14 14:12:59 +080011431 // Sample commands:
11432 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
11433 // hostapd_cli -i wifi0 chan_switch 30 2437
11434 int ret = 0;
11435 char center_freq1_str[32] = ""; // center_freq1=%d
11436 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
11437 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
11438 char hw_mode[16] = ""; // n|ac
11439 char bw_mode[16] = ""; // ht|ht vht
11440 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
11441 char interface_name[16] = {0};
11442 int sec_chan_offset;
11443 int width;
11444 char config_file[64] = {0};
11445 char *ext_str = "None";
11446 wifi_band band = band_invalid;
11447 int center_chan = 0;
11448 int center_freq1 = 0;
developere40952c2023-06-15 18:46:43 +080011449 int res;
developer72fb0bb2023-01-11 09:46:29 +080011450
developere40952c2023-06-15 18:46:43 +080011451 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
11452 if (os_snprintf_error(sizeof(config_file), res)) {
11453 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11454 return RETURN_ERR;
11455 }
developer72fb0bb2023-01-11 09:46:29 +080011456
developera3511852023-06-14 14:12:59 +080011457 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
11458 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011459
developera3511852023-06-14 14:12:59 +080011460 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011461
developera3511852023-06-14 14:12:59 +080011462 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080011463
developera3511852023-06-14 14:12:59 +080011464 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
developer72fb0bb2023-01-11 09:46:29 +080011465
developera3511852023-06-14 14:12:59 +080011466 // Get radio mode HT20|HT40|HT80 etc.
11467 if (channel){
developere40952c2023-06-15 18:46:43 +080011468 res = snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
11469 if (os_snprintf_error(sizeof(ht_mode), res)) {
11470 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11471 return RETURN_ERR;
11472 }
developer72fb0bb2023-01-11 09:46:29 +080011473
developera3511852023-06-14 14:12:59 +080011474 // Provide bandwith if specified
11475 if (channel_width_MHz > 20) {
11476 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
11477 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
11478 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
developer72fb0bb2023-01-11 09:46:29 +080011479
developere40952c2023-06-15 18:46:43 +080011480 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
developera3511852023-06-14 14:12:59 +080011481 }else if (channel_width_MHz == 20){
developere40952c2023-06-15 18:46:43 +080011482 res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
developera3511852023-06-14 14:12:59 +080011483 }
developer72fb0bb2023-01-11 09:46:29 +080011484
developere40952c2023-06-15 18:46:43 +080011485 if (os_snprintf_error(sizeof(opt_chan_info_str), res)) {
11486 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11487 return RETURN_ERR;
11488 }
developer72fb0bb2023-01-11 09:46:29 +080011489
developera3511852023-06-14 14:12:59 +080011490 if (channel_width_MHz > 20) {
11491 if (band == band_6){
11492 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
11493 if(center_chan){
11494 center_freq1 = util_6G_chan_to_freq(center_chan);
11495 }
11496 }else{
11497 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
11498 if(center_chan){
11499 center_freq1 = util_chan_to_freq(center_chan);
11500 }
11501 }
developer69b61b02023-03-07 17:17:44 +080011502
developera3511852023-06-14 14:12:59 +080011503 if (center_freq1)
developere40952c2023-06-15 18:46:43 +080011504 res = snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080011505
developera3511852023-06-14 14:12:59 +080011506 }
developere40952c2023-06-15 18:46:43 +080011507 if (os_snprintf_error(sizeof(center_freq1_str), res)) {
11508 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11509 return RETURN_ERR;
11510 }
developer72fb0bb2023-01-11 09:46:29 +080011511
developera3511852023-06-14 14:12:59 +080011512 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
11513 if (band == band_6){
11514 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
11515 }else{
11516 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
11517 }
developere40952c2023-06-15 18:46:43 +080011518 if (sec_chan_offset != -EINVAL) {
11519 res = snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
11520 if (os_snprintf_error(sizeof(sec_chan_offset_str), res)) {
11521 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11522 return RETURN_ERR;
11523 }
11524 }
developera3511852023-06-14 14:12:59 +080011525 // Only the first AP, other are hanging on the same radio
11526 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
11527 if (ret != RETURN_OK) {
11528 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
11529 return RETURN_ERR;
11530 }
11531 /* wifi_dbg_printf("execute: '%s'\n", cmd);
11532 ret = _syscmd(cmd, buf, sizeof(buf));
11533 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080011534
developera3511852023-06-14 14:12:59 +080011535 ret = wifi_setRadioChannel(radioIndex, channel);
11536 if (ret != RETURN_OK) {
11537 fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__);
11538 return RETURN_ERR;
11539 }
developer72fb0bb2023-01-11 09:46:29 +080011540
developera3511852023-06-14 14:12:59 +080011541 if (sec_chan_offset == 1)
11542 ext_str = "Above";
11543 else if (sec_chan_offset == -1)
11544 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080011545
developera3511852023-06-14 14:12:59 +080011546 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080011547
developera3511852023-06-14 14:12:59 +080011548 } else {
11549 if (channel_width_MHz > 20)
11550 ext_str = "Above";
11551 }
developer72fb0bb2023-01-11 09:46:29 +080011552
developera3511852023-06-14 14:12:59 +080011553 wifi_setRadioExtChannel(radioIndex, ext_str);
developer72fb0bb2023-01-11 09:46:29 +080011554
developera3511852023-06-14 14:12:59 +080011555 char mhz_str[16];
developere40952c2023-06-15 18:46:43 +080011556 res = snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
11557 if (os_snprintf_error(sizeof(mhz_str), res)) {
11558 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11559 return RETURN_ERR;
11560 }
developera3511852023-06-14 14:12:59 +080011561 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
developer72fb0bb2023-01-11 09:46:29 +080011562
developera3511852023-06-14 14:12:59 +080011563 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011564
developera3511852023-06-14 14:12:59 +080011565 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011566}
11567
11568INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
11569{
developera3511852023-06-14 14:12:59 +080011570 int index = -1;
11571 wifi_neighbor_ap2_t *scan_array = NULL;
11572 char cmd[256]={0};
11573 char buf[128]={0};
11574 char file_name[32] = {0};
11575 char filter_SSID[32] = {0};
11576 char line[256] = {0};
11577 char interface_name[16] = {0};
11578 char *ret = NULL;
11579 int freq=0;
11580 FILE *f = NULL;
11581 int channels_num = 0;
11582 int vht_channel_width = 0;
11583 int get_noise_ret = RETURN_ERR;
11584 bool filter_enable = false;
11585 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
11586 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080011587 int res;
developer72fb0bb2023-01-11 09:46:29 +080011588
developera3511852023-06-14 14:12:59 +080011589 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011590
developere40952c2023-06-15 18:46:43 +080011591 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
11592 if (os_snprintf_error(sizeof(file_name), res)) {
11593 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11594 return RETURN_ERR;
11595 }
developera3511852023-06-14 14:12:59 +080011596 f = fopen(file_name, "r");
11597 if (f != NULL) {
11598 fgets(filter_SSID, sizeof(file_name), f);
11599 if (strlen(filter_SSID) != 0)
11600 filter_enable = true;
11601 fclose(f);
11602 }
developer72fb0bb2023-01-11 09:46:29 +080011603
developera3511852023-06-14 14:12:59 +080011604 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
11605 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011606
developera3511852023-06-14 14:12:59 +080011607 phyId = radio_index_to_phy(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080011608
developere40952c2023-06-15 18:46:43 +080011609 res = snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
11610 if (os_snprintf_error(sizeof(cmd), res)) {
11611 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11612 return RETURN_ERR;
11613 }
developera3511852023-06-14 14:12:59 +080011614 _syscmd(cmd, buf, sizeof(buf));
11615 channels_num = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080011616
developera3511852023-06-14 14:12:59 +080011617 sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
11618 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
11619 fprintf(stderr, "cmd: %s\n", cmd);
11620 if ((f = popen(cmd, "r")) == NULL) {
11621 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11622 return RETURN_ERR;
11623 }
developer69b61b02023-03-07 17:17:44 +080011624
developera3511852023-06-14 14:12:59 +080011625 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
11626 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +080011627
developera3511852023-06-14 14:12:59 +080011628 ret = fgets(line, sizeof(line), f);
11629 while (ret != NULL) {
11630 if(strstr(line, "BSS") != NULL) { // new neighbor info
11631 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
11632 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
11633 // 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 +080011634
developera3511852023-06-14 14:12:59 +080011635 if (!filter_BSS) {
11636 index++;
11637 wifi_neighbor_ap2_t *tmp;
11638 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
11639 if (tmp == NULL) { // no more memory to use
11640 index--;
11641 wifi_dbg_printf("%s: realloc failed\n", __func__);
11642 break;
11643 }
11644 scan_array = tmp;
11645 }
11646 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
developer72fb0bb2023-01-11 09:46:29 +080011647
developera3511852023-06-14 14:12:59 +080011648 filter_BSS = false;
11649 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
developerc79e9172023-06-06 19:48:03 +080011650 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
developera3511852023-06-14 14:12:59 +080011651 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
developerc79e9172023-06-06 19:48:03 +080011652 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
developera3511852023-06-14 14:12:59 +080011653 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
developerc79e9172023-06-06 19:48:03 +080011654 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
developera3511852023-06-14 14:12:59 +080011655 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
11656 } else if (strstr(line, "freq") != NULL) {
11657 sscanf(line," freq: %d", &freq);
11658 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080011659
developera3511852023-06-14 14:12:59 +080011660 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +080011661 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080011662 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
developerc79e9172023-06-06 19:48:03 +080011663 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080011664 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
developerc79e9172023-06-06 19:48:03 +080011665 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080011666 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
11667 }
11668 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +080011669 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
developera3511852023-06-14 14:12:59 +080011670 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
developerc79e9172023-06-06 19:48:03 +080011671 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
developera3511852023-06-14 14:12:59 +080011672 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
developerc79e9172023-06-06 19:48:03 +080011673 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
developera3511852023-06-14 14:12:59 +080011674 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
11675 }
developer72fb0bb2023-01-11 09:46:29 +080011676
developera3511852023-06-14 14:12:59 +080011677 scan_array[index].ap_Noise = 0;
11678 if (get_noise_ret == RETURN_OK) {
11679 for (int i = 0; i < channels_num; i++) {
11680 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
11681 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
11682 break;
11683 }
11684 }
11685 }
11686 } else if (strstr(line, "beacon interval") != NULL) {
11687 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
11688 } else if (strstr(line, "signal") != NULL) {
11689 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
11690 } else if (strstr(line,"SSID") != NULL) {
11691 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
11692 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
11693 filter_BSS = true;
11694 }
11695 } else if (strstr(line, "Supported rates") != NULL) {
11696 char SRate[80] = {0}, *tmp = NULL;
11697 memset(buf, 0, sizeof(buf));
11698 strcpy(SRate, line);
11699 tmp = strtok(SRate, ":");
11700 tmp = strtok(NULL, ":");
11701 strcpy(buf, tmp);
11702 memset(SRate, 0, sizeof(SRate));
developer72fb0bb2023-01-11 09:46:29 +080011703
developera3511852023-06-14 14:12:59 +080011704 tmp = strtok(buf, " \n");
11705 while (tmp != NULL) {
11706 strcat(SRate, tmp);
11707 if (SRate[strlen(SRate) - 1] == '*') {
11708 SRate[strlen(SRate) - 1] = '\0';
11709 }
11710 strcat(SRate, ",");
developer72fb0bb2023-01-11 09:46:29 +080011711
developera3511852023-06-14 14:12:59 +080011712 tmp = strtok(NULL, " \n");
11713 }
11714 SRate[strlen(SRate) - 1] = '\0';
11715 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
11716 } else if (strstr(line, "DTIM") != NULL) {
11717 sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod));
11718 } else if (strstr(line, "VHT capabilities") != NULL) {
11719 strcat(scan_array[index].ap_SupportedStandards, ",ac");
11720 strcpy(scan_array[index].ap_OperatingStandards, "ac");
11721 } else if (strstr(line, "HT capabilities") != NULL) {
11722 strcat(scan_array[index].ap_SupportedStandards, ",n");
11723 strcpy(scan_array[index].ap_OperatingStandards, "n");
11724 } else if (strstr(line, "VHT operation") != NULL) {
11725 ret = fgets(line, sizeof(line), f);
11726 sscanf(line," * channel width: %d", &vht_channel_width);
11727 if(vht_channel_width == 1) {
developere40952c2023-06-15 18:46:43 +080011728 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
developera3511852023-06-14 14:12:59 +080011729 } else {
developere40952c2023-06-15 18:46:43 +080011730 res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
developera3511852023-06-14 14:12:59 +080011731 }
developere40952c2023-06-15 18:46:43 +080011732 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
11733 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11734 return RETURN_ERR;
11735 }
11736
developera3511852023-06-14 14:12:59 +080011737 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11738 continue;
11739 } else if (strstr(line, "HT operation") != NULL) {
11740 ret = fgets(line, sizeof(line), f);
11741 sscanf(line," * secondary channel offset: %s", buf);
11742 if (!strcmp(buf, "above")) {
11743 //40Mhz +
developere40952c2023-06-15 18:46:43 +080011744 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 +080011745 }
11746 else if (!strcmp(buf, "below")) {
11747 //40Mhz -
developere40952c2023-06-15 18:46:43 +080011748 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 +080011749 } else {
11750 //20Mhz
developere40952c2023-06-15 18:46:43 +080011751 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 +080011752 }
developere40952c2023-06-15 18:46:43 +080011753 if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
11754 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11755 return RETURN_ERR;
11756 }
11757
developera3511852023-06-14 14:12:59 +080011758 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11759 continue;
11760 } else if (strstr(line, "HE capabilities") != NULL) {
11761 strcat(scan_array[index].ap_SupportedStandards, ",ax");
11762 strcpy(scan_array[index].ap_OperatingStandards, "ax");
11763 ret = fgets(line, sizeof(line), f);
11764 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
11765 if (strstr(line, "HE40/2.4GHz") != NULL)
11766 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
11767 else
11768 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
11769 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
11770 if (strstr(line, "HE80/5GHz") != NULL) {
11771 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
11772 ret = fgets(line, sizeof(line), f);
11773 } else
11774 continue;
11775 if (strstr(line, "HE160/5GHz") != NULL)
11776 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
11777 }
11778 continue;
11779 } else if (strstr(line, "WPA") != NULL) {
11780 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
11781 } else if (strstr(line, "RSN") != NULL) {
11782 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
11783 } else if (strstr(line, "Group cipher") != NULL) {
11784 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
11785 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
11786 strcpy(scan_array[index].ap_EncryptionMode, "AES");
11787 }
11788 }
11789 ret = fgets(line, sizeof(line), f);
11790 }
developer72fb0bb2023-01-11 09:46:29 +080011791
developera3511852023-06-14 14:12:59 +080011792 if (!filter_BSS) {
11793 *output_array_size = index + 1;
11794 } else {
11795 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
11796 *output_array_size = index;
11797 }
11798 *neighbor_ap_array = scan_array;
11799 pclose(f);
11800 free(channels_noise_arr);
11801 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11802 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011803}
11804
11805INT wifi_getApAssociatedDeviceStats(
developera3511852023-06-14 14:12:59 +080011806 INT apIndex,
11807 mac_address_t *clientMacAddress,
11808 wifi_associated_dev_stats_t *associated_dev_stats,
11809 u64 *handle)
developer72fb0bb2023-01-11 09:46:29 +080011810{
developera3511852023-06-14 14:12:59 +080011811 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
11812 char interface_name[50] = {0};
11813 char cmd[1024] = {0};
11814 char mac_str[18] = {0};
11815 char *key = NULL;
11816 char *val = NULL;
11817 FILE *f = NULL;
11818 char *line = NULL;
11819 size_t len = 0;
developer72fb0bb2023-01-11 09:46:29 +080011820
developera3511852023-06-14 14:12:59 +080011821 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11822 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11823 return RETURN_ERR;
11824 }
developer72fb0bb2023-01-11 09:46:29 +080011825
developera3511852023-06-14 14:12:59 +080011826 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
11827 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
11828 if((f = popen(cmd, "r")) == NULL) {
11829 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11830 return RETURN_ERR;
11831 }
developer72fb0bb2023-01-11 09:46:29 +080011832
developera3511852023-06-14 14:12:59 +080011833 while ((getline(&line, &len, f)) != -1) {
11834 key = strtok(line,":");
11835 val = strtok(NULL,":");
developer72fb0bb2023-01-11 09:46:29 +080011836
11837 if(!strncmp(key,"rx bytes",8))
developera3511852023-06-14 14:12:59 +080011838 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
developer72fb0bb2023-01-11 09:46:29 +080011839 if(!strncmp(key,"tx bytes",8))
developera3511852023-06-14 14:12:59 +080011840 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
developer72fb0bb2023-01-11 09:46:29 +080011841 if(!strncmp(key,"rx packets",10))
developera3511852023-06-14 14:12:59 +080011842 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
developer72fb0bb2023-01-11 09:46:29 +080011843 if(!strncmp(key,"tx packets",10))
developera3511852023-06-14 14:12:59 +080011844 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11845 if(!strncmp(key,"tx retries",10))
11846 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
11847 if(!strncmp(key,"tx failed",9))
11848 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
11849 if(!strncmp(key,"rx drop misc",13))
11850 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
11851 if(!strncmp(key,"rx bitrate",10)) {
11852 val = strtok(val, " ");
11853 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
11854 }
11855 if(!strncmp(key,"tx bitrate",10)) {
11856 val = strtok(val, " ");
11857 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
11858 }
11859 }
11860 free(line);
11861 pclose(f);
11862 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011863}
11864
11865INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
11866{
developera3511852023-06-14 14:12:59 +080011867 char interface_name[IF_NAME_SIZE] = {0};
11868 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
developere40952c2023-06-15 18:46:43 +080011869 int res;
developer72fb0bb2023-01-11 09:46:29 +080011870
developera3511852023-06-14 14:12:59 +080011871 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +080011872
developera3511852023-06-14 14:12:59 +080011873 if (NULL == output_string)
11874 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011875
developera3511852023-06-14 14:12:59 +080011876 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11877 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080011878
developere40952c2023-06-15 18:46:43 +080011879 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
11880 if (os_snprintf_error(sizeof(cmd), res)) {
11881 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11882 return RETURN_ERR;
11883 }
developera3511852023-06-14 14:12:59 +080011884 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080011885
developera3511852023-06-14 14:12:59 +080011886 //size of SSID name restricted to value less than 32 bytes
developere40952c2023-06-15 18:46:43 +080011887 res = snprintf(output_string, 32, "%s", buf);
11888 if (os_snprintf_error(32, res)) {
11889 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11890 return RETURN_ERR;
11891 }
developera3511852023-06-14 14:12:59 +080011892 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011893
developera3511852023-06-14 14:12:59 +080011894 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080011895}
11896
11897INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
11898{
developer2edaf012023-05-24 14:24:53 +080011899 char *mac_arry_buf = NULL;
11900 INT policy = -1;
11901 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080011902
developer2edaf012023-05-24 14:24:53 +080011903 mac_arry_buf = malloc(buf_size);
11904 if (!mac_arry_buf) {
11905 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080011906 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011907 }
11908 memset(mac_arry_buf, 0, buf_size);
11909 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
11910 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
11911 goto err;
11912 }
11913 /*
11914 mtk format to get policy:
11915 "policy=1
11916 00:11:22:33:44:55
11917 00:11:22:33:44:66
11918 "
11919 */
11920 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
11921 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
11922 goto err;
11923 }
11924 if (!(policy >=0 && policy <= 2)){
11925 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
11926 goto err;
11927 }
11928 *output_filterMode = policy;
11929 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
11930 free(mac_arry_buf);
11931 mac_arry_buf = NULL;
11932 return RETURN_OK;
11933err:
11934 free(mac_arry_buf);
11935 mac_arry_buf = NULL;
11936 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
11937 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011938}
11939
developer2edaf012023-05-24 14:24:53 +080011940
developer72fb0bb2023-01-11 09:46:29 +080011941INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
11942{
developera3511852023-06-14 14:12:59 +080011943 FILE *fp = NULL;
11944 char str[MAX_BUF_SIZE] = {0};
11945 int wificlientindex = 0 ;
11946 int count = 0;
11947 int signalstrength = 0;
11948 int arr[MACADDRESS_SIZE] = {0};
11949 unsigned char mac[MACADDRESS_SIZE] = {0};
11950 UINT wifi_count = 0;
11951 char pipeCmd[MAX_CMD_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080011952 int res;
developer72fb0bb2023-01-11 09:46:29 +080011953
developera3511852023-06-14 14:12:59 +080011954 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11955 *output_array_size = 0;
11956 *associated_dev_array = NULL;
11957 char interface_name[50] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011958
developera3511852023-06-14 14:12:59 +080011959 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11960 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11961 return RETURN_ERR;
11962 }
developer72fb0bb2023-01-11 09:46:29 +080011963
developera3511852023-06-14 14:12:59 +080011964 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
11965 fp = popen(pipeCmd, "r");
11966 if (fp == NULL)
11967 {
11968 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11969 return RETURN_ERR;
11970 }
developer72fb0bb2023-01-11 09:46:29 +080011971
developera3511852023-06-14 14:12:59 +080011972 /* Read the output a line at a time - output it. */
11973 fgets(str, sizeof(str)-1, fp);
11974 wifi_count = (unsigned int) atoi ( str );
11975 *output_array_size = wifi_count;
11976 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11977 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080011978
developera3511852023-06-14 14:12:59 +080011979 if(wifi_count == 0)
11980 {
11981 return RETURN_OK;
11982 }
11983 else
11984 {
11985 wifi_associated_dev2_t* temp = NULL;
11986 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
11987 *associated_dev_array = temp;
11988 if(temp == NULL)
11989 {
11990 printf("Error Statement. Insufficient memory \n");
11991 return RETURN_ERR;
11992 }
developer72fb0bb2023-01-11 09:46:29 +080011993
developere40952c2023-06-15 18:46:43 +080011994 res = snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11995 if (os_snprintf_error(sizeof(pipeCmd), res)) {
11996 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
11997 return RETURN_ERR;
11998 }
11999
developera3511852023-06-14 14:12:59 +080012000 system(pipeCmd);
developer72fb0bb2023-01-11 09:46:29 +080012001
developera3511852023-06-14 14:12:59 +080012002 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
12003 if(fp == NULL)
12004 {
12005 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
12006 return RETURN_ERR;
12007 }
12008 fclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080012009
developera3511852023-06-14 14:12:59 +080012010 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
12011 fp = popen(pipeCmd, "r");
12012 if(fp)
12013 {
12014 for(count =0 ; count < wifi_count; count++)
12015 {
12016 fgets(str, MAX_BUF_SIZE, fp);
12017 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
12018 {
12019 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
12020 {
12021 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
developer72fb0bb2023-01-11 09:46:29 +080012022
developera3511852023-06-14 14:12:59 +080012023 }
12024 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
12025 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]);
12026 }
12027 temp[count].cli_AuthenticationState = 1; //TODO
12028 temp[count].cli_Active = 1; //TODO
12029 }
12030 pclose(fp);
12031 }
developer72fb0bb2023-01-11 09:46:29 +080012032
developera3511852023-06-14 14:12:59 +080012033 //Updating RSSI per client
12034 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
12035 fp = popen(pipeCmd, "r");
12036 if(fp)
12037 {
12038 pclose(fp);
12039 }
12040 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
12041 if(fp)
12042 {
12043 for(count =0 ; count < wifi_count ;count++)
12044 {
12045 fgets(str, MAX_BUF_SIZE, fp);
12046 signalstrength = atoi(str);
12047 temp[count].cli_RSSI = signalstrength;
12048 }
12049 pclose(fp);
12050 }
developer72fb0bb2023-01-11 09:46:29 +080012051
12052
developera3511852023-06-14 14:12:59 +080012053 //LastDataDownlinkRate
12054 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
12055 fp = popen(pipeCmd, "r");
12056 if (fp)
12057 {
12058 pclose(fp);
12059 }
12060 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
12061 if (fp)
12062 {
12063 for (count = 0; count < wifi_count; count++)
12064 {
12065 fgets(str, MAX_BUF_SIZE, fp);
12066 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
12067 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
12068 }
12069 pclose(fp);
12070 }
developer72fb0bb2023-01-11 09:46:29 +080012071
developera3511852023-06-14 14:12:59 +080012072 //LastDataUplinkRate
12073 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
12074 fp = popen(pipeCmd, "r");
12075 if (fp)
12076 {
12077 pclose(fp);
12078 }
12079 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
12080 if (fp)
12081 {
12082 for (count = 0; count < wifi_count; count++)
12083 {
12084 fgets(str, MAX_BUF_SIZE, fp);
12085 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
12086 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
12087 }
12088 pclose(fp);
12089 }
12090 }
12091 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12092 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012093
12094}
12095
12096INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
12097{
developera3511852023-06-14 14:12:59 +080012098 FILE *fp = NULL;
12099 char interface_name[50] = {0};
12100 char pipeCmd[128] = {0};
12101 char str[256] = {0};
12102 wifi_ssidTrafficStats2_t *out = output_struct;
developer72fb0bb2023-01-11 09:46:29 +080012103
developera3511852023-06-14 14:12:59 +080012104 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
12105 if (!output_struct)
12106 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012107
developera3511852023-06-14 14:12:59 +080012108 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
12109 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
12110 return RETURN_ERR;
12111 sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name);
developer72fb0bb2023-01-11 09:46:29 +080012112
developera3511852023-06-14 14:12:59 +080012113 fp = popen(pipeCmd, "r");
12114 if (fp == NULL) {
12115 fprintf(stderr, "%s: popen failed\n", __func__);
12116 return RETURN_ERR;
12117 }
12118 fgets(str, sizeof(str), fp);
12119 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080012120
developera3511852023-06-14 14:12:59 +080012121 if (strlen(str) == 0) // interface not exist
12122 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012123
developera3511852023-06-14 14:12:59 +080012124 sscanf(str, "%*[^:]: %lu %lu %lu %lu %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
12125 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
developer72fb0bb2023-01-11 09:46:29 +080012126
developera3511852023-06-14 14:12:59 +080012127 memset(str, 0, sizeof(str));
12128 sprintf(pipeCmd, "tail -n1 /proc/net/netstat");
12129 fp = popen(pipeCmd, "r");
12130 if (fp == NULL) {
12131 fprintf(stderr, "%s: popen failed\n", __func__);
12132 return RETURN_ERR;
12133 }
12134 fgets(str, sizeof(str), fp);
developer72fb0bb2023-01-11 09:46:29 +080012135
developera3511852023-06-14 14:12:59 +080012136 sscanf(str, "%*[^:]: %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
12137 &out->ssid_BroadcastPacketsSent);
12138 pclose(fp);
developer72fb0bb2023-01-11 09:46:29 +080012139
developera3511852023-06-14 14:12:59 +080012140 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
12141 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
developer72fb0bb2023-01-11 09:46:29 +080012142
developera3511852023-06-14 14:12:59 +080012143 // Not supported
12144 output_struct->ssid_RetransCount = 0;
12145 output_struct->ssid_FailedRetransCount = 0;
12146 output_struct->ssid_RetryCount = 0;
12147 output_struct->ssid_MultipleRetryCount = 0;
12148 output_struct->ssid_ACKFailureCount = 0;
12149 output_struct->ssid_AggregatedPacketCount = 0;
developer72fb0bb2023-01-11 09:46:29 +080012150
developera3511852023-06-14 14:12:59 +080012151 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012152}
12153
12154//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).
12155INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
12156{
developera3511852023-06-14 14:12:59 +080012157 char output_val[16]={'\0'};
12158 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012159
developera3511852023-06-14 14:12:59 +080012160 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12161 if (!output)
12162 return RETURN_ERR;
12163 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12164 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
developer72fb0bb2023-01-11 09:46:29 +080012165
developera3511852023-06-14 14:12:59 +080012166 if( strcmp(output_val,"1") == 0 )
12167 *output = TRUE;
12168 else
12169 *output = FALSE;
12170 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012171
developera3511852023-06-14 14:12:59 +080012172 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012173}
12174
12175INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
12176{
developera3511852023-06-14 14:12:59 +080012177 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12178 char string[MAX_BUF_SIZE]={'\0'};
12179 char config_file[MAX_BUF_SIZE] = {0};
12180 struct params params;
developer72fb0bb2023-01-11 09:46:29 +080012181
developera3511852023-06-14 14:12:59 +080012182 if(enable == TRUE)
12183 strcpy(string,"1");
12184 else
12185 strcpy(string,"0");
developer72fb0bb2023-01-11 09:46:29 +080012186
developera3511852023-06-14 14:12:59 +080012187 params.name = "ap_isolate";
12188 params.value = string;
developer72fb0bb2023-01-11 09:46:29 +080012189
developera3511852023-06-14 14:12:59 +080012190 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12191 wifi_hostapdWrite(config_file,&params,1);
12192 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012193
developera3511852023-06-14 14:12:59 +080012194 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012195}
12196
12197INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
12198{
developera3511852023-06-14 14:12:59 +080012199 char mgmtpwr_file[32] = {0};
12200 char cmd[64] = {0};
12201 char buf[32]={0};
developere40952c2023-06-15 18:46:43 +080012202 int res;
developera1255e42023-05-13 17:45:02 +080012203
developera3511852023-06-14 14:12:59 +080012204 if (NULL == output_dBm)
12205 return RETURN_ERR;
developere40952c2023-06-15 18:46:43 +080012206 res = snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
12207 if (os_snprintf_error(sizeof(mgmtpwr_file), res)) {
12208 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12209 return RETURN_ERR;
12210 }
12211
12212 res = snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
12213 if (os_snprintf_error(sizeof(cmd), res)) {
12214 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12215 return RETURN_ERR;
12216 }
developera3511852023-06-14 14:12:59 +080012217 _syscmd(cmd, buf, sizeof(buf));
12218 if (strlen(buf) > 0)
12219 *output_dBm = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +080012220 else
12221 *output_dBm = 23;
developera3511852023-06-14 14:12:59 +080012222 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012223}
12224
12225INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
12226{
developera1255e42023-05-13 17:45:02 +080012227 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080012228 char mgmt_pwr_file[128]={0};
12229 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080012230 int if_idx, ret = 0;
12231 struct nl_msg *msg = NULL;
12232 struct nlattr * msg_data = NULL;
12233 struct mtk_nl80211_param param;
12234 struct unl unl_ins;
12235 char power[16] = {0};
developere40952c2023-06-15 18:46:43 +080012236 int res;
developera1255e42023-05-13 17:45:02 +080012237
12238 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12239
12240 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
12241 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080012242
12243 if_idx = if_nametoindex(interface_name);
12244 /*init mtk nl80211 vendor cmd*/
12245 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
12246 param.if_type = NL80211_ATTR_IFINDEX;
12247 param.if_idx = if_idx;
12248
12249 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
12250 if (ret) {
12251 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
12252 return RETURN_ERR;
12253 }
12254
12255 /*add mtk vendor cmd data*/
developere40952c2023-06-15 18:46:43 +080012256 res = snprintf(power, sizeof(power), "%d", dBm);
12257 if (os_snprintf_error(sizeof(power), res)) {
12258 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12259 return RETURN_ERR;
12260 }
12261
developerfead3972023-05-25 20:15:02 +080012262 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
12263 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
12264 nlmsg_free(msg);
12265 goto err;
12266 }
12267
12268 /*send mtk nl80211 vendor msg*/
12269 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
12270 if (ret) {
12271 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
12272 goto err;
12273 }
12274
12275 /*deinit mtk nl80211 vendor msg*/
12276 mtk_nl80211_deint(&unl_ins);
12277 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
12278
developere40952c2023-06-15 18:46:43 +080012279 res = snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
12280 if (os_snprintf_error(sizeof(mgmt_pwr_file), res)) {
12281 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12282 return RETURN_ERR;
12283 }
12284
developera1255e42023-05-13 17:45:02 +080012285 f = fopen(mgmt_pwr_file, "w");
12286 if (f == NULL) {
12287 fprintf(stderr, "%s: fopen failed\n", __func__);
12288 return RETURN_ERR;
12289 }
12290 fprintf(f, "%d", dBm);
12291 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080012292 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080012293err:
12294 mtk_nl80211_deint(&unl_ins);
12295 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12296 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012297}
12298INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
12299{
developera3511852023-06-14 14:12:59 +080012300 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012301}
12302INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
12303{
developera3511852023-06-14 14:12:59 +080012304 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012305}
12306INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
12307{
developera3511852023-06-14 14:12:59 +080012308 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012309}
12310INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
12311{
developera3511852023-06-14 14:12:59 +080012312 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012313}
12314INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
12315{
developera3511852023-06-14 14:12:59 +080012316 char config_file[MAX_BUF_SIZE] = {0};
12317 struct params list;
developere40952c2023-06-15 18:46:43 +080012318 int res;
developer72fb0bb2023-01-11 09:46:29 +080012319
developera3511852023-06-14 14:12:59 +080012320 list.name = "bss_transition";
12321 list.value = activate?"1":"0";
developere40952c2023-06-15 18:46:43 +080012322 res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
12323 if (os_snprintf_error(sizeof(config_file), res)) {
12324 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12325 return RETURN_ERR;
12326 }
developera3511852023-06-14 14:12:59 +080012327 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080012328
developera3511852023-06-14 14:12:59 +080012329 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012330}
12331wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
12332
12333void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
12334{
developera3511852023-06-14 14:12:59 +080012335 return;
developer72fb0bb2023-01-11 09:46:29 +080012336}
12337
12338INT wifi_setApCsaDeauth(INT apIndex, INT mode)
12339{
developera3511852023-06-14 14:12:59 +080012340 // TODO Implement me!
12341 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012342}
12343
12344INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
12345{
developera3511852023-06-14 14:12:59 +080012346 char file_name[128] = {0};
12347 FILE *f = NULL;
12348 int max_num_radios = 0;
developere40952c2023-06-15 18:46:43 +080012349 int res;
developer72fb0bb2023-01-11 09:46:29 +080012350
developera3511852023-06-14 14:12:59 +080012351 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012352
developera3511852023-06-14 14:12:59 +080012353 wifi_getMaxRadioNumber(&max_num_radios);
12354 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
12355 for (int index = 0; index < max_num_radios; index++) {
developere40952c2023-06-15 18:46:43 +080012356 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
12357 if (os_snprintf_error(sizeof(file_name), res)) {
12358 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12359 return RETURN_ERR;
12360 }
12361
developera3511852023-06-14 14:12:59 +080012362 f = fopen(file_name, "w");
12363 if (f == NULL)
12364 return RETURN_ERR;
12365 // For mode == 0 is to disable filter, just don't write to the file.
12366 if (mode)
12367 fprintf(f, "%s", essid);
developer72fb0bb2023-01-11 09:46:29 +080012368
developera3511852023-06-14 14:12:59 +080012369 fclose(f);
12370 }
12371 } else { // special case, need to set AP's SSID as filter for each radio.
developere40952c2023-06-15 18:46:43 +080012372 res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
12373 if (os_snprintf_error(sizeof(file_name), res)) {
12374 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12375 return RETURN_ERR;
12376 }
12377
developera3511852023-06-14 14:12:59 +080012378 f = fopen(file_name, "w");
12379 if (f == NULL)
12380 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012381
developera3511852023-06-14 14:12:59 +080012382 // For mode == 0 is to disable filter, just don't write to the file.
12383 if (mode)
12384 fprintf(f, "%s", essid);
developer72fb0bb2023-01-11 09:46:29 +080012385
developera3511852023-06-14 14:12:59 +080012386 fclose(f);
12387 }
developer72fb0bb2023-01-11 09:46:29 +080012388
developera3511852023-06-14 14:12:59 +080012389 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12390 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012391}
12392
12393INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
12394{
developera3511852023-06-14 14:12:59 +080012395 // TODO Implement me!
12396 //Apply wifi_pushRadioChannel() instantly
12397 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012398}
12399
12400INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
12401{
developera3511852023-06-14 14:12:59 +080012402 // TODO Implement me!
12403 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012404}
12405
developer72fb0bb2023-01-11 09:46:29 +080012406
developera3511852023-06-14 14:12:59 +080012407static int tidStats_callback(struct nl_msg *msg, void *arg) {
12408 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12409 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12410 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12411 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
12412 int rem , tid_index = 0;
developer72fb0bb2023-01-11 09:46:29 +080012413
developera3511852023-06-14 14:12:59 +080012414 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
12415 wifi_associated_dev_tid_entry_t *stats_entry;
developer72fb0bb2023-01-11 09:46:29 +080012416
developera3511852023-06-14 14:12:59 +080012417 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
12418 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
12419 };
12420 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
12421 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
12422 };
developer72fb0bb2023-01-11 09:46:29 +080012423
developera3511852023-06-14 14:12:59 +080012424 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
12425 genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080012426
developer72fb0bb2023-01-11 09:46:29 +080012427
developera3511852023-06-14 14:12:59 +080012428 if (!tb[NL80211_ATTR_STA_INFO]) {
12429 fprintf(stderr, "station stats missing!\n");
12430 return NL_SKIP;
12431 }
developer72fb0bb2023-01-11 09:46:29 +080012432
developera3511852023-06-14 14:12:59 +080012433 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
12434 tb[NL80211_ATTR_STA_INFO],
12435 stats_policy)) {
12436 fprintf(stderr, "failed to parse nested attributes!\n");
12437 return NL_SKIP;
12438 }
developer72fb0bb2023-01-11 09:46:29 +080012439
developera3511852023-06-14 14:12:59 +080012440 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
12441 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
12442 {
12443 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080012444
developera3511852023-06-14 14:12:59 +080012445 stats_entry->tid = tid_index;
12446 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080012447
developera3511852023-06-14 14:12:59 +080012448 if(sinfo[NL80211_STA_INFO_TID_STATS])
12449 {
12450 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
12451 printf("failed to parse nested stats attributes!");
12452 return NL_SKIP;
12453 }
12454 }
12455 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12456 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080012457
developera3511852023-06-14 14:12:59 +080012458 if(tid_index < (PS_MAX_TID - 1))
12459 tid_index++;
12460 }
12461 }
12462 //ToDo: sum_time_ms, ewma_time_ms
12463 return NL_SKIP;
12464}
developer72fb0bb2023-01-11 09:46:29 +080012465
developera3511852023-06-14 14:12:59 +080012466INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
12467{
12468 Netlink nl;
12469 char if_name[IF_NAME_SIZE];
12470 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080012471 int res;
developer72fb0bb2023-01-11 09:46:29 +080012472
developera3511852023-06-14 14:12:59 +080012473 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12474 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012475
developere40952c2023-06-15 18:46:43 +080012476 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
12477 if (os_snprintf_error(sizeof(if_name), res)) {
12478 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12479 return RETURN_ERR;
12480 }
developer72fb0bb2023-01-11 09:46:29 +080012481
developera3511852023-06-14 14:12:59 +080012482 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080012483
developera3511852023-06-14 14:12:59 +080012484 if (nl.id < 0) {
12485 fprintf(stderr, "Error initializing netlink \n");
12486 return -1;
12487 }
developer72fb0bb2023-01-11 09:46:29 +080012488
developera3511852023-06-14 14:12:59 +080012489 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080012490
developera3511852023-06-14 14:12:59 +080012491 if (!msg) {
12492 fprintf(stderr, "Failed to allocate netlink message.\n");
12493 nlfree(&nl);
12494 return -2;
12495 }
developer72fb0bb2023-01-11 09:46:29 +080012496
developera3511852023-06-14 14:12:59 +080012497 genlmsg_put(msg,
12498 NL_AUTO_PID,
12499 NL_AUTO_SEQ,
12500 nl.id,
12501 0,
12502 0,
12503 NL80211_CMD_GET_STATION,
12504 0);
developer72fb0bb2023-01-11 09:46:29 +080012505
developera3511852023-06-14 14:12:59 +080012506 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12507 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12508 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
12509 nl_send_auto_complete(nl.socket, msg);
12510 nl_recvmsgs(nl.socket, nl.cb);
12511 nlmsg_free(msg);
12512 nlfree(&nl);
12513 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012514}
12515
12516
12517INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
12518{
developera3511852023-06-14 14:12:59 +080012519 char interface_name[16] = {0};
12520 char cmd[128]={0};
12521 char buf[128]={0};
12522 int freq = 0;
developere40952c2023-06-15 18:46:43 +080012523 int res;
developer72fb0bb2023-01-11 09:46:29 +080012524
developera3511852023-06-14 14:12:59 +080012525 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012526
developera3511852023-06-14 14:12:59 +080012527 // full mode is used to scan all channels.
12528 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
12529 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
12530 ieee80211_channel_to_frequency(chan_list[0], &freq);
developer72fb0bb2023-01-11 09:46:29 +080012531
developera3511852023-06-14 14:12:59 +080012532 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12533 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012534
developera3511852023-06-14 14:12:59 +080012535 if (freq)
developere40952c2023-06-15 18:46:43 +080012536 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 +080012537 else
developere40952c2023-06-15 18:46:43 +080012538 res = snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
12539 if (os_snprintf_error(sizeof(cmd), res)) {
12540 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12541 return RETURN_ERR;
12542 }
developer72fb0bb2023-01-11 09:46:29 +080012543
developera3511852023-06-14 14:12:59 +080012544 _syscmd(cmd, buf, sizeof(buf));
12545 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080012546
developera3511852023-06-14 14:12:59 +080012547 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012548}
12549
12550
12551INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
12552{
developera3511852023-06-14 14:12:59 +080012553 // TODO Implement me!
12554 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012555}
12556
12557INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
12558{
developera3511852023-06-14 14:12:59 +080012559 // TODO Implement me!
12560 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012561}
12562
12563INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
12564{
developera3511852023-06-14 14:12:59 +080012565 // TODO Implement me!
12566 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012567}
12568
12569INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
12570{
developera3511852023-06-14 14:12:59 +080012571 // TODO Implement me!
12572 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012573}
12574
12575INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
12576{
developera3511852023-06-14 14:12:59 +080012577 // TODO Implement me!
12578 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012579}
12580
12581INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
12582{
developera3511852023-06-14 14:12:59 +080012583 // TODO Implement me!
12584 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012585}
12586
12587INT wifi_steering_eventUnregister(void)
12588{
developera3511852023-06-14 14:12:59 +080012589 // TODO Implement me!
12590 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012591}
12592
12593INT wifi_delApAclDevices(INT apIndex)
12594{
developer7e4a2a62023-04-06 19:56:03 +080012595 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080012596 struct unl unl_ins;
12597 int if_idx = 0, ret = 0;
12598 struct nl_msg *msg = NULL;
12599 struct nlattr * msg_data = NULL;
12600 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080012601
developer7e4a2a62023-04-06 19:56:03 +080012602 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
12603 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080012604 if_idx = if_nametoindex(inf_name);
12605 if (!if_idx) {
12606 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
12607 return RETURN_ERR;
12608 }
12609 /*init mtk nl80211 vendor cmd*/
12610 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
12611 param.if_type = NL80211_ATTR_IFINDEX;
12612 param.if_idx = if_idx;
12613 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
12614 if (ret) {
12615 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
12616 return RETURN_ERR;
12617 }
12618 /*add mtk vendor cmd data*/
12619 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
12620 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
12621 nlmsg_free(msg);
12622 goto err;
12623 }
12624 /*send mtk nl80211 vendor msg*/
12625 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
12626 if (ret) {
12627 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
12628 goto err;
12629 }
12630 /*deinit mtk nl80211 vendor msg*/
12631 mtk_nl80211_deint(&unl_ins);
12632 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
12633 return RETURN_OK;
12634err:
12635 mtk_nl80211_deint(&unl_ins);
12636 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12637 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012638
developera3511852023-06-14 14:12:59 +080012639 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012640}
12641
developer72fb0bb2023-01-11 09:46:29 +080012642static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080012643 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12644 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12645 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12646 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12647 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12648 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080012649
developera3511852023-06-14 14:12:59 +080012650 nla_parse(tb,
12651 NL80211_ATTR_MAX,
12652 genlmsg_attrdata(gnlh, 0),
12653 genlmsg_attrlen(gnlh, 0),
12654 NULL);
developer72fb0bb2023-01-11 09:46:29 +080012655
developera3511852023-06-14 14:12:59 +080012656 if (!tb[NL80211_ATTR_STA_INFO]) {
12657 fprintf(stderr, "sta stats missing!\n");
12658 return NL_SKIP;
12659 }
developer72fb0bb2023-01-11 09:46:29 +080012660
developera3511852023-06-14 14:12:59 +080012661 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12662 fprintf(stderr, "failed to parse nested attributes!\n");
12663 return NL_SKIP;
12664 }
12665 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080012666
developera3511852023-06-14 14:12:59 +080012667 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080012668
developera3511852023-06-14 14:12:59 +080012669 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12670 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
12671 fprintf(stderr, "failed to parse nested rate attributes!");
12672 return NL_SKIP;
12673 }
12674 }
developer72fb0bb2023-01-11 09:46:29 +080012675
developera3511852023-06-14 14:12:59 +080012676 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
12677 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12678 printf("failed to parse nested stats attributes!");
12679 return NL_SKIP;
12680 }
12681 }
12682 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080012683
developera3511852023-06-14 14:12:59 +080012684 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
12685 {
12686 printf("Type is VHT\n");
12687 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12688 ((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 +080012689
developera3511852023-06-14 14:12:59 +080012690 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12691 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
12692 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12693 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12694 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12695 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12696 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12697 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12698 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
12699 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12700 } else {
12701 printf(" OFDM or CCK \n");
12702 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12703 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
12704 }
12705 }
developer72fb0bb2023-01-11 09:46:29 +080012706
developera3511852023-06-14 14:12:59 +080012707 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
developereff896f2023-05-29 14:52:55 +080012708 if(rinfo[NL80211_RATE_INFO_MCS])
12709 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12710 }
developera3511852023-06-14 14:12:59 +080012711 if (sinfo[NL80211_STA_INFO_RX_BYTES64])
developereff896f2023-05-29 14:52:55 +080012712 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
12713 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
12714 ((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 +080012715
developera3511852023-06-14 14:12:59 +080012716 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
12717 if (stats_info[NL80211_TID_STATS_RX_MSDU])
developereff896f2023-05-29 14:52:55 +080012718 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
12719 }
developer72fb0bb2023-01-11 09:46:29 +080012720
developereff896f2023-05-29 14:52:55 +080012721 if (sinfo[NL80211_STA_INFO_SIGNAL])
12722 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
12723 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
12724 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
12725 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
12726 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
12727 //rssi_array need to be filled
12728 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080012729}
developer72fb0bb2023-01-11 09:46:29 +080012730
12731INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12732{
developera3511852023-06-14 14:12:59 +080012733 Netlink nl;
12734 char if_name[32];
12735 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12736 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012737
developera3511852023-06-14 14:12:59 +080012738 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080012739
developera3511852023-06-14 14:12:59 +080012740 if (*output_array_size <= 0)
12741 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012742
developera3511852023-06-14 14:12:59 +080012743 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080012744
developera3511852023-06-14 14:12:59 +080012745 if (nl.id < 0) {
12746 fprintf(stderr, "Error initializing netlink \n");
12747 return 0;
12748 }
developer72fb0bb2023-01-11 09:46:29 +080012749
developera3511852023-06-14 14:12:59 +080012750 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080012751
developera3511852023-06-14 14:12:59 +080012752 if (!msg) {
12753 fprintf(stderr, "Failed to allocate netlink message.\n");
12754 nlfree(&nl);
12755 return 0;
12756 }
developer72fb0bb2023-01-11 09:46:29 +080012757
developera3511852023-06-14 14:12:59 +080012758 genlmsg_put(msg,
12759 NL_AUTO_PID,
12760 NL_AUTO_SEQ,
12761 nl.id,
12762 0,
12763 0,
12764 NL80211_CMD_GET_STATION,
12765 0);
developer72fb0bb2023-01-11 09:46:29 +080012766
developera3511852023-06-14 14:12:59 +080012767 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
12768 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12769 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
12770 nl_send_auto_complete(nl.socket, msg);
12771 nl_recvmsgs(nl.socket, nl.cb);
12772 nlmsg_free(msg);
12773 nlfree(&nl);
12774 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012775}
12776
developer72fb0bb2023-01-11 09:46:29 +080012777static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080012778 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12779 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12780 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12781 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12782 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12783 char mac_addr[20],dev[20];
developer72fb0bb2023-01-11 09:46:29 +080012784
developera3511852023-06-14 14:12:59 +080012785 nla_parse(tb,
12786 NL80211_ATTR_MAX,
12787 genlmsg_attrdata(gnlh, 0),
12788 genlmsg_attrlen(gnlh, 0),
12789 NULL);
developer72fb0bb2023-01-11 09:46:29 +080012790
developera3511852023-06-14 14:12:59 +080012791 if(!tb[NL80211_ATTR_STA_INFO]) {
12792 fprintf(stderr, "sta stats missing!\n");
12793 return NL_SKIP;
12794 }
developer72fb0bb2023-01-11 09:46:29 +080012795
developera3511852023-06-14 14:12:59 +080012796 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12797 fprintf(stderr, "failed to parse nested attributes!\n");
12798 return NL_SKIP;
12799 }
developer72fb0bb2023-01-11 09:46:29 +080012800
developera3511852023-06-14 14:12:59 +080012801 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
developer72fb0bb2023-01-11 09:46:29 +080012802
developera3511852023-06-14 14:12:59 +080012803 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080012804
developera3511852023-06-14 14:12:59 +080012805 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12806 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
12807 fprintf(stderr, "failed to parse nested rate attributes!");
12808 return NL_SKIP;
12809 }
12810 }
developer72fb0bb2023-01-11 09:46:29 +080012811
developera3511852023-06-14 14:12:59 +080012812 if(sinfo[NL80211_STA_INFO_TID_STATS])
12813 {
12814 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12815 printf("failed to parse nested stats attributes!");
12816 return NL_SKIP;
12817 }
12818 }
12819 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
12820 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
12821 {
12822 printf("Type is VHT\n");
12823 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12824 ((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 +080012825
developera3511852023-06-14 14:12:59 +080012826 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12827 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
12828 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12829 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12830 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12831 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12832 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12833 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12834 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
12835 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
12836 }
12837 else
12838 {
12839 printf(" OFDM or CCK \n");
12840 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
12841 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
12842 }
12843 }
developer72fb0bb2023-01-11 09:46:29 +080012844
developera3511852023-06-14 14:12:59 +080012845 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12846 if(rinfo[NL80211_RATE_INFO_MCS])
12847 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12848 }
developer72fb0bb2023-01-11 09:46:29 +080012849
developera3511852023-06-14 14:12:59 +080012850 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
12851 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
12852 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
12853 ((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 +080012854
developera3511852023-06-14 14:12:59 +080012855 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
12856 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
12857 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080012858
developera3511852023-06-14 14:12:59 +080012859 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12860 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12861 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
12862 }
developer72fb0bb2023-01-11 09:46:29 +080012863
developera3511852023-06-14 14:12:59 +080012864 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
12865 ((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 +080012866
developera3511852023-06-14 14:12:59 +080012867 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
12868 ((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 +080012869
developera3511852023-06-14 14:12:59 +080012870 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080012871}
developer72fb0bb2023-01-11 09:46:29 +080012872
12873INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12874{
developera3511852023-06-14 14:12:59 +080012875 Netlink nl;
12876 char if_name[IF_NAME_SIZE];
12877 char interface_name[IF_NAME_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080012878 int res;
12879
developera3511852023-06-14 14:12:59 +080012880 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12881 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012882
developera3511852023-06-14 14:12:59 +080012883 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
developer72fb0bb2023-01-11 09:46:29 +080012884
developera3511852023-06-14 14:12:59 +080012885 if (*output_array_size <= 0)
12886 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012887
developere40952c2023-06-15 18:46:43 +080012888 res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
12889 if (os_snprintf_error(sizeof(if_name), res)) {
12890 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12891 return RETURN_ERR;
12892 }
developer72fb0bb2023-01-11 09:46:29 +080012893
developera3511852023-06-14 14:12:59 +080012894 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080012895
developera3511852023-06-14 14:12:59 +080012896 if(nl.id < 0) {
12897 fprintf(stderr, "Error initializing netlink \n");
12898 return 0;
12899 }
developer72fb0bb2023-01-11 09:46:29 +080012900
developera3511852023-06-14 14:12:59 +080012901 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080012902
developera3511852023-06-14 14:12:59 +080012903 if(!msg) {
12904 fprintf(stderr, "Failed to allocate netlink message.\n");
12905 nlfree(&nl);
12906 return 0;
12907 }
developer72fb0bb2023-01-11 09:46:29 +080012908
developera3511852023-06-14 14:12:59 +080012909 genlmsg_put(msg,
12910 NL_AUTO_PID,
12911 NL_AUTO_SEQ,
12912 nl.id,
12913 0,
12914 0,
12915 NL80211_CMD_GET_STATION,
12916 0);
developer72fb0bb2023-01-11 09:46:29 +080012917
developera3511852023-06-14 14:12:59 +080012918 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12919 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12920 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
12921 nl_send_auto_complete(nl.socket, msg);
12922 nl_recvmsgs(nl.socket, nl.cb);
12923 nlmsg_free(msg);
12924 nlfree(&nl);
12925 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012926}
12927
12928INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
12929{
developera3511852023-06-14 14:12:59 +080012930 // TODO Implement me!
12931 char buf[MAX_BUF_SIZE] = {0};
12932 char config_file[MAX_BUF_SIZE] = {0};
developere40952c2023-06-15 18:46:43 +080012933 int res;
developer72fb0bb2023-01-11 09:46:29 +080012934
developere40952c2023-06-15 18:46:43 +080012935 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12936 if (os_snprintf_error(sizeof(config_file), res)) {
12937 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
12938 return RETURN_ERR;
12939 }
developera3511852023-06-14 14:12:59 +080012940 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
12941 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080012942
developera3511852023-06-14 14:12:59 +080012943 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012944}
12945
12946INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
12947{
developera3511852023-06-14 14:12:59 +080012948 char config_file[MAX_BUF_SIZE] = {0};
12949 struct params list;
developer72fb0bb2023-01-11 09:46:29 +080012950
developera3511852023-06-14 14:12:59 +080012951 list.name = "rrm_neighbor_report";
12952 list.value = activate?"1":"0";
12953 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12954 wifi_hostapdWrite(config_file, &list, 1);
developer72fb0bb2023-01-11 09:46:29 +080012955
developera3511852023-06-14 14:12:59 +080012956 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012957}
12958
12959INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
12960{
developera3511852023-06-14 14:12:59 +080012961 char buf[32] = {0};
12962 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012963
developera3511852023-06-14 14:12:59 +080012964 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12965 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
12966 *activate = (strncmp("1",buf,1) == 0);
developer72fb0bb2023-01-11 09:46:29 +080012967
developera3511852023-06-14 14:12:59 +080012968 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080012969}
12970#undef HAL_NETLINK_IMPL
12971#ifdef HAL_NETLINK_IMPL
12972static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
developera3511852023-06-14 14:12:59 +080012973 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12974 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12975 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
12976 char dev[20];
12977 int freq =0 ;
12978 static int i=0;
developer72fb0bb2023-01-11 09:46:29 +080012979
developera3511852023-06-14 14:12:59 +080012980 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
developer72fb0bb2023-01-11 09:46:29 +080012981
developera3511852023-06-14 14:12:59 +080012982 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
12983 };
developer72fb0bb2023-01-11 09:46:29 +080012984
developera3511852023-06-14 14:12:59 +080012985 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
developer72fb0bb2023-01-11 09:46:29 +080012986
developera3511852023-06-14 14:12:59 +080012987 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
developer72fb0bb2023-01-11 09:46:29 +080012988
developera3511852023-06-14 14:12:59 +080012989 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
12990 fprintf(stderr, "survey data missing!\n");
12991 return NL_SKIP;
12992 }
developer72fb0bb2023-01-11 09:46:29 +080012993
developera3511852023-06-14 14:12:59 +080012994 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
12995 {
12996 fprintf(stderr, "failed to parse nested attributes!\n");
12997 return NL_SKIP;
12998 }
developer72fb0bb2023-01-11 09:46:29 +080012999
13000
developera3511852023-06-14 14:12:59 +080013001 if(out[0].array_size == 1 )
13002 {
13003 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
13004 {
13005 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
13006 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
13007 out[0].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080013008
developera3511852023-06-14 14:12:59 +080013009 if (sinfo[NL80211_SURVEY_INFO_NOISE])
13010 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
13011 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
13012 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
13013 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
13014 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
13015 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
13016 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
13017 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
13018 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
13019 if (sinfo[NL80211_SURVEY_INFO_TIME])
13020 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
13021 return NL_STOP;
13022 }
13023 } else {
13024 if ( i <= out[0].array_size ) {
13025 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
13026 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
13027 out[i].ch_number = ieee80211_frequency_to_channel(freq);
developer72fb0bb2023-01-11 09:46:29 +080013028
developera3511852023-06-14 14:12:59 +080013029 if (sinfo[NL80211_SURVEY_INFO_NOISE])
13030 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
13031 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
13032 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
13033 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
13034 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
13035 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
13036 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
13037 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
13038 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
13039 if (sinfo[NL80211_SURVEY_INFO_TIME])
13040 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
13041 }
13042 }
developer72fb0bb2023-01-11 09:46:29 +080013043
developera3511852023-06-14 14:12:59 +080013044 i++;
13045 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080013046}
13047#endif
13048
13049static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
13050{
developera3511852023-06-14 14:12:59 +080013051 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
13052 FILE *fp;
developere40952c2023-06-15 18:46:43 +080013053 int res;
developer72fb0bb2023-01-11 09:46:29 +080013054
developera3511852023-06-14 14:12:59 +080013055 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
13056 {
13057 printf("Creating Frequency-Channel Map\n");
13058 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
13059 }
developere40952c2023-06-15 18:46:43 +080013060 res = snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
13061 if (os_snprintf_error(sizeof(command), res)) {
13062 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13063 return RETURN_ERR;
13064 }
13065
developera3511852023-06-14 14:12:59 +080013066 if((fp = popen(command, "r")))
13067 {
13068 fgets(output, sizeof(output), fp);
13069 *freqMHz = atoi(output);
13070 pclose(fp);
13071 }
developer72fb0bb2023-01-11 09:46:29 +080013072
developera3511852023-06-14 14:12:59 +080013073 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013074}
13075
developer2f79c922023-06-02 17:33:42 +080013076static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
developer72fb0bb2023-01-11 09:46:29 +080013077{
developera3511852023-06-14 14:12:59 +080013078 int freqMHz = -1;
13079 char cmd[MAX_CMD_SIZE] = {'\0'};
13080 char interface_name[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013081
developera3511852023-06-14 14:12:59 +080013082 ieee80211_channel_to_frequency(channel, &freqMHz);
13083 if (freqMHz == -1) {
13084 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
13085 return -1;
13086 }
developer72fb0bb2023-01-11 09:46:29 +080013087
developera3511852023-06-14 14:12:59 +080013088 wifi_GetInterfaceName(radioIndex, interface_name);
13089 if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) {
13090 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
13091 radioIndex, freqMHz);
13092 return -1;
13093 }
developer72fb0bb2023-01-11 09:46:29 +080013094
developera3511852023-06-14 14:12:59 +080013095 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
13096 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
13097 return -1;
13098 }
developer72fb0bb2023-01-11 09:46:29 +080013099
developera3511852023-06-14 14:12:59 +080013100 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013101}
13102
13103static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
13104{
developera3511852023-06-14 14:12:59 +080013105 const char *ptr = buf;
13106 char *key = NULL;
13107 char *val = NULL;
13108 char line[256] = { '\0' };
developer72fb0bb2023-01-11 09:46:29 +080013109
developera3511852023-06-14 14:12:59 +080013110 while ((ptr = get_line_from_str_buf(ptr, line))) {
13111 if (strstr(line, "Frequency")) continue;
developer72fb0bb2023-01-11 09:46:29 +080013112
developera3511852023-06-14 14:12:59 +080013113 key = strtok(line, ":");
13114 val = strtok(NULL, " ");
13115 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
developer72fb0bb2023-01-11 09:46:29 +080013116
developera3511852023-06-14 14:12:59 +080013117 if (!strcmp(key, "noise")) {
13118 sscanf(val, "%d", &stats->ch_noise);
13119 if (stats->ch_noise == 0) {
13120 // Workaround for missing noise information.
13121 // Assume -95 for 2.4G and -103 for 5G
13122 if (radioIndex == 0) stats->ch_noise = -95;
13123 if (radioIndex == 1) stats->ch_noise = -103;
13124 }
13125 }
13126 else if (!strcmp(key, "channel active time")) {
13127 sscanf(val, "%llu", &stats->ch_utilization_total);
13128 }
13129 else if (!strcmp(key, "channel busy time")) {
13130 sscanf(val, "%llu", &stats->ch_utilization_busy);
13131 }
13132 else if (!strcmp(key, "channel receive time")) {
13133 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
13134 }
13135 else if (!strcmp(key, "channel transmit time")) {
13136 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
13137 }
13138 };
developer72fb0bb2023-01-11 09:46:29 +080013139
developera3511852023-06-14 14:12:59 +080013140 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013141}
13142
13143INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
13144{
developera3511852023-06-14 14:12:59 +080013145 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013146#ifdef HAL_NETLINK_IMPL
developera3511852023-06-14 14:12:59 +080013147 Netlink nl;
13148 wifi_channelStats_t_loc local[array_size];
13149 char if_name[32];
developer72fb0bb2023-01-11 09:46:29 +080013150
developera3511852023-06-14 14:12:59 +080013151 local[0].array_size = array_size;
developer72fb0bb2023-01-11 09:46:29 +080013152
developera3511852023-06-14 14:12:59 +080013153 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
13154 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013155
developera3511852023-06-14 14:12:59 +080013156 nl.id = initSock80211(&nl);
developer72fb0bb2023-01-11 09:46:29 +080013157
developera3511852023-06-14 14:12:59 +080013158 if (nl.id < 0) {
13159 fprintf(stderr, "Error initializing netlink \n");
13160 return -1;
13161 }
developer72fb0bb2023-01-11 09:46:29 +080013162
developera3511852023-06-14 14:12:59 +080013163 struct nl_msg* msg = nlmsg_alloc();
developer72fb0bb2023-01-11 09:46:29 +080013164
developera3511852023-06-14 14:12:59 +080013165 if (!msg) {
13166 fprintf(stderr, "Failed to allocate netlink message.\n");
13167 nlfree(&nl);
13168 return -2;
13169 }
developer72fb0bb2023-01-11 09:46:29 +080013170
developera3511852023-06-14 14:12:59 +080013171 genlmsg_put(msg,
13172 NL_AUTO_PID,
13173 NL_AUTO_SEQ,
13174 nl.id,
13175 0,
13176 NLM_F_DUMP,
13177 NL80211_CMD_GET_SURVEY,
13178 0);
developer72fb0bb2023-01-11 09:46:29 +080013179
developera3511852023-06-14 14:12:59 +080013180 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
13181 nl_send_auto_complete(nl.socket, msg);
13182 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
13183 nl_recvmsgs(nl.socket, nl.cb);
13184 nlmsg_free(msg);
13185 nlfree(&nl);
13186 //Copying the Values
13187 for(int i=0;i<array_size;i++)
13188 {
13189 input_output_channelStats_array[i].ch_number = local[i].ch_number;
13190 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
13191 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
13192 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
13193 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
13194 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
13195 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
13196 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
13197 }
developer72fb0bb2023-01-11 09:46:29 +080013198#else
developera3511852023-06-14 14:12:59 +080013199 ULONG channel = 0;
13200 int i;
13201 int number_of_channels = array_size;
13202 char buf[512];
developer72fb0bb2023-01-11 09:46:29 +080013203
developera3511852023-06-14 14:12:59 +080013204 if (number_of_channels == 0) {
13205 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
13206 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
13207 return RETURN_ERR;
13208 }
13209 number_of_channels = 1;
13210 input_output_channelStats_array[0].ch_number = channel;
13211 }
developer72fb0bb2023-01-11 09:46:29 +080013212
developera3511852023-06-14 14:12:59 +080013213 for (i = 0; i < number_of_channels; i++) {
developer72fb0bb2023-01-11 09:46:29 +080013214
developera3511852023-06-14 14:12:59 +080013215 input_output_channelStats_array[i].ch_noise = 0;
13216 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
13217 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
13218 input_output_channelStats_array[i].ch_utilization_busy = 0;
13219 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
13220 input_output_channelStats_array[i].ch_utilization_total = 0;
developer72fb0bb2023-01-11 09:46:29 +080013221
developera3511852023-06-14 14:12:59 +080013222 memset(buf, 0, sizeof(buf));
13223 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
13224 return RETURN_ERR;
13225 }
13226 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
13227 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
13228 return RETURN_ERR;
13229 }
developer72fb0bb2023-01-11 09:46:29 +080013230
developera3511852023-06-14 14:12:59 +080013231 // XXX: fake missing 'self' counter which is not available in iw survey output
13232 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
13233 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 +080013234
developera3511852023-06-14 14:12:59 +080013235 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
13236 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
13237 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
13238 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
13239 input_output_channelStats_array[i].ch_utilization_total *= 1000;
developer72fb0bb2023-01-11 09:46:29 +080013240
developera3511852023-06-14 14:12:59 +080013241 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",
13242 __func__,
13243 input_output_channelStats_array[i].ch_number,
13244 input_output_channelStats_array[i].ch_noise,
13245 input_output_channelStats_array[i].ch_utilization_total,
13246 input_output_channelStats_array[i].ch_utilization_busy,
13247 input_output_channelStats_array[i].ch_utilization_busy_rx,
13248 input_output_channelStats_array[i].ch_utilization_busy_tx,
13249 input_output_channelStats_array[i].ch_utilization_busy_self,
13250 input_output_channelStats_array[i].ch_utilization_busy_ext);
13251 }
developer72fb0bb2023-01-11 09:46:29 +080013252#endif
developera3511852023-06-14 14:12:59 +080013253 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13254 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013255}
13256#define HAL_NETLINK_IMPL
13257
13258/* Hostapd events */
13259
13260#ifndef container_of
13261#define offset_of(st, m) ((size_t)&(((st *)0)->m))
13262#define container_of(ptr, type, member) \
developera3511852023-06-14 14:12:59 +080013263 ((type *)((char *)ptr - offset_of(type, member)))
developer72fb0bb2023-01-11 09:46:29 +080013264#endif /* container_of */
13265
13266struct ctrl {
developera3511852023-06-14 14:12:59 +080013267 char sockpath[128];
13268 char sockdir[128];
13269 char bss[IFNAMSIZ];
13270 char reply[4096];
13271 int ssid_index;
13272 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
13273 void (*overrun)(struct ctrl *ctrl);
13274 struct wpa_ctrl *wpa;
13275 unsigned int ovfl;
13276 size_t reply_len;
13277 int initialized;
13278 ev_timer retry;
13279 ev_timer watchdog;
13280 ev_stat stat;
13281 ev_io io;
developer72fb0bb2023-01-11 09:46:29 +080013282};
13283static wifi_newApAssociatedDevice_callback clients_connect_cb;
13284static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
13285static struct ctrl wpa_ctrl[MAX_APS];
13286static int initialized;
13287
13288static unsigned int ctrl_get_drops(struct ctrl *ctrl)
13289{
developera3511852023-06-14 14:12:59 +080013290 char cbuf[256] = {};
13291 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
13292 struct cmsghdr *cmsg;
13293 unsigned int ovfl = ctrl->ovfl;
13294 unsigned int drop;
developer72fb0bb2023-01-11 09:46:29 +080013295
developera3511852023-06-14 14:12:59 +080013296 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
13297 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
13298 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
13299 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
developer72fb0bb2023-01-11 09:46:29 +080013300
developera3511852023-06-14 14:12:59 +080013301 drop = ovfl - ctrl->ovfl;
13302 ctrl->ovfl = ovfl;
developer72fb0bb2023-01-11 09:46:29 +080013303
developera3511852023-06-14 14:12:59 +080013304 return drop;
developer72fb0bb2023-01-11 09:46:29 +080013305}
13306
13307static void ctrl_close(struct ctrl *ctrl)
13308{
developera3511852023-06-14 14:12:59 +080013309 if (ctrl->io.cb)
13310 ev_io_stop(EV_DEFAULT_ &ctrl->io);
13311 if (ctrl->retry.cb)
13312 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
13313 if (!ctrl->wpa)
13314 return;
developer72fb0bb2023-01-11 09:46:29 +080013315
developera3511852023-06-14 14:12:59 +080013316 wpa_ctrl_detach(ctrl->wpa);
13317 wpa_ctrl_close(ctrl->wpa);
13318 ctrl->wpa = NULL;
13319 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
developer72fb0bb2023-01-11 09:46:29 +080013320}
13321
13322static void ctrl_process(struct ctrl *ctrl)
13323{
developera3511852023-06-14 14:12:59 +080013324 const char *str;
13325 int drops;
13326 int level;
developer72fb0bb2023-01-11 09:46:29 +080013327
developera3511852023-06-14 14:12:59 +080013328 /* Example events:
13329 *
13330 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
13331 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
13332 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
13333 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
13334 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
13335 */
13336 if (!(str = index(ctrl->reply, '>')))
13337 return;
13338 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
13339 return;
developer72fb0bb2023-01-11 09:46:29 +080013340
developera3511852023-06-14 14:12:59 +080013341 str++;
developer72fb0bb2023-01-11 09:46:29 +080013342
developera3511852023-06-14 14:12:59 +080013343 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
13344 if (!(str = index(ctrl->reply, ' ')))
13345 return;
13346 wifi_associated_dev_t sta;
13347 memset(&sta, 0, sizeof(sta));
developer72fb0bb2023-01-11 09:46:29 +080013348
developera3511852023-06-14 14:12:59 +080013349 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
13350 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
13351 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
developer72fb0bb2023-01-11 09:46:29 +080013352
developera3511852023-06-14 14:12:59 +080013353 sta.cli_Active=true;
developer72fb0bb2023-01-11 09:46:29 +080013354
developera3511852023-06-14 14:12:59 +080013355 (clients_connect_cb)(ctrl->ssid_index, &sta);
13356 goto handled;
13357 }
developer72fb0bb2023-01-11 09:46:29 +080013358
developera3511852023-06-14 14:12:59 +080013359 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
13360 if (!(str = index(ctrl->reply, ' ')))
13361 return;
developer72fb0bb2023-01-11 09:46:29 +080013362
developera3511852023-06-14 14:12:59 +080013363 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
13364 goto handled;
13365 }
developer72fb0bb2023-01-11 09:46:29 +080013366
developera3511852023-06-14 14:12:59 +080013367 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
13368 printf("CTRL_WPA: handle TERMINATING event\n");
13369 goto retry;
13370 }
developer72fb0bb2023-01-11 09:46:29 +080013371
developera3511852023-06-14 14:12:59 +080013372 if (strncmp("AP-DISABLED", str, 11) == 0) {
13373 printf("CTRL_WPA: handle AP-DISABLED\n");
13374 goto retry;
13375 }
developer72fb0bb2023-01-11 09:46:29 +080013376
developera3511852023-06-14 14:12:59 +080013377 printf("Event not supported!!\n");
developer72fb0bb2023-01-11 09:46:29 +080013378
13379handled:
13380
developera3511852023-06-14 14:12:59 +080013381 if ((drops = ctrl_get_drops(ctrl))) {
13382 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
13383 if (ctrl->overrun)
13384 ctrl->overrun(ctrl);
13385 }
developer72fb0bb2023-01-11 09:46:29 +080013386
developera3511852023-06-14 14:12:59 +080013387 return;
developer72fb0bb2023-01-11 09:46:29 +080013388
13389retry:
developera3511852023-06-14 14:12:59 +080013390 printf("WPA_CTRL: closing\n");
13391 ctrl_close(ctrl);
13392 printf("WPA_CTRL: retrying from ctrl prcoess\n");
13393 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
developer72fb0bb2023-01-11 09:46:29 +080013394}
13395
13396static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
13397{
developera3511852023-06-14 14:12:59 +080013398 struct ctrl *ctrl = container_of(io, struct ctrl, io);
13399 int err;
developer72fb0bb2023-01-11 09:46:29 +080013400
developera3511852023-06-14 14:12:59 +080013401 memset(ctrl->reply, 0, sizeof(ctrl->reply));
13402 ctrl->reply_len = sizeof(ctrl->reply) - 1;
13403 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
13404 ctrl->reply[ctrl->reply_len] = 0;
13405 if (err < 0) {
13406 if (errno == EAGAIN || errno == EWOULDBLOCK)
13407 return;
13408 ctrl_close(ctrl);
13409 ev_timer_again(EV_A_ &ctrl->retry);
13410 return;
13411 }
developer72fb0bb2023-01-11 09:46:29 +080013412
developera3511852023-06-14 14:12:59 +080013413 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080013414}
13415
13416static int ctrl_open(struct ctrl *ctrl)
13417{
developera3511852023-06-14 14:12:59 +080013418 int fd;
developer72fb0bb2023-01-11 09:46:29 +080013419
developera3511852023-06-14 14:12:59 +080013420 if (ctrl->wpa)
13421 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013422
developera3511852023-06-14 14:12:59 +080013423 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
13424 if (!ctrl->wpa)
13425 goto err;
developer72fb0bb2023-01-11 09:46:29 +080013426
developera3511852023-06-14 14:12:59 +080013427 if (wpa_ctrl_attach(ctrl->wpa) < 0)
13428 goto err_close;
developer72fb0bb2023-01-11 09:46:29 +080013429
developera3511852023-06-14 14:12:59 +080013430 fd = wpa_ctrl_get_fd(ctrl->wpa);
13431 if (fd < 0)
13432 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080013433
developera3511852023-06-14 14:12:59 +080013434 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
13435 goto err_detach;
developer72fb0bb2023-01-11 09:46:29 +080013436
developera3511852023-06-14 14:12:59 +080013437 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
13438 ev_io_start(EV_DEFAULT_ &ctrl->io);
developer72fb0bb2023-01-11 09:46:29 +080013439
developera3511852023-06-14 14:12:59 +080013440 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013441
13442err_detach:
developera3511852023-06-14 14:12:59 +080013443 wpa_ctrl_detach(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080013444err_close:
developera3511852023-06-14 14:12:59 +080013445 wpa_ctrl_close(ctrl->wpa);
developer72fb0bb2023-01-11 09:46:29 +080013446err:
developera3511852023-06-14 14:12:59 +080013447 ctrl->wpa = NULL;
13448 return -1;
developer72fb0bb2023-01-11 09:46:29 +080013449}
13450
13451static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
13452{
developera3511852023-06-14 14:12:59 +080013453 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
developer72fb0bb2023-01-11 09:46:29 +080013454
developera3511852023-06-14 14:12:59 +080013455 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
13456 ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080013457}
13458
13459static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
13460{
developera3511852023-06-14 14:12:59 +080013461 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
developer72fb0bb2023-01-11 09:46:29 +080013462
developera3511852023-06-14 14:12:59 +080013463 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
13464 if (ctrl_open(ctrl) == 0) {
13465 printf("WPA_CTRL: retry successful\n");
13466 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
13467 }
developer72fb0bb2023-01-11 09:46:29 +080013468}
13469
13470int ctrl_enable(struct ctrl *ctrl)
13471{
developera3511852023-06-14 14:12:59 +080013472 if (ctrl->wpa)
13473 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013474
developera3511852023-06-14 14:12:59 +080013475 if (!ctrl->stat.cb) {
13476 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
13477 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
13478 }
developer72fb0bb2023-01-11 09:46:29 +080013479
developera3511852023-06-14 14:12:59 +080013480 if (!ctrl->retry.cb) {
13481 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
13482 }
developer72fb0bb2023-01-11 09:46:29 +080013483
developera3511852023-06-14 14:12:59 +080013484 return ctrl_open(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080013485}
13486
13487static void
13488ctrl_msg_cb(char *buf, size_t len)
13489{
developera3511852023-06-14 14:12:59 +080013490 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
developer72fb0bb2023-01-11 09:46:29 +080013491
developera3511852023-06-14 14:12:59 +080013492 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
13493 ctrl_process(ctrl);
developer72fb0bb2023-01-11 09:46:29 +080013494}
13495
13496static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
13497{
developera3511852023-06-14 14:12:59 +080013498 int err;
developer72fb0bb2023-01-11 09:46:29 +080013499
developera3511852023-06-14 14:12:59 +080013500 if (!ctrl->wpa)
13501 return -1;
13502 if (*reply_len < 2)
13503 return -1;
developer72fb0bb2023-01-11 09:46:29 +080013504
developera3511852023-06-14 14:12:59 +080013505 (*reply_len)--;
13506 ctrl->reply_len = sizeof(ctrl->reply);
13507 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
13508 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
13509 if (err < 0)
13510 return err;
developer72fb0bb2023-01-11 09:46:29 +080013511
developera3511852023-06-14 14:12:59 +080013512 if (ctrl->reply_len > *reply_len)
13513 ctrl->reply_len = *reply_len;
developer72fb0bb2023-01-11 09:46:29 +080013514
developera3511852023-06-14 14:12:59 +080013515 *reply_len = ctrl->reply_len;
13516 memcpy(reply, ctrl->reply, *reply_len);
13517 reply[*reply_len - 1] = 0;
13518 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
13519 return 0;
developer72fb0bb2023-01-11 09:46:29 +080013520}
13521
13522static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
13523{
developera3511852023-06-14 14:12:59 +080013524 const char *pong = "PONG";
13525 const char *ping = "PING";
13526 char reply[1024];
13527 size_t len = sizeof(reply);
13528 int err;
13529 ULONG s, snum;
13530 INT ret;
13531 BOOL status;
developer72fb0bb2023-01-11 09:46:29 +080013532
developera3511852023-06-14 14:12:59 +080013533 printf("WPA_CTRL: watchdog cb\n");
developer72fb0bb2023-01-11 09:46:29 +080013534
developera3511852023-06-14 14:12:59 +080013535 ret = wifi_getSSIDNumberOfEntries(&snum);
13536 if (ret != RETURN_OK) {
13537 printf("%s: failed to get SSID count", __func__);
13538 return;
13539 }
developer72fb0bb2023-01-11 09:46:29 +080013540
developera3511852023-06-14 14:12:59 +080013541 if (snum > MAX_APS) {
13542 printf("more ssid than supported! %lu\n", snum);
13543 return;
13544 }
developer72fb0bb2023-01-11 09:46:29 +080013545
developera3511852023-06-14 14:12:59 +080013546 for (s = 0; s < snum; s++) {
13547 if (wifi_getApEnable(s, &status) != RETURN_OK) {
13548 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
13549 continue;
13550 }
13551 if (status == false) continue;
developer72fb0bb2023-01-11 09:46:29 +080013552
developera3511852023-06-14 14:12:59 +080013553 memset(reply, 0, sizeof(reply));
13554 len = sizeof(reply);
13555 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
13556 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
13557 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
13558 continue;
developer72fb0bb2023-01-11 09:46:29 +080013559
developera3511852023-06-14 14:12:59 +080013560 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
13561 ctrl_close(&wpa_ctrl[s]);
13562 printf("WPA_CTRL: ev_timer_again %lu\n", s);
13563 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
13564 }
developer72fb0bb2023-01-11 09:46:29 +080013565}
13566
13567static int init_wpa()
13568{
developera3511852023-06-14 14:12:59 +080013569 int ret = 0;
13570 ULONG s, snum;
developer72fb0bb2023-01-11 09:46:29 +080013571
developera3511852023-06-14 14:12:59 +080013572 ret = wifi_getSSIDNumberOfEntries(&snum);
13573 if (ret != RETURN_OK) {
13574 printf("%s: failed to get SSID count", __func__);
13575 return RETURN_ERR;
13576 }
developer72fb0bb2023-01-11 09:46:29 +080013577
developera3511852023-06-14 14:12:59 +080013578 if (snum > MAX_APS) {
13579 printf("more ssid than supported! %lu\n", snum);
13580 return RETURN_ERR;
13581 }
developer72fb0bb2023-01-11 09:46:29 +080013582
developera3511852023-06-14 14:12:59 +080013583 for (s = 0; s < snum; s++) {
13584 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
13585 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
13586 wpa_ctrl[s].ssid_index = s;
13587 ctrl_enable(&wpa_ctrl[s]);
13588 }
developer72fb0bb2023-01-11 09:46:29 +080013589
developera3511852023-06-14 14:12:59 +080013590 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
13591 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
developer72fb0bb2023-01-11 09:46:29 +080013592
developera3511852023-06-14 14:12:59 +080013593 initialized = 1;
13594 printf("WPA_CTRL: initialized\n");
developer72fb0bb2023-01-11 09:46:29 +080013595
developera3511852023-06-14 14:12:59 +080013596 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013597}
13598
13599void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
13600{
developera3511852023-06-14 14:12:59 +080013601 clients_connect_cb = callback_proc;
13602 if (!initialized)
13603 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080013604}
13605
13606void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
13607{
developera3511852023-06-14 14:12:59 +080013608 clients_disconnect_cb = callback_proc;
13609 if (!initialized)
13610 init_wpa();
developer72fb0bb2023-01-11 09:46:29 +080013611}
13612
13613INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
13614{
developera3511852023-06-14 14:12:59 +080013615 // TODO Implement me!
13616 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013617}
13618
13619INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
13620{
developera3511852023-06-14 14:12:59 +080013621 // TODO Implement me!
13622 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013623}
13624
13625INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
13626{
developera3511852023-06-14 14:12:59 +080013627 int i;
13628 int phyId = -1;
13629 char cmd[256] = {0};
13630 char channel_numbers_buf[256] = {0};
13631 char dfs_state_buf[256] = {0};
13632 char line[256] = {0};
13633 const char *ptr;
13634 BOOL dfs_enable = false;
developere40952c2023-06-15 18:46:43 +080013635 int res;
developer72fb0bb2023-01-11 09:46:29 +080013636
developera3511852023-06-14 14:12:59 +080013637 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080013638
developera3511852023-06-14 14:12:59 +080013639 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
13640 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013641
developere40952c2023-06-15 18:46:43 +080013642 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\\|");
13643 if (os_snprintf_error(sizeof(cmd), res)) {
13644 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13645 return RETURN_ERR;
13646 }
developer72fb0bb2023-01-11 09:46:29 +080013647
developera3511852023-06-14 14:12:59 +080013648 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
13649 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13650 return RETURN_ERR;
13651 }
developer72fb0bb2023-01-11 09:46:29 +080013652
developera3511852023-06-14 14:12:59 +080013653 ptr = channel_numbers_buf;
13654 i = 0;
13655 while ((ptr = get_line_from_str_buf(ptr, line))) {
13656 if (i >= outputMapSize) {
13657 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
13658 return RETURN_ERR;
13659 }
13660 sscanf(line, "%d", &outputMap[i].ch_number);
developerd1824452023-05-18 12:30:04 +080013661
developera3511852023-06-14 14:12:59 +080013662 memset(cmd, 0, sizeof(cmd));
13663 // Below command should fetch string for DFS state (usable, available or unavailable)
13664 // Example line: "DFS state: usable (for 78930 sec)"
13665 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) {
13666 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
13667 return RETURN_ERR;
13668 }
developer72fb0bb2023-01-11 09:46:29 +080013669
developera3511852023-06-14 14:12:59 +080013670 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
13671 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
13672 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13673 return RETURN_ERR;
13674 }
developer72fb0bb2023-01-11 09:46:29 +080013675
developera3511852023-06-14 14:12:59 +080013676 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080013677
developera3511852023-06-14 14:12:59 +080013678 if (!strcmp(dfs_state_buf, "usable")) {
13679 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
13680 } else if (!strcmp(dfs_state_buf, "available")) {
13681 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
13682 } else if (!strcmp(dfs_state_buf, "unavailable")) {
13683 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
13684 } else {
13685 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
13686 }
13687 i++;
13688 }
developer40ba1762023-05-13 11:03:49 +080013689
developera3511852023-06-14 14:12:59 +080013690 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +080013691
developera3511852023-06-14 14:12:59 +080013692 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
13693 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013694}
13695
13696INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
13697{
developera3511852023-06-14 14:12:59 +080013698 // TODO Implement me!
13699 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013700}
13701
13702INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
13703{
developera3511852023-06-14 14:12:59 +080013704 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013705}
13706
13707INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
13708{
developera3511852023-06-14 14:12:59 +080013709 // TODO Implement me!
13710 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013711}
13712
13713INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
13714{
developera3511852023-06-14 14:12:59 +080013715 // TODO API refrence Implementaion is present on RPI hal
13716 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013717}
13718
13719INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
13720{
developera3511852023-06-14 14:12:59 +080013721 ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080013722
developera3511852023-06-14 14:12:59 +080013723 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13724 if(txpwr_pcntg == NULL)
developerdaf24792023-06-06 11:40:04 +080013725 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013726
developera1255e42023-05-13 17:45:02 +080013727 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
13728 *txpwr_pcntg = pwr_percentage;
developera3511852023-06-14 14:12:59 +080013729 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13730 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013731}
13732
13733INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
13734{
developera3511852023-06-14 14:12:59 +080013735 // TODO precac feature.
13736 struct params params[2] = {0};
13737 char config_file[128] = {0};
13738 BOOL dfs_enable = false;
13739 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080013740 int res;
developer72fb0bb2023-01-11 09:46:29 +080013741
developera3511852023-06-14 14:12:59 +080013742 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13743 band = wifi_index_to_band(radioIndex);
13744 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080013745
developera3511852023-06-14 14:12:59 +080013746 if (dfs_enable == false) {
13747 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
13748 return RETURN_ERR;
13749 }
13750 params[0].name = "DfsZeroWaitDefault";
13751 params[0].value = enable?"1":"0";
13752 params[1].name = "DfsDedicatedZeroWait";
13753 params[1].value = enable?"1":"0";
developere40952c2023-06-15 18:46:43 +080013754 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13755 if (os_snprintf_error(sizeof(config_file), res)) {
13756 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13757 return RETURN_ERR;
13758 }
developera3511852023-06-14 14:12:59 +080013759 wifi_datfileWrite(config_file, params, 2);
13760 wifi_reloadAp(radioIndex);
13761 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080013762
developera3511852023-06-14 14:12:59 +080013763 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13764 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013765}
13766
13767INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
13768{
developera3511852023-06-14 14:12:59 +080013769 char config_file[128] = {0};
13770 char buf1[32] = {0};
13771 char buf2[32] = {0};
13772 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080013773 int res;
developer72fb0bb2023-01-11 09:46:29 +080013774
developera3511852023-06-14 14:12:59 +080013775 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13776 if (NULL == enable || NULL == precac)
13777 return RETURN_ERR;
13778 band = wifi_index_to_band(radioIndex);
developere40952c2023-06-15 18:46:43 +080013779 res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13780 if (os_snprintf_error(sizeof(config_file), res)) {
13781 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13782 return RETURN_ERR;
13783 }
developera3511852023-06-14 14:12:59 +080013784 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
13785 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
13786 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
13787 *enable = true;
13788 else
13789 *enable = false;
developer72fb0bb2023-01-11 09:46:29 +080013790
developera3511852023-06-14 14:12:59 +080013791 /* TODO precac feature */
developer72fb0bb2023-01-11 09:46:29 +080013792
developera3511852023-06-14 14:12:59 +080013793 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13794 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013795}
13796
13797INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
13798{
developera3511852023-06-14 14:12:59 +080013799 *supported = TRUE;
13800 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013801}
13802
13803INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
13804{
developer863a4a62023-06-06 16:55:59 +080013805 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080013806 wifi_band band = band_invalid;
13807 char ofdmabuf[32] = {'\0'};
13808 char mimobuf[32] = {'\0'};
13809 char new_ofdmabuf[32] = {'\0'};
13810 char new_mimobuf[32] = {'\0'};
13811 struct params params[2];
developera1255e42023-05-13 17:45:02 +080013812 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13813 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13814 UCHAR bss_cnt = 0;
13815 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080013816 int res;
developer72fb0bb2023-01-11 09:46:29 +080013817
developera3511852023-06-14 14:12:59 +080013818 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +080013819 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
13820 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
13821 printf("%s:mu_type input Error", __func__);
13822 return RETURN_ERR;
13823 }
developera3511852023-06-14 14:12:59 +080013824 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080013825 if (band == band_invalid) {
13826 printf("%s:Band Error\n", __func__);
13827 return RETURN_ERR;
13828 }
developere40952c2023-06-15 18:46:43 +080013829 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13830 if (os_snprintf_error(sizeof(dat_file), res)) {
13831 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13832 return RETURN_ERR;
13833 }
13834
developera1255e42023-05-13 17:45:02 +080013835 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080013836 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13837 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080013838 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13839 get_bssnum_byindex(radio_index, &bss_cnt);
13840 val_cnt = 2*bss_cnt - 1;
13841 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
13842 if ((val_cnt >= sizeof(new_ofdmabuf))
13843 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080013844 printf("%s:bss cnt Error", __func__);
developera1255e42023-05-13 17:45:02 +080013845 return RETURN_ERR;
13846 }
13847 /*translate set value*/
13848 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
13849 strncpy(new_ofdmabuf, str_zero, val_cnt);
13850 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080013851 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080013852 strncpy(new_ofdmabuf, str_one, val_cnt);
13853 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080013854 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080013855 strncpy(new_ofdmabuf, str_zero, val_cnt);
13856 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080013857 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
developera1255e42023-05-13 17:45:02 +080013858 strncpy(new_ofdmabuf, str_one, val_cnt);
13859 strncpy(new_mimobuf, str_one, val_cnt);
developera3511852023-06-14 14:12:59 +080013860 }
developera1255e42023-05-13 17:45:02 +080013861 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13862 /*same value, not operation*/
13863 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13864 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13865 printf("%s:Reduntant value\n", __func__);
13866 return RETURN_OK;
13867 }
13868 /*modify dat file to new file*/
13869 params[0].name="MuOfdmaDlEnable";
13870 params[0].value=new_ofdmabuf;
13871 params[1].name="MuMimoDlEnable";
13872 params[1].value=new_mimobuf;
13873 wifi_datfileWrite(dat_file, params, 2);
13874 /*hostapd control restarp ap to take effect on these new value*/
13875 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080013876 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13877 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013878}
13879
13880INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
13881{
developer5a333cf2023-06-06 18:18:50 +080013882 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080013883 wifi_band band = band_invalid;
13884 char ofdmabuf[32] = {'\0'};
13885 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080013886 char *token = NULL;
13887 UCHAR ofdma = 0;
13888 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080013889 int res;
developer72fb0bb2023-01-11 09:46:29 +080013890
developera3511852023-06-14 14:12:59 +080013891 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080013892
developera3511852023-06-14 14:12:59 +080013893 if (mu_type == NULL)
13894 return RETURN_ERR;
13895 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080013896 if (band == band_invalid) {
13897 printf("%s:Band Error\n", __func__);
13898 return RETURN_ERR;
13899 }
developere40952c2023-06-15 18:46:43 +080013900 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13901 if (os_snprintf_error(sizeof(dat_file), res)) {
13902 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13903 return RETURN_ERR;
13904 }
developera1255e42023-05-13 17:45:02 +080013905 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080013906 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13907 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013908
developera1255e42023-05-13 17:45:02 +080013909 token = strtok(ofdmabuf, ";");
13910 ofdma = strtol(token, NULL, 10);
13911 token = strtok(mimobuf, ";");
13912 mimo = strtol(token, NULL, 10);
13913 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
13914 if ((ofdma == 1) && (mimo == 1))
13915 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
13916 else if ((ofdma == 0) && (mimo == 1))
13917 *mu_type = WIFI_DL_MU_TYPE_MIMO;
13918 else if ((ofdma == 1) && (mimo == 0))
13919 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
13920 else
13921 *mu_type = WIFI_DL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080013922 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13923 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013924}
13925
13926INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
13927{
developera3511852023-06-14 14:12:59 +080013928 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developer863a4a62023-06-06 16:55:59 +080013929 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080013930 wifi_band band = band_invalid;
13931 char ofdmabuf[32] = {'\0'};
13932 char mimobuf[32] = {'\0'};
13933 char new_ofdmabuf[32] = {'\0'};
13934 char new_mimobuf[32] = {'\0'};
13935 struct params params[2];
developera1255e42023-05-13 17:45:02 +080013936 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13937 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13938 UCHAR bss_cnt = 0;
13939 UCHAR val_cnt = 0;
developere40952c2023-06-15 18:46:43 +080013940 int res;
developer72fb0bb2023-01-11 09:46:29 +080013941
developera3511852023-06-14 14:12:59 +080013942 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13943 band = wifi_index_to_band(radio_index);
developera1255e42023-05-13 17:45:02 +080013944 if (band == band_invalid) {
13945 printf("%s:Band Error\n", __func__);
13946 return RETURN_ERR;
13947 }
13948 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
13949 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
13950 printf("%s:mu_type input Error\n", __func__);
13951 return RETURN_ERR;
13952 }
developere40952c2023-06-15 18:46:43 +080013953 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13954 if (os_snprintf_error(sizeof(dat_file), res)) {
13955 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
13956 return RETURN_ERR;
13957 }
developera1255e42023-05-13 17:45:02 +080013958 /*get current value in dat file*/
developera3511852023-06-14 14:12:59 +080013959 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13960 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developera1255e42023-05-13 17:45:02 +080013961 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13962 get_bssnum_byindex(radio_index, &bss_cnt);
13963 val_cnt = 2*bss_cnt - 1;
13964 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
13965 if ((val_cnt >= sizeof(new_ofdmabuf))
13966 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080013967 printf("%s:bss cnt Error\n", __func__);
developera1255e42023-05-13 17:45:02 +080013968 return RETURN_ERR;
13969 }
13970 /*translate set value*/
13971 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
13972 strncpy(new_ofdmabuf, str_zero, val_cnt);
13973 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080013974 }
developera1255e42023-05-13 17:45:02 +080013975 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
13976 strncpy(new_ofdmabuf, str_one, val_cnt);
13977 strncpy(new_mimobuf, str_zero, val_cnt);
developera3511852023-06-14 14:12:59 +080013978 }
developera1255e42023-05-13 17:45:02 +080013979 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13980 /*same value, not operation*/
13981 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13982 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13983 printf("%s:Reduntant value\n", __func__);
13984 return RETURN_OK;
13985 }
13986 /*modify dat file to new file*/
13987 params[0].name="MuOfdmaUlEnable";
13988 params[0].value=new_ofdmabuf;
13989 params[1].name="MuMimoUlEnable";
13990 params[1].value=new_mimobuf;
13991 wifi_datfileWrite(dat_file, params, 2);
13992 wifi_reloadAp(radio_index);
developera3511852023-06-14 14:12:59 +080013993 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13994 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080013995}
13996
13997INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
13998{
developer863a4a62023-06-06 16:55:59 +080013999 CHAR dat_file[64] = {0};
developera3511852023-06-14 14:12:59 +080014000 wifi_band band = band_invalid;
14001 char ofdmabuf[32] = {'\0'};
14002 char mimobuf[32] = {'\0'};
developera1255e42023-05-13 17:45:02 +080014003 char *token = NULL;
14004 UCHAR ofdma = 0;
14005 UCHAR mimo = 0;
developere40952c2023-06-15 18:46:43 +080014006 int res;
developer72fb0bb2023-01-11 09:46:29 +080014007
developera3511852023-06-14 14:12:59 +080014008 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014009
developera3511852023-06-14 14:12:59 +080014010 if (mu_type == NULL)
14011 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080014012 band = wifi_index_to_band(radio_index);
14013 if (band == band_invalid) {
14014 printf("%s:Band Error", __func__);
14015 return RETURN_ERR;
14016 }
developere40952c2023-06-15 18:46:43 +080014017 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
14018 if (os_snprintf_error(sizeof(dat_file), res)) {
14019 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14020 return RETURN_ERR;
14021 }
developera1255e42023-05-13 17:45:02 +080014022 /*get current value in dat file*/
14023 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
14024 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080014025
developera1255e42023-05-13 17:45:02 +080014026 token = strtok(ofdmabuf, ";");
14027 ofdma = strtol(token, NULL, 10);
14028 token = strtok(mimobuf, ";");
14029 mimo = strtol(token, NULL, 10);
14030 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
14031 if ((ofdma == 1) && (mimo == 0))
14032 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
14033 else
14034 *mu_type = WIFI_UL_MU_TYPE_NONE;
developera3511852023-06-14 14:12:59 +080014035 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14036 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014037}
14038
14039
14040INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
14041{
developera3511852023-06-14 14:12:59 +080014042 char cmd[128] = {0};
14043 char buf[256] = {0};
14044 char config_file[64] = {0};
14045 char GI[8] = {0};
14046 UINT mode_map = 0;
14047 FILE *f = NULL;
14048 wifi_band band = band_invalid;
14049 char dat_file[64] = {'\0'};
14050 struct params params[3];
developere40952c2023-06-15 18:46:43 +080014051 int res;
developer72fb0bb2023-01-11 09:46:29 +080014052
developera3511852023-06-14 14:12:59 +080014053 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014054
developera3511852023-06-14 14:12:59 +080014055 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
14056 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
14057 return RETURN_ERR;
14058 }
developera1255e42023-05-13 17:45:02 +080014059 /*sanity check*/
14060 if (((guard_interval == wifi_guard_interval_1600)
14061 || (guard_interval == wifi_guard_interval_3200))
developerdaf24792023-06-06 11:40:04 +080014062 && ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
developera3511852023-06-14 14:12:59 +080014063 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
14064 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080014065 }
developere40952c2023-06-15 18:46:43 +080014066 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
14067 if (os_snprintf_error(sizeof(config_file), res)) {
14068 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14069 return RETURN_ERR;
14070 }
developera3511852023-06-14 14:12:59 +080014071 band = wifi_index_to_band(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080014072
developera3511852023-06-14 14:12:59 +080014073 // Hostapd are not supported HE mode GI 1600, 3200 ns.
14074 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
developere40952c2023-06-15 18:46:43 +080014075 res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
14076 if (os_snprintf_error(sizeof(cmd), res)) {
14077 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14078 return RETURN_ERR;
14079 }
developera3511852023-06-14 14:12:59 +080014080 _syscmd(cmd, buf, sizeof(buf));
14081 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
14082 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
14083 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080014084 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
14085 if (os_snprintf_error(sizeof(cmd), res)) {
14086 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14087 return RETURN_ERR;
14088 }
developera3511852023-06-14 14:12:59 +080014089 _syscmd(cmd, buf, sizeof(buf));
14090 }
14091 if (band == band_5) {
14092 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
14093 if (strstr(buf, "[SHORT-GI-") == NULL) {
developere40952c2023-06-15 18:46:43 +080014094 res = snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
14095 if (os_snprintf_error(sizeof(cmd), res)) {
14096 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14097 return RETURN_ERR;
14098 }
developera3511852023-06-14 14:12:59 +080014099 _syscmd(cmd, buf, sizeof(buf));
14100 }
14101 }
14102 }
14103 /*wifi_reloadAp(radio_index);
developera1255e42023-05-13 17:45:02 +080014104 caller "wifi_setRadioOperatingParameters" have done this step.
14105 */
developere40952c2023-06-15 18:46:43 +080014106 res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
14107 if (os_snprintf_error(sizeof(dat_file), res)) {
14108 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14109 return RETURN_ERR;
14110 }
developera3511852023-06-14 14:12:59 +080014111 if (guard_interval == wifi_guard_interval_400) {
developera1255e42023-05-13 17:45:02 +080014112 params[0].name = "HT_GI";
14113 params[0].value = "1";
14114 params[1].name = "VHT_SGI";
14115 params[1].value = "1";
14116 wifi_datfileWrite(dat_file, params, 2);
developera3511852023-06-14 14:12:59 +080014117 strcpy(GI, "0.4");
developera1255e42023-05-13 17:45:02 +080014118 } else {
14119 params[0].name = "HT_GI";
14120 params[0].value = "0";
14121 params[1].name = "VHT_SGI";
14122 params[1].value = "0";
14123 /*should enable FIXED_HE_GI_SUPPORT in driver*/
14124 params[2].name = "FgiFltf";
14125 if (guard_interval == wifi_guard_interval_800) {
14126 params[2].value = "800";
14127 strcpy(GI, "0.8");
14128 } else if (guard_interval == wifi_guard_interval_1600) {
14129 params[2].value = "1600";
14130 strcpy(GI, "1.6");
14131 } else if (guard_interval == wifi_guard_interval_3200) {
14132 params[2].value = "3200";
14133 strcpy(GI, "3.2");
14134 } else if (guard_interval == wifi_guard_interval_auto) {
14135 params[2].value = "0";
14136 strcpy(GI, "auto");
14137 }
14138 wifi_datfileWrite(dat_file, params, 3);
14139 }
developera3511852023-06-14 14:12:59 +080014140 // Record GI for get GI function
developere40952c2023-06-15 18:46:43 +080014141 res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
14142 if (os_snprintf_error(sizeof(buf), res)) {
14143 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14144 return RETURN_ERR;
14145 }
developera3511852023-06-14 14:12:59 +080014146 f = fopen(buf, "w");
14147 if (f == NULL)
14148 return RETURN_ERR;
14149 fprintf(f, "%s", GI);
14150 fclose(f);
14151 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14152 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014153}
14154
14155INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
14156{
developera3511852023-06-14 14:12:59 +080014157 char buf[32] = {0};
14158 char cmd[64] = {0};
developere40952c2023-06-15 18:46:43 +080014159 int res;
developer72fb0bb2023-01-11 09:46:29 +080014160
developera3511852023-06-14 14:12:59 +080014161 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080014162
developera3511852023-06-14 14:12:59 +080014163 if (guard_interval == NULL)
14164 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014165
developere40952c2023-06-15 18:46:43 +080014166 res = snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
14167 if (os_snprintf_error(sizeof(cmd), res)) {
14168 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14169 return RETURN_ERR;
14170 }
developera3511852023-06-14 14:12:59 +080014171 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080014172
developera3511852023-06-14 14:12:59 +080014173 if (strncmp(buf, "0.4", 3) == 0)
14174 *guard_interval = wifi_guard_interval_400;
14175 else if (strncmp(buf, "0.8", 3) == 0)
14176 *guard_interval = wifi_guard_interval_800;
14177 else if (strncmp(buf, "1.6", 3) == 0)
14178 *guard_interval = wifi_guard_interval_1600;
14179 else if (strncmp(buf, "3.2", 3) == 0)
14180 *guard_interval = wifi_guard_interval_3200;
14181 else
14182 *guard_interval = wifi_guard_interval_auto;
developer72fb0bb2023-01-11 09:46:29 +080014183
developera3511852023-06-14 14:12:59 +080014184 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14185 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014186}
14187
14188INT wifi_setBSSColor(INT radio_index, UCHAR color)
14189{
developera3511852023-06-14 14:12:59 +080014190 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14191 struct params params = {0};
14192 char config_file[128] = {0};
14193 char bss_color[4] ={0};
developere40952c2023-06-15 18:46:43 +080014194 int res;
developer72fb0bb2023-01-11 09:46:29 +080014195
developera1255e42023-05-13 17:45:02 +080014196 if (color < 1 || color > 63) {
14197 wifi_dbg_printf("color value is err:%d.\n", color);
14198 return RETURN_ERR;
14199 }
developera3511852023-06-14 14:12:59 +080014200 params.name = "he_bss_color";
developere40952c2023-06-15 18:46:43 +080014201 res = snprintf(bss_color, sizeof(bss_color), "%hhu", color);
14202 if (os_snprintf_error(sizeof(bss_color), res)) {
14203 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14204 return RETURN_ERR;
14205 }
developera3511852023-06-14 14:12:59 +080014206 params.value = bss_color;
14207 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
14208 wifi_hostapdWrite(config_file, &params, 1);
14209 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
developera1255e42023-05-13 17:45:02 +080014210 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080014211
developera3511852023-06-14 14:12:59 +080014212 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14213 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014214}
14215
14216INT wifi_getBSSColor(INT radio_index, UCHAR *color)
14217{
developera3511852023-06-14 14:12:59 +080014218 char config_file[128] = {0};
14219 char buf[64] = {0};
14220 char temp_output[128] = {'\0'};
developere40952c2023-06-15 18:46:43 +080014221 int res;
developer72fb0bb2023-01-11 09:46:29 +080014222
developera3511852023-06-14 14:12:59 +080014223 wifi_dbg_printf("\nFunc=%s\n", __func__);
14224 if (NULL == color)
14225 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014226
developera3511852023-06-14 14:12:59 +080014227 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
14228 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080014229
developera3511852023-06-14 14:12:59 +080014230 if(strlen(buf) > 0) {
developere40952c2023-06-15 18:46:43 +080014231 res = snprintf(temp_output, sizeof(temp_output), "%s", buf);
developera3511852023-06-14 14:12:59 +080014232 } else {
developere40952c2023-06-15 18:46:43 +080014233 res = snprintf(temp_output, sizeof(temp_output), "1"); // default value
14234 }
14235 if (os_snprintf_error(sizeof(temp_output), res)) {
14236 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14237 return RETURN_ERR;
developera3511852023-06-14 14:12:59 +080014238 }
developer72fb0bb2023-01-11 09:46:29 +080014239
developera3511852023-06-14 14:12:59 +080014240 *color = (UCHAR)strtoul(temp_output, NULL, 10);
14241 wifi_dbg_printf("\noutput_string=%s\n", color);
developer72fb0bb2023-01-11 09:46:29 +080014242
developera3511852023-06-14 14:12:59 +080014243 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014244}
14245
14246/* multi-psk support */
14247INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
14248{
developera3511852023-06-14 14:12:59 +080014249 char cmd[256];
14250 char interface_name[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +080014251
developera3511852023-06-14 14:12:59 +080014252 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14253 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014254
developera3511852023-06-14 14:12:59 +080014255 sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
14256 interface_name,
14257 mac[0],
14258 mac[1],
14259 mac[2],
14260 mac[3],
14261 mac[4],
14262 mac[5]
14263 );
14264 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
14265 _syscmd(cmd, key->wifi_keyId, 64);
developer72fb0bb2023-01-11 09:46:29 +080014266
14267
developera3511852023-06-14 14:12:59 +080014268 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014269}
14270
14271INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
14272{
developera3511852023-06-14 14:12:59 +080014273 char interface_name[16] = {0};
14274 FILE *fd = NULL;
14275 char fname[100];
14276 char cmd[128] = {0};
14277 char out[64] = {0};
14278 wifi_key_multi_psk_t * key = NULL;
developere40952c2023-06-15 18:46:43 +080014279 int res;
14280
developera3511852023-06-14 14:12:59 +080014281 if(keysNumber < 0)
14282 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014283
developere40952c2023-06-15 18:46:43 +080014284 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
14285 if (os_snprintf_error(sizeof(fname), res)) {
14286 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14287 return RETURN_ERR;
14288 }
developera3511852023-06-14 14:12:59 +080014289 fd = fopen(fname, "w");
14290 if (!fd) {
14291 return RETURN_ERR;
14292 }
14293 key= (wifi_key_multi_psk_t *) keys;
14294 for(int i=0; i<keysNumber; ++i, key++) {
14295 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
14296 }
14297 fclose(fd);
developer72fb0bb2023-01-11 09:46:29 +080014298
developera3511852023-06-14 14:12:59 +080014299 //reload file
14300 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14301 return RETURN_ERR;
14302 sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
14303 _syscmd(cmd, out, 64);
14304 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014305}
14306
14307INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
14308{
developera3511852023-06-14 14:12:59 +080014309 FILE *fd = NULL;
14310 char fname[100];
14311 char * line = NULL;
14312 char * pos = NULL;
14313 size_t len = 0;
14314 ssize_t read = 0;
14315 INT ret = RETURN_OK;
14316 wifi_key_multi_psk_t *keys_it = NULL;
developere40952c2023-06-15 18:46:43 +080014317 int res;
developer72fb0bb2023-01-11 09:46:29 +080014318
developera3511852023-06-14 14:12:59 +080014319 if (keysNumber < 1) {
14320 return RETURN_ERR;
14321 }
developer72fb0bb2023-01-11 09:46:29 +080014322
developere40952c2023-06-15 18:46:43 +080014323 res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
14324 if (os_snprintf_error(sizeof(fname), res)) {
14325 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14326 return RETURN_ERR;
14327 }
developera3511852023-06-14 14:12:59 +080014328 fd = fopen(fname, "r");
14329 if (!fd) {
14330 return RETURN_ERR;
14331 }
developer72fb0bb2023-01-11 09:46:29 +080014332
developera3511852023-06-14 14:12:59 +080014333 if (keys == NULL) {
14334 ret = RETURN_ERR;
14335 goto close;
14336 }
developer72fb0bb2023-01-11 09:46:29 +080014337
developera3511852023-06-14 14:12:59 +080014338 keys_it = keys;
14339 while ((read = getline(&line, &len, fd)) != -1) {
14340 //Strip trailing new line if present
14341 if (read > 0 && line[read-1] == '\n') {
14342 line[read-1] = '\0';
14343 }
developer72fb0bb2023-01-11 09:46:29 +080014344
developera3511852023-06-14 14:12:59 +080014345 if(strcmp(line,"keyid=")) {
14346 sscanf(line, "keyid=%s", keys_it->wifi_keyId);
14347 if (!(pos = index(line, ' '))) {
14348 ret = RETURN_ERR;
14349 goto close;
14350 }
14351 pos++;
14352 //Here should be 00:00:00:00:00:00
14353 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
14354 printf("Not supported MAC: %s\n", pos);
14355 }
14356 if (!(pos = index(pos, ' '))) {
14357 ret = RETURN_ERR;
14358 goto close;
14359 }
14360 pos++;
developer72fb0bb2023-01-11 09:46:29 +080014361
developera3511852023-06-14 14:12:59 +080014362 //The rest is PSK
developere40952c2023-06-15 18:46:43 +080014363 res = snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
14364 if (os_snprintf_error(sizeof(keys_it->wifi_psk), res)) {
14365 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14366 return RETURN_ERR;
14367 }
14368
developera3511852023-06-14 14:12:59 +080014369 keys_it++;
developer72fb0bb2023-01-11 09:46:29 +080014370
developera3511852023-06-14 14:12:59 +080014371 if(--keysNumber <= 0)
developer72fb0bb2023-01-11 09:46:29 +080014372 break;
developera3511852023-06-14 14:12:59 +080014373 }
14374 }
developer72fb0bb2023-01-11 09:46:29 +080014375
14376close:
developera3511852023-06-14 14:12:59 +080014377 free(line);
14378 fclose(fd);
14379 return ret;
developer72fb0bb2023-01-11 09:46:29 +080014380}
14381/* end of multi-psk support */
14382
14383INT wifi_setNeighborReports(UINT apIndex,
developera3511852023-06-14 14:12:59 +080014384 UINT numNeighborReports,
14385 wifi_NeighborReport_t *neighborReports)
developer72fb0bb2023-01-11 09:46:29 +080014386{
developera3511852023-06-14 14:12:59 +080014387 char cmd[256] = { 0 };
14388 char hex_bssid[13] = { 0 };
14389 char bssid[18] = { 0 };
14390 char nr[100] = { 0 };
14391 char ssid[32];
14392 char hex_ssid[32];
14393 char interface_name[16] = {0};
14394 INT ret;
developere40952c2023-06-15 18:46:43 +080014395 int res;
developer72fb0bb2023-01-11 09:46:29 +080014396
developera3511852023-06-14 14:12:59 +080014397 /*rmeove all neighbors*/
14398 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
14399 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14400 return RETURN_ERR;
14401 sprintf(cmd, "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",interface_name,interface_name);
14402 system(cmd);
developer72fb0bb2023-01-11 09:46:29 +080014403
developera3511852023-06-14 14:12:59 +080014404 for(unsigned int i = 0; i < numNeighborReports; i++)
14405 {
14406 memset(ssid, 0, sizeof(ssid));
14407 ret = wifi_getSSIDName(apIndex, ssid);
14408 if (ret != RETURN_OK)
14409 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080014410
developera3511852023-06-14 14:12:59 +080014411 memset(hex_ssid, 0, sizeof(hex_ssid));
14412 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
14413 sprintf(hex_ssid + k,"%02x", ssid[j]);
developer72fb0bb2023-01-11 09:46:29 +080014414
developere40952c2023-06-15 18:46:43 +080014415 res = snprintf(hex_bssid, sizeof(hex_bssid),
developera3511852023-06-14 14:12:59 +080014416 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
14417 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 +080014418 if (os_snprintf_error(sizeof(hex_bssid), res)) {
14419 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14420 return RETURN_ERR;
14421 }
14422 res = snprintf(bssid, sizeof(bssid),
developera3511852023-06-14 14:12:59 +080014423 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
14424 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 +080014425 if (os_snprintf_error(sizeof(bssid), res)) {
14426 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14427 return RETURN_ERR;
14428 }
developer72fb0bb2023-01-11 09:46:29 +080014429
developere40952c2023-06-15 18:46:43 +080014430 res = snprintf(nr, sizeof(nr),
developera3511852023-06-14 14:12:59 +080014431 "%s" // bssid
14432 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
14433 "%02hhx" // operclass
14434 "%02hhx" // channel
14435 "%02hhx", // phy_mode
14436 hex_bssid,
14437 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
14438 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
14439 neighborReports[i].opClass,
14440 neighborReports[i].channel,
14441 neighborReports[i].phyTable);
developere40952c2023-06-15 18:46:43 +080014442 if (os_snprintf_error(sizeof(nr), res)) {
14443 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14444 return RETURN_ERR;
14445 }
developer72fb0bb2023-01-11 09:46:29 +080014446
developere40952c2023-06-15 18:46:43 +080014447 res = snprintf(cmd, sizeof(cmd),
developera3511852023-06-14 14:12:59 +080014448 "hostapd_cli set_neighbor "
14449 "%s " // bssid
14450 "ssid=%s " // ssid
14451 "nr=%s " // nr
14452 "-i %s",
14453 bssid,hex_ssid,nr, interface_name);
developere40952c2023-06-15 18:46:43 +080014454 if (os_snprintf_error(sizeof(cmd), res)) {
14455 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
14456 return RETURN_ERR;
14457 }
developer72fb0bb2023-01-11 09:46:29 +080014458
developera3511852023-06-14 14:12:59 +080014459 if (WEXITSTATUS(system(cmd)) != 0)
14460 {
14461 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
14462 }
14463 }
developer72fb0bb2023-01-11 09:46:29 +080014464
developera3511852023-06-14 14:12:59 +080014465 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014466}
14467
14468INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
14469{
developera3511852023-06-14 14:12:59 +080014470 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080014471}
14472
14473#ifdef _WIFI_HAL_TEST_
14474int main(int argc,char **argv)
14475{
developera3511852023-06-14 14:12:59 +080014476 int index;
14477 INT ret=0;
14478 char buf[1024]="";
developer72fb0bb2023-01-11 09:46:29 +080014479
developera3511852023-06-14 14:12:59 +080014480 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14481 if(argc<3)
14482 {
14483 if(argc==2)
14484 {
14485 if(!strcmp(argv[1], "init"))
14486 return wifi_init();
14487 if(!strcmp(argv[1], "reset"))
14488 return wifi_reset();
14489 if(!strcmp(argv[1], "wifi_getHalVersion"))
14490 {
14491 char buffer[64];
14492 if(wifi_getHalVersion(buffer)==RETURN_OK)
14493 printf("Version: %s\n", buffer);
14494 else
14495 printf("Error in wifi_getHalVersion\n");
14496 return RETURN_OK;
14497 }
14498 }
14499 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
14500 exit(-1);
14501 }
developer72fb0bb2023-01-11 09:46:29 +080014502
developera3511852023-06-14 14:12:59 +080014503 index = atoi(argv[2]);
14504 if(strstr(argv[1], "wifi_getApName")!=NULL)
14505 {
14506 wifi_getApName(index,buf);
14507 printf("Ap name is %s \n",buf);
14508 return 0;
14509 }
developerfead3972023-05-25 20:15:02 +080014510 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080014511 {
developerfead3972023-05-25 20:15:02 +080014512 UINT pureMode = atoi(argv[3]);
14513
developera3511852023-06-14 14:12:59 +080014514 wifi_setRadioMode(index, NULL, pureMode);
14515 printf("Ap SET Radio mode 0x%x\n", pureMode);
14516 return 0;
14517 }
14518 if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
14519 unsigned char enable = atoi(argv[3]);
14520 if (enable)
14521 wifi_setRadioAutoBlockAckEnable(index, TRUE);
14522 else
14523 wifi_setRadioAutoBlockAckEnable(index, FALSE);
14524 printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
14525 }
developerfead3972023-05-25 20:15:02 +080014526 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
developera3511852023-06-14 14:12:59 +080014527 {
developerfead3972023-05-25 20:15:02 +080014528 ULONG TransmitPower = atoi(argv[3]);
14529
developera3511852023-06-14 14:12:59 +080014530 wifi_setRadioTransmitPower(index, TransmitPower);
14531 printf("Ap SET TransmitPower %lu\n", TransmitPower);
14532 return 0;
14533 }
developerfead3972023-05-25 20:15:02 +080014534 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
developera3511852023-06-14 14:12:59 +080014535 {
developerfead3972023-05-25 20:15:02 +080014536 INT TransmitPower = atoi(argv[3]);
14537
developera3511852023-06-14 14:12:59 +080014538 wifi_setApManagementFramePowerControl(index, TransmitPower);
14539 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
14540 return 0;
14541 }
developerfead3972023-05-25 20:15:02 +080014542 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
developera3511852023-06-14 14:12:59 +080014543 {
developerfead3972023-05-25 20:15:02 +080014544 CHAR *bandwith = argv[3];
14545
developera3511852023-06-14 14:12:59 +080014546 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
14547 printf("Ap SET bw %s\n", bandwith);
14548 return 0;
14549 }
developerfead3972023-05-25 20:15:02 +080014550 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
developera3511852023-06-14 14:12:59 +080014551 {
14552 wifi_factoryResetRadio(index);
14553 printf("wifi_factoryResetRadio ok!\n");
14554 return 0;
14555 }
developerfead3972023-05-25 20:15:02 +080014556 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
developera3511852023-06-14 14:12:59 +080014557 {
14558 ULONG rst_cnt;
14559 wifi_getRadioResetCount(index, &rst_cnt);
14560 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
14561 return 0;
14562 }
developer2edaf012023-05-24 14:24:53 +080014563 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080014564 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080014565 {
14566 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14567 exit(-1);
14568 }
developer49b17232023-05-19 16:35:19 +080014569 wifi_addApAclDevice(index, argv[3]);
14570 return 0;
14571 }
developer2edaf012023-05-24 14:24:53 +080014572 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
14573 wifi_getApAclDevices(index, buf, 1024);
14574 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080014575 return 0;
14576 }
developer2edaf012023-05-24 14:24:53 +080014577 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
14578 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080014579 {
14580 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14581 exit(-1);
14582 }
developer2edaf012023-05-24 14:24:53 +080014583 wifi_delApAclDevice(index, argv[3]);
14584 return 0;
14585 }
14586 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
14587 wifi_delApAclDevices(index);
14588 return 0;
14589 }
14590 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
developer863a4a62023-06-06 16:55:59 +080014591 UINT acl_num = 0;
developer2edaf012023-05-24 14:24:53 +080014592 wifi_getApAclDeviceNum(index, &acl_num);
14593 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
14594 return 0;
14595 }
14596 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
14597 wifi_getApDenyAclDevices(index, buf, 1024);
14598 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
14599 return 0;
14600 }
14601 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
14602 int filter_mode = 0;
14603 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080014604 {
14605 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14606 exit(-1);
14607 }
developer2edaf012023-05-24 14:24:53 +080014608 filter_mode = atoi(argv[3]);
14609 wifi_setApMacAddressControlMode(index,filter_mode);
14610 return 0;
14611 }
developer5cd4c862023-05-26 09:34:42 +080014612 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
14613 BOOL output_bool = 0;
14614 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
14615 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
14616 return 0;
14617 }
14618 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
14619 BOOL output_bool = 0;
14620 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
14621 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
14622 return 0;
14623 }
14624
14625 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14626 int filter_mode = 0;
14627 wifi_getApMacAddressControlMode(index, &filter_mode);
14628 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14629 return 0;
14630 }
14631 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
14632 int enable = 0;
14633 if(argc <= 3 )
developera3511852023-06-14 14:12:59 +080014634 {
14635 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14636 exit(-1);
14637 }
developer5cd4c862023-05-26 09:34:42 +080014638 enable = (BOOL)atoi(argv[3]);
14639 wifi_setRadioIGMPSnoopingEnable(index, enable);
14640 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
14641 return 0;
14642 }
14643
14644 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
14645 BOOL out_status = 0;
14646 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
14647 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
14648 return 0;
14649 }
developer121a8e72023-05-22 09:19:39 +080014650
developer95c045d2023-05-24 19:26:28 +080014651 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
14652 int enable = 0;
14653 if(argc <= 3)
14654 {
14655 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14656 exit(-1);
14657 }
14658 enable = atoi(argv[3]);
14659 wifi_setApWmmEnable(index,enable);
14660 return 0;
14661 }
developerc1aa6532023-06-09 09:37:01 +080014662 if (strncmp(argv[1], "wifi_pushSsidAdvertisementEnable", strlen(argv[1])) == 0) {
14663 int enable = 0;
14664 if(argc <= 3)
14665 {
14666 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14667 exit(-1);
14668 }
14669 enable = atoi(argv[3]);
14670 wifi_pushSsidAdvertisementEnable(index,enable);
14671 return 0;
14672 }
developer56fbedb2023-05-30 16:47:05 +080014673 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
14674 wifi_down();
14675 return 0;
14676 }
developer95c045d2023-05-24 19:26:28 +080014677
developer56fbedb2023-05-30 16:47:05 +080014678 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
14679 BOOL enable = 0;
14680
14681 wifi_getRadioStatus(index, &enable);
14682 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
14683 return 0;
14684 }
developer333c1eb2023-05-31 14:59:39 +080014685
developer95c045d2023-05-24 19:26:28 +080014686 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
14687 BOOL enable = 0;
14688
14689 wifi_getApWMMCapability(index, &enable);
14690 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
14691 return 0;
14692 }
14693
14694 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
14695 BOOL enable = 0;
14696
14697 wifi_getApWmmEnable(index, &enable);
14698 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
14699 return 0;
14700 }
14701
developer2edaf012023-05-24 14:24:53 +080014702 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14703 int filter_mode = 0;
14704 wifi_getApMacAddressControlMode(index, &filter_mode);
14705 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14706 return 0;
14707 }
developer0f10c772023-05-16 21:43:39 +080014708 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
developera3511852023-06-14 14:12:59 +080014709 {
developer863a4a62023-06-06 16:55:59 +080014710 UINT mode = 0;
developer0f10c772023-05-16 21:43:39 +080014711
developera3511852023-06-14 14:12:59 +080014712 wifi_getRadioMode(index, buf, &mode);
14713 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
14714 return 0;
14715 }
14716 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
14717 {
14718 BOOL b = FALSE;
14719 BOOL *output_bool = &b;
14720 wifi_getRadioAutoChannelEnable(index,output_bool);
14721 printf("Channel enabled = %d \n",b);
14722 return 0;
14723 }
14724 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
14725 {
14726 wifi_getApWpaEncryptionMode(index,buf);
14727 printf("encryption enabled = %s\n",buf);
14728 return 0;
14729 }
14730 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
14731 {
14732 BOOL b = FALSE;
14733 BOOL *output_bool = &b;
14734 wifi_getApSsidAdvertisementEnable(index,output_bool);
14735 printf("advertisment enabled = %d\n",b);
14736 return 0;
14737 }
14738 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
14739 {
14740 if(argc <= 3 )
14741 {
14742 printf("Insufficient arguments \n");
14743 exit(-1);
14744 }
developer72fb0bb2023-01-11 09:46:29 +080014745
developera3511852023-06-14 14:12:59 +080014746 char sta[20] = {'\0'};
14747 ULLONG handle= 0;
14748 strcpy(sta,argv[3]);
14749 mac_address_t st;
developer72fb0bb2023-01-11 09:46:29 +080014750 mac_addr_aton(st,sta);
14751
developera3511852023-06-14 14:12:59 +080014752 wifi_associated_dev_tid_stats_t tid_stats;
14753 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
14754 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
14755 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);
14756 }
developer72fb0bb2023-01-11 09:46:29 +080014757
developera3511852023-06-14 14:12:59 +080014758 if(strstr(argv[1], "getApEnable")!=NULL) {
14759 BOOL enable;
14760 ret=wifi_getApEnable(index, &enable);
14761 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14762 }
14763 else if(strstr(argv[1], "setApEnable")!=NULL) {
14764 BOOL enable = atoi(argv[3]);
14765 ret=wifi_setApEnable(index, enable);
14766 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14767 }
14768 else if(strstr(argv[1], "getApStatus")!=NULL) {
14769 char status[64];
14770 ret=wifi_getApStatus(index, status);
14771 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
14772 }
14773 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
14774 {
14775 wifi_getSSIDNameStatus(index,buf);
14776 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
14777 return 0;
14778 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
14779 wifi_resetApVlanCfg(index);
14780 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
14781 return 0;
14782 }
14783 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
14784 wifi_ssidTrafficStats2_t stats={0};
14785 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
14786 printf("%s %d: returns %d\n", argv[1], index, ret);
14787 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
14788 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
14789 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
14790 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
14791 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
14792 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
14793 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
14794 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
14795 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
14796 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
14797 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
14798 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
14799 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
14800 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
14801 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
14802 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
14803 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
14804 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
14805 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
14806 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
14807 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
14808 }
14809 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
14810 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
14811 UINT array_size=0;
14812 UINT i=0;
14813 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
14814 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
14815 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
14816 printf(" neighbor %d:\n", i);
14817 printf(" ap_SSID =%s\n", pt->ap_SSID);
14818 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
14819 printf(" ap_Mode =%s\n", pt->ap_Mode);
14820 printf(" ap_Channel =%d\n", pt->ap_Channel);
14821 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
14822 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14823 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
14824 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
14825 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
14826 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
14827 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14828 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
14829 printf(" ap_Noise =%d\n", pt->ap_Noise);
14830 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
14831 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
14832 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
14833 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
14834 }
14835 if(neighbor_ap_array)
14836 free(neighbor_ap_array); //make sure to free the list
14837 }
14838 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
14839 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
14840 UINT array_size=0;
14841 UINT i=0;
14842 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
14843 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
14844 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
14845 printf(" associated_dev %d:\n", i);
14846 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
14847 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
14848 printf(" cli_SNR =%d\n", pt->cli_SNR);
14849 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
14850 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
14851 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
14852 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
14853 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
14854 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
14855 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
14856 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
14857 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
14858 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
14859 }
14860 if(associated_dev_array)
14861 free(associated_dev_array); //make sure to free the list
14862 }
developer72fb0bb2023-01-11 09:46:29 +080014863
developera3511852023-06-14 14:12:59 +080014864 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
14865 {
developer72fb0bb2023-01-11 09:46:29 +080014866#define MAX_ARRAY_SIZE 64
developera3511852023-06-14 14:12:59 +080014867 int i, array_size;
14868 char *p, *ch_str;
14869 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
developer72fb0bb2023-01-11 09:46:29 +080014870
developera3511852023-06-14 14:12:59 +080014871 if(argc != 5)
14872 {
14873 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
14874 exit(-1);
14875 }
14876 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
developer72fb0bb2023-01-11 09:46:29 +080014877
developera3511852023-06-14 14:12:59 +080014878 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
14879 {
14880 strtok_r(ch_str, ",", &p);
14881 input_output_channelStats_array[i].ch_number = atoi(ch_str);
14882 }
14883 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
14884 if(!array_size)
14885 array_size=1;//Need to print current channel statistics
14886 for(i=0; i<array_size; i++)
14887 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
14888 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
14889 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
14890 input_output_channelStats_array[i].ch_number,\
14891 input_output_channelStats_array[i].ch_noise,\
14892 input_output_channelStats_array[i].ch_utilization_busy_rx,\
14893 input_output_channelStats_array[i].ch_utilization_busy_tx,\
14894 input_output_channelStats_array[i].ch_utilization_busy,\
14895 input_output_channelStats_array[i].ch_utilization_busy_ext,\
14896 input_output_channelStats_array[i].ch_utilization_total);
14897 }
developer72fb0bb2023-01-11 09:46:29 +080014898
developera3511852023-06-14 14:12:59 +080014899 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
14900 {
14901 if(argc <= 3 )
14902 {
14903 printf("Insufficient arguments \n");
14904 exit(-1);
14905 }
14906 char mac_addr[20] = {'\0'};
14907 wifi_device_t output_struct;
14908 int dev_index = atoi(argv[3]);
developer72fb0bb2023-01-11 09:46:29 +080014909
developera3511852023-06-14 14:12:59 +080014910 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
14911 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
14912 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);
14913 }
developer72fb0bb2023-01-11 09:46:29 +080014914
developera3511852023-06-14 14:12:59 +080014915 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
14916 {
14917 if (argc <= 3)
14918 {
14919 printf("Insufficient arguments\n");
14920 exit(-1);
14921 }
14922 char args[256];
14923 wifi_NeighborReport_t *neighborReports;
developer72fb0bb2023-01-11 09:46:29 +080014924
developera3511852023-06-14 14:12:59 +080014925 neighborReports = calloc(argc - 2, sizeof(neighborReports));
14926 if (!neighborReports)
14927 {
14928 printf("Failed to allocate memory");
14929 exit(-1);
14930 }
developer72fb0bb2023-01-11 09:46:29 +080014931
developera3511852023-06-14 14:12:59 +080014932 for (int i = 3; i < argc; ++i)
14933 {
14934 char *val;
14935 int j = 0;
14936 memset(args, 0, sizeof(args));
14937 strncpy(args, argv[i], sizeof(args));
14938 val = strtok(args, ";");
14939 while (val != NULL)
14940 {
14941 if (j == 0)
14942 {
14943 mac_addr_aton(neighborReports[i - 3].bssid, val);
14944 } else if (j == 1)
14945 {
14946 neighborReports[i - 3].info = strtol(val, NULL, 16);
14947 } else if (j == 2)
14948 {
14949 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
14950 } else if (j == 3)
14951 {
14952 neighborReports[i - 3].channel = strtol(val, NULL, 16);
14953 } else if (j == 4)
14954 {
14955 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
14956 } else {
14957 printf("Insufficient arguments]n\n");
14958 exit(-1);
14959 }
14960 val = strtok(NULL, ";");
14961 j++;
14962 }
14963 }
developer72fb0bb2023-01-11 09:46:29 +080014964
developera3511852023-06-14 14:12:59 +080014965 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
14966 if (ret != RETURN_OK)
14967 {
14968 printf("wifi_setNeighborReports ret = %d", ret);
14969 exit(-1);
14970 }
14971 }
14972 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
14973 {
14974 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
14975 printf("%s.\n", buf);
14976 else
14977 printf("Error returned\n");
14978 }
14979 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
14980 {
14981 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
14982 printf("%s.\n", buf);
14983 else
14984 printf("Error returned\n");
14985 }
14986 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
14987 {
14988 if (argc <= 2)
14989 {
14990 printf("Insufficient arguments\n");
14991 exit(-1);
14992 }
14993 char buf[64]= {'\0'};
14994 wifi_getRadioOperatingChannelBandwidth(index,buf);
14995 printf("Current bandwidth is %s \n",buf);
14996 return 0;
14997 }
14998 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
14999 {
15000 if (argc <= 5)
15001 {
15002 printf("Insufficient arguments\n");
15003 exit(-1);
15004 }
15005 UINT channel = atoi(argv[3]);
15006 UINT width = atoi(argv[4]);
15007 UINT beacon = atoi(argv[5]);
15008 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
15009 printf("Result = %d", ret);
15010 }
developercc5cbfb2023-06-13 18:29:52 +080015011 if(strstr(argv[1],"wifi_getApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080015012 {
developercc5cbfb2023-06-13 18:29:52 +080015013 char br_name[64], ip[64], subset[64] = {0};
15014 wifi_getApBridgeInfo(0, br_name, ip, subset);
15015 printf("wifi_getApBridgeInfo br_name = %s, ip = %s, subset = %s\n", br_name, ip, subset);
developera3511852023-06-14 14:12:59 +080015016 }
developercc5cbfb2023-06-13 18:29:52 +080015017 if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
developera3511852023-06-14 14:12:59 +080015018 {
developercc5cbfb2023-06-13 18:29:52 +080015019 int enable = atoi(argv[3]);
15020 wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
15021 printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
developera3511852023-06-14 14:12:59 +080015022 }
developercc5cbfb2023-06-13 18:29:52 +080015023 if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
developera3511852023-06-14 14:12:59 +080015024 {
developercc5cbfb2023-06-13 18:29:52 +080015025 wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
15026 printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
developera3511852023-06-14 14:12:59 +080015027 }
developer72fb0bb2023-01-11 09:46:29 +080015028
developera3511852023-06-14 14:12:59 +080015029 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15030 return 0;
developer72fb0bb2023-01-11 09:46:29 +080015031}
15032
15033#endif
15034
15035#ifdef WIFI_HAL_VERSION_3
15036
15037INT BitMapToTransmitRates(UINT bitMap, char *BasicRate)
15038{
developera3511852023-06-14 14:12:59 +080015039 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15040 if (bitMap & WIFI_BITRATE_1MBPS)
15041 strcat(BasicRate, "1,");
15042 if (bitMap & WIFI_BITRATE_2MBPS)
15043 strcat(BasicRate, "2,");
15044 if (bitMap & WIFI_BITRATE_5_5MBPS)
15045 strcat(BasicRate, "5.5,");
15046 if (bitMap & WIFI_BITRATE_6MBPS)
15047 strcat(BasicRate, "6,");
15048 if (bitMap & WIFI_BITRATE_9MBPS)
15049 strcat(BasicRate, "9,");
15050 if (bitMap & WIFI_BITRATE_11MBPS)
15051 strcat(BasicRate, "11,");
15052 if (bitMap & WIFI_BITRATE_12MBPS)
15053 strcat(BasicRate, "12,");
15054 if (bitMap & WIFI_BITRATE_18MBPS)
15055 strcat(BasicRate, "18,");
15056 if (bitMap & WIFI_BITRATE_24MBPS)
15057 strcat(BasicRate, "24,");
15058 if (bitMap & WIFI_BITRATE_36MBPS)
15059 strcat(BasicRate, "36,");
15060 if (bitMap & WIFI_BITRATE_48MBPS)
15061 strcat(BasicRate, "48,");
15062 if (bitMap & WIFI_BITRATE_54MBPS)
15063 strcat(BasicRate, "54,");
15064 if (strlen(BasicRate) != 0) // remove last comma
15065 BasicRate[strlen(BasicRate) - 1] = '\0';
15066 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15067 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015068}
15069
15070INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
15071{
developera3511852023-06-14 14:12:59 +080015072 UINT BitMap = 0;
15073 char *rate;
developer72fb0bb2023-01-11 09:46:29 +080015074
developera3511852023-06-14 14:12:59 +080015075 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15076 rate = strtok(BasicRatesList, ",");
15077 while(rate != NULL)
15078 {
15079 if (strcmp(rate, "1") == 0)
15080 BitMap |= WIFI_BITRATE_1MBPS;
15081 else if (strcmp(rate, "2") == 0)
15082 BitMap |= WIFI_BITRATE_2MBPS;
15083 else if (strcmp(rate, "5.5") == 0)
15084 BitMap |= WIFI_BITRATE_5_5MBPS;
15085 else if (strcmp(rate, "6") == 0)
15086 BitMap |= WIFI_BITRATE_6MBPS;
15087 else if (strcmp(rate, "9") == 0)
15088 BitMap |= WIFI_BITRATE_9MBPS;
15089 else if (strcmp(rate, "11") == 0)
15090 BitMap |= WIFI_BITRATE_11MBPS;
15091 else if (strcmp(rate, "12") == 0)
15092 BitMap |= WIFI_BITRATE_12MBPS;
15093 else if (strcmp(rate, "18") == 0)
15094 BitMap |= WIFI_BITRATE_18MBPS;
15095 else if (strcmp(rate, "24") == 0)
15096 BitMap |= WIFI_BITRATE_24MBPS;
15097 else if (strcmp(rate, "36") == 0)
15098 BitMap |= WIFI_BITRATE_36MBPS;
15099 else if (strcmp(rate, "48") == 0)
15100 BitMap |= WIFI_BITRATE_48MBPS;
15101 else if (strcmp(rate, "54") == 0)
15102 BitMap |= WIFI_BITRATE_54MBPS;
15103 rate = strtok(NULL, ",");
15104 }
15105 *basicRateBitMap = BitMap;
15106 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15107 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015108}
15109
15110// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
15111INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
15112{
developera3511852023-06-14 14:12:59 +080015113 char buf[128] = {0};
15114 int bandwidth = 20;
15115 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080015116 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developera3511852023-06-14 14:12:59 +080015117 wifi_radio_operationParam_t current_param;
developer72fb0bb2023-01-11 09:46:29 +080015118
developera3511852023-06-14 14:12:59 +080015119 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015120
developera3511852023-06-14 14:12:59 +080015121 multiple_set = TRUE;
15122 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
15123 fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__);
15124 return RETURN_ERR;
15125 }
15126 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
15127 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
15128 fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__);
15129 return RETURN_ERR;
15130 }
15131 drv_dat_change = TRUE;
15132 }
15133 if (current_param.channelWidth != operationParam->channelWidth ||
15134 current_param.channel != operationParam->channel ||
15135 current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
15136 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
15137 bandwidth = 20;
15138 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
15139 bandwidth = 40;
15140 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
15141 bandwidth = 80;
15142 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
15143 bandwidth = 160;
developer72fb0bb2023-01-11 09:46:29 +080015144
developera3511852023-06-14 14:12:59 +080015145 if (operationParam->autoChannelEnabled) {
15146 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
15147 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
15148 return RETURN_ERR;
15149 }
15150 } else {
15151 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
15152 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
15153 return RETURN_ERR;
15154 }
15155 }
developer56fbedb2023-05-30 16:47:05 +080015156 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080015157 }
15158 if (current_param.variant != operationParam->variant) {
15159 // Two different definition bit map, so need to check every bit.
15160 if (operationParam->variant & WIFI_80211_VARIANT_A)
15161 set_mode |= WIFI_MODE_A;
15162 if (operationParam->variant & WIFI_80211_VARIANT_B)
15163 set_mode |= WIFI_MODE_B;
15164 if (operationParam->variant & WIFI_80211_VARIANT_G)
15165 set_mode |= WIFI_MODE_G;
15166 if (operationParam->variant & WIFI_80211_VARIANT_N)
15167 set_mode |= WIFI_MODE_N;
15168 if (operationParam->variant & WIFI_80211_VARIANT_AC)
15169 set_mode |= WIFI_MODE_AC;
15170 if (operationParam->variant & WIFI_80211_VARIANT_AX)
15171 set_mode |= WIFI_MODE_AX;
15172 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
15173 memset(buf, 0, sizeof(buf));
15174 drv_dat_change = TRUE;
15175 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
15176 fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__);
15177 return RETURN_ERR;
15178 }
15179 }
15180 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer56fbedb2023-05-30 16:47:05 +080015181 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080015182 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
15183 fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__);
15184 return RETURN_ERR;
15185 }
15186 }
15187 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer56fbedb2023-05-30 16:47:05 +080015188 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080015189 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
15190 fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__);
15191 return RETURN_ERR;
15192 }
15193 }
15194 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer56fbedb2023-05-30 16:47:05 +080015195 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080015196 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf);
15197 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
15198 fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__);
15199 return RETURN_ERR;
15200 }
15201 }
15202 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer56fbedb2023-05-30 16:47:05 +080015203 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080015204 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
15205 fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__);
15206 return RETURN_ERR;
15207 }
15208 }
15209 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080015210 hapd_conf_change = TRUE;
15211 drv_dat_change = TRUE;
15212 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developera3511852023-06-14 14:12:59 +080015213 fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__);
15214 return RETURN_ERR;
15215 }
15216 }
15217 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080015218 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080015219 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
15220 fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__);
15221 return RETURN_ERR;
15222 }
15223 }
15224 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
developer56fbedb2023-05-30 16:47:05 +080015225 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080015226 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
15227 fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__);
15228 return RETURN_ERR;
15229 }
15230 }
15231 if (current_param.obssCoex != operationParam->obssCoex) {
developer56fbedb2023-05-30 16:47:05 +080015232 hapd_conf_change = TRUE;
developera3511852023-06-14 14:12:59 +080015233 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
15234 fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__);
15235 return RETURN_ERR;
15236 }
15237 }
15238 if (current_param.stbcEnable != operationParam->stbcEnable) {
developer56fbedb2023-05-30 16:47:05 +080015239 hapd_conf_change = TRUE;
15240 drv_dat_change = TRUE;
developera3511852023-06-14 14:12:59 +080015241 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
15242 fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__);
15243 return RETURN_ERR;
15244 }
15245 }
15246 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
15247 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
15248 fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__);
15249 return RETURN_ERR;
15250 }
15251 }
developer72fb0bb2023-01-11 09:46:29 +080015252
developera3511852023-06-14 14:12:59 +080015253 /* only down/up interface when dat file has been changed,
15254 * if enable is true, then restart the radio.
15255 */
15256 if (drv_dat_change == TRUE) {
15257 wifi_setRadioEnable(index, FALSE);
developer56fbedb2023-05-30 16:47:05 +080015258 if (operationParam->enable == TRUE)
developera3511852023-06-14 14:12:59 +080015259 wifi_setRadioEnable(index, TRUE);
15260 } else if (hapd_conf_change == TRUE) {
15261 hostapd_raw_remove_bss(index);
15262 if (operationParam->enable == TRUE)
15263 hostapd_raw_add_bss(index);
15264 }
developer56fbedb2023-05-30 16:47:05 +080015265
developera3511852023-06-14 14:12:59 +080015266 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080015267
developera3511852023-06-14 14:12:59 +080015268 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015269}
15270
15271INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
15272{
developera3511852023-06-14 14:12:59 +080015273 char band[64] = {0};
15274 char buf[256] = {0};
15275 char config_file[64] = {0};
15276 char cmd[128] = {0};
15277 UINT mode = 0;
15278 BOOL enabled = FALSE;
developer863a4a62023-06-06 16:55:59 +080015279 int dtimPeriod;
developer2f79c922023-06-02 17:33:42 +080015280 UINT beaconInterval;
15281 UINT basicDataTransmitRates;
15282 UINT operationalDataTransmitRates;
15283 wifi_guard_interval_t guardInterval;
15284 UINT transmitPower;
developere40952c2023-06-15 18:46:43 +080015285 int res;
developer72fb0bb2023-01-11 09:46:29 +080015286
developera3511852023-06-14 14:12:59 +080015287 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15288 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080015289
developera3511852023-06-14 14:12:59 +080015290 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
developere40952c2023-06-15 18:46:43 +080015291 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
15292 if (os_snprintf_error(sizeof(config_file), res)) {
15293 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15294 return RETURN_ERR;
15295 }
developera3511852023-06-14 14:12:59 +080015296 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
15297 {
15298 fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__);
15299 return RETURN_ERR;
15300 }
15301 operationParam->enable = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015302
developera3511852023-06-14 14:12:59 +080015303 memset(band, 0, sizeof(band));
15304 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
15305 {
15306 fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__);
15307 return RETURN_ERR;
15308 }
developer72fb0bb2023-01-11 09:46:29 +080015309
developera3511852023-06-14 14:12:59 +080015310 if (!strcmp(band, "2.4GHz"))
15311 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
15312 else if (!strcmp(band, "5GHz"))
15313 operationParam->band = WIFI_FREQUENCY_5_BAND;
15314 else if (!strcmp(band, "6GHz"))
15315 operationParam->band = WIFI_FREQUENCY_6_BAND;
15316 else
15317 {
15318 fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
15319 band);
15320 }
developer72fb0bb2023-01-11 09:46:29 +080015321
developera3511852023-06-14 14:12:59 +080015322 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
15323 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
15324 operationParam->channel = 0;
15325 operationParam->autoChannelEnabled = TRUE;
15326 } else {
15327 operationParam->channel = strtol(buf, NULL, 10);
15328 operationParam->autoChannelEnabled = FALSE;
15329 }
developer72fb0bb2023-01-11 09:46:29 +080015330
developera3511852023-06-14 14:12:59 +080015331 memset(buf, 0, sizeof(buf));
15332 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
15333 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__);
15334 return RETURN_ERR;
15335 }
15336 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
15337 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
15338 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
15339 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
15340 else
15341 {
15342 fprintf(stderr, "Unknown channel bandwidth: %s\n", buf);
15343 return false;
15344 }
developer72fb0bb2023-01-11 09:46:29 +080015345
developera3511852023-06-14 14:12:59 +080015346 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
15347 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
15348 return RETURN_ERR;
15349 }
15350 // Two different definition bit map, so need to check every bit.
15351 if (mode & WIFI_MODE_A)
15352 operationParam->variant |= WIFI_80211_VARIANT_A;
15353 if (mode & WIFI_MODE_B)
15354 operationParam->variant |= WIFI_80211_VARIANT_B;
15355 if (mode & WIFI_MODE_G)
15356 operationParam->variant |= WIFI_80211_VARIANT_G;
15357 if (mode & WIFI_MODE_N)
15358 operationParam->variant |= WIFI_80211_VARIANT_N;
15359 if (mode & WIFI_MODE_AC)
15360 operationParam->variant |= WIFI_80211_VARIANT_AC;
15361 if (mode & WIFI_MODE_AX)
15362 operationParam->variant |= WIFI_80211_VARIANT_AX;
15363 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
15364 fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__);
15365 return RETURN_ERR;
15366 }
15367 if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
15368 fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__);
15369 return RETURN_ERR;
15370 }
developer2f79c922023-06-02 17:33:42 +080015371 operationParam->dtimPeriod = dtimPeriod;
developera3511852023-06-14 14:12:59 +080015372 if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
15373 fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__);
15374 return RETURN_ERR;
15375 }
developer2f79c922023-06-02 17:33:42 +080015376 operationParam->beaconInterval = beaconInterval;
developer72fb0bb2023-01-11 09:46:29 +080015377
developera3511852023-06-14 14:12:59 +080015378 memset(buf, 0, sizeof(buf));
15379 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
15380 fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__);
15381 return RETURN_ERR;
15382 }
15383 TransmitRatesToBitMap(buf, &basicDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080015384 operationParam->basicDataTransmitRates = basicDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080015385
developera3511852023-06-14 14:12:59 +080015386 memset(buf, 0, sizeof(buf));
15387 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
15388 fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__);
15389 return RETURN_ERR;
15390 }
15391 TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
developer2f79c922023-06-02 17:33:42 +080015392 operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080015393
developera3511852023-06-14 14:12:59 +080015394 memset(buf, 0, sizeof(buf));
15395 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
15396 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080015397
developera3511852023-06-14 14:12:59 +080015398 if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
15399 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
15400 return RETURN_ERR;
15401 }
developer2f79c922023-06-02 17:33:42 +080015402 operationParam->guardInterval = guardInterval;
15403
developera3511852023-06-14 14:12:59 +080015404 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
15405 fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__);
15406 return RETURN_ERR;
15407 }
developer2f79c922023-06-02 17:33:42 +080015408 operationParam->transmitPower = transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080015409
developera3511852023-06-14 14:12:59 +080015410 memset(buf, 0, sizeof(buf));
15411 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
15412 if (strcmp(buf, "-1") == 0) {
15413 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
15414 operationParam->ctsProtection = FALSE;
15415 } else {
15416 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
15417 operationParam->ctsProtection = TRUE;
15418 }
developer72fb0bb2023-01-11 09:46:29 +080015419
developera3511852023-06-14 14:12:59 +080015420 memset(buf, 0, sizeof(buf));
15421 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
15422 if (strcmp(buf, "0") == 0)
15423 operationParam->obssCoex = FALSE;
15424 else
15425 operationParam->obssCoex = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080015426
developere40952c2023-06-15 18:46:43 +080015427 res = snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
15428 if (os_snprintf_error(sizeof(cmd), res)) {
15429 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15430 return RETURN_ERR;
15431 }
developera3511852023-06-14 14:12:59 +080015432 _syscmd(cmd, buf, sizeof(buf));
15433 if (strlen(buf) != 0)
15434 operationParam->stbcEnable = TRUE;
15435 else
15436 operationParam->stbcEnable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015437
developera3511852023-06-14 14:12:59 +080015438 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
15439 fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__);
15440 return RETURN_ERR;
15441 }
developer72fb0bb2023-01-11 09:46:29 +080015442
developera3511852023-06-14 14:12:59 +080015443 // Below value is hardcoded
developer72fb0bb2023-01-11 09:46:29 +080015444
developera3511852023-06-14 14:12:59 +080015445 operationParam->numSecondaryChannels = 0;
15446 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
15447 operationParam->channelSecondary[i] = 0;
15448 }
15449 operationParam->csa_beacon_count = 15;
15450 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
developer72fb0bb2023-01-11 09:46:29 +080015451
developera3511852023-06-14 14:12:59 +080015452 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15453 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015454}
15455
15456static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
15457{
developera3511852023-06-14 14:12:59 +080015458 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +080015459
developera3511852023-06-14 14:12:59 +080015460 wifi_getMaxRadioNumber(&max_radio_num);
15461 if (radioIndex >= max_radio_num) {
15462 fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex);
15463 return RETURN_ERR;
15464 }
developer72fb0bb2023-01-11 09:46:29 +080015465
developera3511852023-06-14 14:12:59 +080015466 return (arrayIndex * max_radio_num) + radioIndex;
developer72fb0bb2023-01-11 09:46:29 +080015467}
15468
developer96b38512023-02-22 11:17:45 +080015469static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
15470{
developera3511852023-06-14 14:12:59 +080015471 int max_radio_num = 0;
developer96b38512023-02-22 11:17:45 +080015472
developera3511852023-06-14 14:12:59 +080015473 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
developer96b38512023-02-22 11:17:45 +080015474 return -1;
15475
developera3511852023-06-14 14:12:59 +080015476 wifi_getMaxRadioNumber(&max_radio_num);
developer96b38512023-02-22 11:17:45 +080015477
developera3511852023-06-14 14:12:59 +080015478 (*radioIndex) = vapIndex % max_radio_num;
15479 (*arrayIndex) = vapIndex / max_radio_num;
developer96b38512023-02-22 11:17:45 +080015480
developera3511852023-06-14 14:12:59 +080015481 return 0;
developer96b38512023-02-22 11:17:45 +080015482}
15483
15484
developer72fb0bb2023-01-11 09:46:29 +080015485wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
developera3511852023-06-14 14:12:59 +080015486 if (strncmp(beaconRate, "1Mbps", 5) == 0)
15487 return WIFI_BITRATE_1MBPS;
15488 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
15489 return WIFI_BITRATE_2MBPS;
15490 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
15491 return WIFI_BITRATE_5_5MBPS;
15492 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
15493 return WIFI_BITRATE_6MBPS;
15494 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
15495 return WIFI_BITRATE_9MBPS;
15496 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
15497 return WIFI_BITRATE_11MBPS;
15498 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
15499 return WIFI_BITRATE_12MBPS;
15500 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
15501 return WIFI_BITRATE_18MBPS;
15502 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
15503 return WIFI_BITRATE_24MBPS;
15504 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
15505 return WIFI_BITRATE_36MBPS;
15506 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
15507 return WIFI_BITRATE_48MBPS;
15508 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
15509 return WIFI_BITRATE_54MBPS;
15510 return WIFI_BITRATE_DEFAULT;
developer72fb0bb2023-01-11 09:46:29 +080015511}
15512
15513INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str)
15514{
developera3511852023-06-14 14:12:59 +080015515 if (beacon == WIFI_BITRATE_1MBPS)
15516 strcpy(beacon_str, "1Mbps");
15517 else if (beacon == WIFI_BITRATE_2MBPS)
15518 strcpy(beacon_str, "2Mbps");
15519 else if (beacon == WIFI_BITRATE_5_5MBPS)
15520 strcpy(beacon_str, "5.5Mbps");
15521 else if (beacon == WIFI_BITRATE_6MBPS)
15522 strcpy(beacon_str, "6Mbps");
15523 else if (beacon == WIFI_BITRATE_9MBPS)
15524 strcpy(beacon_str, "9Mbps");
15525 else if (beacon == WIFI_BITRATE_11MBPS)
15526 strcpy(beacon_str, "11Mbps");
15527 else if (beacon == WIFI_BITRATE_12MBPS)
15528 strcpy(beacon_str, "12Mbps");
15529 else if (beacon == WIFI_BITRATE_18MBPS)
15530 strcpy(beacon_str, "18Mbps");
15531 else if (beacon == WIFI_BITRATE_24MBPS)
15532 strcpy(beacon_str, "24Mbps");
15533 else if (beacon == WIFI_BITRATE_36MBPS)
15534 strcpy(beacon_str, "36Mbps");
15535 else if (beacon == WIFI_BITRATE_48MBPS)
15536 strcpy(beacon_str, "48Mbps");
15537 else if (beacon == WIFI_BITRATE_54MBPS)
15538 strcpy(beacon_str, "54Mbps");
15539 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015540}
15541
15542INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15543{
developera3511852023-06-14 14:12:59 +080015544 INT mode = 0;
15545 INT ret = -1;
15546 UINT output = 0;
15547 int i = 0;
15548 int vap_index = 0;
15549 BOOL enabled = FALSE;
15550 char buf[32] = {0};
15551 wifi_vap_security_t security = {0};
developere40952c2023-06-15 18:46:43 +080015552 int res;
developer72fb0bb2023-01-11 09:46:29 +080015553
developera3511852023-06-14 14:12:59 +080015554 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15555 printf("Entering %s index = %d\n", __func__, (int)index);
developer72fb0bb2023-01-11 09:46:29 +080015556
developera3511852023-06-14 14:12:59 +080015557 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
15558 if (ret != 0) {
15559 fprintf(stderr, "%s: wifi_BandProfileRead BssidNum failed\n", __func__);
15560 return RETURN_ERR;
15561 }
developerfde01262023-05-22 15:15:24 +080015562
developera3511852023-06-14 14:12:59 +080015563 map->num_vaps = atoi(buf);
15564 if (map->num_vaps <= 0) {
15565 fprintf(stderr, "%s: invalid BssidNum %s\n", __func__, buf);
15566 return RETURN_ERR;
15567 }
developerfde01262023-05-22 15:15:24 +080015568
developera3511852023-06-14 14:12:59 +080015569 for (i = 0; i < map->num_vaps; i++)
15570 {
15571 map->vap_array[i].radio_index = index;
developer72fb0bb2023-01-11 09:46:29 +080015572
developera3511852023-06-14 14:12:59 +080015573 vap_index = array_index_to_vap_index(index, i);
15574 if (vap_index < 0)
15575 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080015576
developera3511852023-06-14 14:12:59 +080015577 strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME);
developer72fb0bb2023-01-11 09:46:29 +080015578
developera3511852023-06-14 14:12:59 +080015579 map->vap_array[i].vap_index = vap_index;
developer72fb0bb2023-01-11 09:46:29 +080015580
developera3511852023-06-14 14:12:59 +080015581 memset(buf, 0, sizeof(buf));
15582 ret = wifi_getApName(vap_index, buf);
15583 if (ret != RETURN_OK) {
15584 printf("%s: wifi_getApName return error\n", __func__);
15585 return RETURN_ERR;
15586 }
developere40952c2023-06-15 18:46:43 +080015587 res = snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
15588 if (os_snprintf_error(sizeof(map->vap_array[i].vap_name), res)) {
15589 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15590 return RETURN_ERR;
15591 }
developer72fb0bb2023-01-11 09:46:29 +080015592
developera3511852023-06-14 14:12:59 +080015593 memset(buf, 0, sizeof(buf));
15594 ret = wifi_getSSIDName(vap_index, buf);
15595 if (ret != RETURN_OK) {
15596 printf("%s: wifi_getSSIDName return error\n", __func__);
15597 return RETURN_ERR;
15598 }
developere40952c2023-06-15 18:46:43 +080015599 res = snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
15600 if (os_snprintf_error(sizeof(map->vap_array[i].u.bss_info.ssid), res)) {
15601 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15602 return RETURN_ERR;
15603 }
developer72fb0bb2023-01-11 09:46:29 +080015604
developera3511852023-06-14 14:12:59 +080015605 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080015606
developera3511852023-06-14 14:12:59 +080015607 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
15608 if (ret != RETURN_OK) {
15609 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
15610 return RETURN_ERR;
15611 }
15612 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080015613
developera3511852023-06-14 14:12:59 +080015614 ret = wifi_getApIsolationEnable(vap_index, &enabled);
15615 if (ret != RETURN_OK) {
15616 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
15617 return RETURN_ERR;
15618 }
15619 map->vap_array[i].u.bss_info.isolation = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015620
developera3511852023-06-14 14:12:59 +080015621 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
15622 if (ret != RETURN_OK) {
15623 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
15624 return RETURN_ERR;
15625 }
15626 map->vap_array[i].u.bss_info.bssMaxSta = output;
developer72fb0bb2023-01-11 09:46:29 +080015627
developera3511852023-06-14 14:12:59 +080015628 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
15629 if (ret != RETURN_OK) {
15630 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
15631 return RETURN_ERR;
15632 }
15633 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015634
developera3511852023-06-14 14:12:59 +080015635 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
15636 if (ret != RETURN_OK) {
15637 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
15638 return RETURN_ERR;
15639 }
15640 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015641
developera3511852023-06-14 14:12:59 +080015642 ret = wifi_getApSecurity(vap_index, &security);
15643 if (ret != RETURN_OK) {
15644 printf("%s: wifi_getApSecurity return error\n", __func__);
15645 return RETURN_ERR;
15646 }
15647 map->vap_array[i].u.bss_info.security = security;
developer72fb0bb2023-01-11 09:46:29 +080015648
developera3511852023-06-14 14:12:59 +080015649 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
15650 if (ret != RETURN_OK) {
15651 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
15652 return RETURN_ERR;
15653 }
15654 if (mode == 0)
15655 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
15656 else
15657 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
15658 if (mode == 1)
15659 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
15660 else if (mode == 2)
15661 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
developer72fb0bb2023-01-11 09:46:29 +080015662
developera3511852023-06-14 14:12:59 +080015663 ret = wifi_getApWmmEnable(vap_index, &enabled);
15664 if (ret != RETURN_OK) {
15665 printf("%s: wifi_getApWmmEnable return error\n", __func__);
15666 return RETURN_ERR;
15667 }
15668 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015669
developera3511852023-06-14 14:12:59 +080015670 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
15671 if (ret != RETURN_OK) {
15672 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
15673 return RETURN_ERR;
15674 }
15675 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015676
developera3511852023-06-14 14:12:59 +080015677 memset(buf, 0, sizeof(buf));
15678 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
15679 if (ret != RETURN_OK) {
15680 printf("%s: wifi_getApBeaconRate return error\n", __func__);
15681 return RETURN_ERR;
15682 }
15683 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
developer72fb0bb2023-01-11 09:46:29 +080015684
developera3511852023-06-14 14:12:59 +080015685 memset(buf, 0, sizeof(buf));
15686 ret = wifi_getBaseBSSID(vap_index, buf);
15687 if (ret != RETURN_OK) {
15688 printf("%s: wifi_getBaseBSSID return error\n", __func__);
15689 return RETURN_ERR;
15690 }
developer5b2f10c2023-05-25 17:02:21 +080015691 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
15692 printf("%s: hwaddr_aton2 fail\n", __func__);
developera3511852023-06-14 14:12:59 +080015693 return RETURN_ERR;
developer5b2f10c2023-05-25 17:02:21 +080015694 }
developer72fb0bb2023-01-11 09:46:29 +080015695
developera3511852023-06-14 14:12:59 +080015696 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
15697 if (ret != RETURN_OK) {
15698 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
15699 return RETURN_ERR;
15700 }
15701 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
developer72fb0bb2023-01-11 09:46:29 +080015702
developera3511852023-06-14 14:12:59 +080015703 // TODO: wps, noack
15704 }
15705 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15706 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015707}
15708
developer47cc27a2023-05-17 23:09:58 +080015709void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080015710{
developera3511852023-06-14 14:12:59 +080015711 char if_name[16] = {0};
15712 char cmd[128] = {0};
15713 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080015714 int res;
developer72fb0bb2023-01-11 09:46:29 +080015715
developera3511852023-06-14 14:12:59 +080015716 *enable = FALSE;
15717 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
15718 return;
developer72fb0bb2023-01-11 09:46:29 +080015719
developere40952c2023-06-15 18:46:43 +080015720 res = snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
15721 if (os_snprintf_error(sizeof(cmd), res)) {
15722 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15723 return;
15724 }
developera3511852023-06-14 14:12:59 +080015725 _syscmd(cmd, buf, sizeof(buf));
15726 if (strlen(buf) > 0)
15727 *enable = TRUE;
15728 return;
developer72fb0bb2023-01-11 09:46:29 +080015729}
15730
developer56fbedb2023-05-30 16:47:05 +080015731int hostapd_manage_bss(INT apIndex, BOOL enable)
15732{
15733 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080015734 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer56fbedb2023-05-30 16:47:05 +080015735 char cmd[MAX_CMD_SIZE] = {0};
15736 char buf[MAX_BUF_SIZE] = {0};
15737 BOOL status = FALSE;
15738 int max_radio_num = 0;
15739 int phyId = 0;
developere40952c2023-06-15 18:46:43 +080015740 int res;
developer56fbedb2023-05-30 16:47:05 +080015741
15742 wifi_getApEnable(apIndex, &status);
15743
15744 wifi_getMaxRadioNumber(&max_radio_num);
15745 if (enable == status)
15746 return RETURN_OK;
15747
15748 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
15749 return RETURN_ERR;
15750
15751 if (enable == TRUE) {
15752 int radioIndex = apIndex % max_radio_num;
15753 phyId = radio_index_to_phy(radioIndex);
15754 fprintf(stderr, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080015755 res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
15756 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
15757 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15758 return RETURN_ERR;
15759 }
15760 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
15761 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
15762 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15763 return RETURN_ERR;
15764 }
developer56fbedb2023-05-30 16:47:05 +080015765 _syscmd(cmd, buf, sizeof(buf));
15766 } else {
15767 fprintf(stderr, "%s %d\n", __func__, __LINE__);
developere40952c2023-06-15 18:46:43 +080015768 res = snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
15769 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
15770 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15771 return RETURN_ERR;
15772 }
developer56fbedb2023-05-30 16:47:05 +080015773 _syscmd(cmd, buf, sizeof(buf));
15774 }
developere40952c2023-06-15 18:46:43 +080015775 res = snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
developer56fbedb2023-05-30 16:47:05 +080015776 interface_name, interface_name, enable, VAP_STATUS_FILE);
developere40952c2023-06-15 18:46:43 +080015777 if (os_snprintf_error(MAX_CMD_SIZE, res)) {
15778 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15779 return RETURN_ERR;
15780 }
developer56fbedb2023-05-30 16:47:05 +080015781 _syscmd(cmd, buf, sizeof(buf));
15782 //Wait for wifi up/down to apply
15783 return RETURN_OK;
15784}
15785
15786int hostapd_raw_add_bss(int apIndex)
15787{
15788 return hostapd_manage_bss(apIndex, TRUE);
15789}
15790
15791int hostapd_raw_remove_bss(int apIndex)
15792{
15793 return hostapd_manage_bss(apIndex, FALSE);
15794}
15795
15796int hostapd_raw_restart_bss(int apIndex)
developer333c1eb2023-05-31 14:59:39 +080015797{
developerdaf24792023-06-06 11:40:04 +080015798 int ret = 0;
15799
15800 ret = hostapd_raw_remove_bss(apIndex);
15801 if(ret != RETURN_OK)
15802 return RETURN_ERR;
15803
15804 ret = hostapd_raw_add_bss(apIndex);
15805 if(ret != RETURN_OK)
15806 return RETURN_ERR;
15807
15808 return RETURN_OK;
developer56fbedb2023-05-30 16:47:05 +080015809}
15810
developer72fb0bb2023-01-11 09:46:29 +080015811INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15812{
developera3511852023-06-14 14:12:59 +080015813 unsigned int i;
15814 wifi_vap_info_t *vap_info = NULL;
15815 int acl_mode;
15816 int ret = 0;
15817 char buf[256] = {0};
15818 char cmd[128] = {0};
15819 char config_file[64] = {0};
15820 char psk_file[64] = {0};
15821 BOOL enable = FALSE;
15822 int band_idx;
developere40952c2023-06-15 18:46:43 +080015823 int res;
developere740c2a2023-05-23 18:34:32 +080015824
developer72fb0bb2023-01-11 09:46:29 +080015825
developera3511852023-06-14 14:12:59 +080015826 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15827 printf("Entering %s index = %d\n", __func__, (int)index);
15828 for (i = 0; i < map->num_vaps; i++)
15829 {
15830 multiple_set = TRUE;
15831 vap_info = &map->vap_array[i];
developer72fb0bb2023-01-11 09:46:29 +080015832
developera3511852023-06-14 14:12:59 +080015833 // Check vap status file to enable multiple ap if the system boot.
15834 checkVapStatus(vap_info->vap_index, &enable);
15835 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
15836 continue;
developer72fb0bb2023-01-11 09:46:29 +080015837
developera3511852023-06-14 14:12:59 +080015838 fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
developer72fb0bb2023-01-11 09:46:29 +080015839
developera3511852023-06-14 14:12:59 +080015840 band_idx = radio_index_to_band(index);
developere40952c2023-06-15 18:46:43 +080015841 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
15842 if (os_snprintf_error(sizeof(config_file), res)) {
15843 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15844 return RETURN_ERR;
15845 }
15846 res = snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
15847 if (os_snprintf_error(sizeof(cmd), res)) {
15848 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15849 return RETURN_ERR;
15850 }
developera3511852023-06-14 14:12:59 +080015851 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015852
developera3511852023-06-14 14:12:59 +080015853 struct params params[3];
15854 params[0].name = "interface";
15855 params[0].value = vap_info->vap_name;
developere40952c2023-06-15 18:46:43 +080015856 res = snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
15857 if (os_snprintf_error(sizeof(psk_file), res)) {
15858 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15859 return RETURN_ERR;
15860 }
developera3511852023-06-14 14:12:59 +080015861 params[1].name = "wpa_psk_file";
15862 params[1].value = psk_file;
15863 params[2].name = "ssid";
15864 params[2].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080015865
developera3511852023-06-14 14:12:59 +080015866 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
15867 wifi_hostapdWrite(config_file, params, 3);
developer72fb0bb2023-01-11 09:46:29 +080015868
developere40952c2023-06-15 18:46:43 +080015869 res = snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
15870 if (os_snprintf_error(sizeof(cmd), res)) {
15871 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15872 return RETURN_ERR;
15873 }
developera3511852023-06-14 14:12:59 +080015874 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015875
developera3511852023-06-14 14:12:59 +080015876 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
15877 if (ret != RETURN_OK) {
15878 fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__);
15879 return RETURN_ERR;
15880 }
developer72fb0bb2023-01-11 09:46:29 +080015881
developera3511852023-06-14 14:12:59 +080015882 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
15883 if (ret != RETURN_OK) {
15884 fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__);
15885 return RETURN_ERR;
15886 }
developer72fb0bb2023-01-11 09:46:29 +080015887
developera3511852023-06-14 14:12:59 +080015888 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
15889 if (ret != RETURN_OK) {
15890 fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__);
15891 return RETURN_ERR;
15892 }
developer72fb0bb2023-01-11 09:46:29 +080015893
developera3511852023-06-14 14:12:59 +080015894 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
15895 if (ret != RETURN_OK) {
15896 fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__);
15897 return RETURN_ERR;
15898 }
developer72fb0bb2023-01-11 09:46:29 +080015899
developera3511852023-06-14 14:12:59 +080015900 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
15901 if (ret != RETURN_OK) {
15902 fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__);
15903 return RETURN_ERR;
15904 }
developer72fb0bb2023-01-11 09:46:29 +080015905
developera3511852023-06-14 14:12:59 +080015906 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
15907 if (ret != RETURN_OK) {
15908 fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__);
15909 return RETURN_ERR;
15910 }
developer72fb0bb2023-01-11 09:46:29 +080015911
developera3511852023-06-14 14:12:59 +080015912 if (vap_info->u.bss_info.mac_filter_enable == false){
15913 acl_mode = 0;
15914 }else {
15915 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
15916 acl_mode = 2;
developere40952c2023-06-15 18:46:43 +080015917 res = snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
15918 if (os_snprintf_error(sizeof(cmd), res)) {
15919 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
15920 return RETURN_ERR;
15921 }
developera3511852023-06-14 14:12:59 +080015922 _syscmd(cmd, buf, sizeof(buf));
15923 }else{
15924 acl_mode = 1;
15925 }
15926 }
developer72fb0bb2023-01-11 09:46:29 +080015927
developera3511852023-06-14 14:12:59 +080015928 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
15929 if (ret != RETURN_OK) {
15930 fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__);
15931 return RETURN_ERR;
15932 }
developer72fb0bb2023-01-11 09:46:29 +080015933
developera3511852023-06-14 14:12:59 +080015934 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
15935 if (ret != RETURN_OK) {
15936 fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__);
15937 return RETURN_ERR;
15938 }
developer72fb0bb2023-01-11 09:46:29 +080015939
developera3511852023-06-14 14:12:59 +080015940 memset(buf, 0, sizeof(buf));
15941 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf);
15942 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
15943 if (ret != RETURN_OK) {
15944 fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__);
15945 return RETURN_ERR;
15946 }
developer72fb0bb2023-01-11 09:46:29 +080015947
developera3511852023-06-14 14:12:59 +080015948 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
15949 if (ret != RETURN_OK) {
15950 fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__);
15951 return RETURN_ERR;
15952 }
developer72fb0bb2023-01-11 09:46:29 +080015953
developera3511852023-06-14 14:12:59 +080015954 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
15955 if (ret != RETURN_OK) {
15956 fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__);
15957 return RETURN_ERR;
15958 }
developer333c1eb2023-05-31 14:59:39 +080015959
developer56fbedb2023-05-30 16:47:05 +080015960 hostapd_raw_restart_bss(vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080015961
developera3511852023-06-14 14:12:59 +080015962 multiple_set = FALSE;
developer23e71282023-01-18 10:25:19 +080015963
developera3511852023-06-14 14:12:59 +080015964 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
15965 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
15966 if (ret != RETURN_OK) {
15967 fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__);
15968 return RETURN_ERR;
15969 }
developer72fb0bb2023-01-11 09:46:29 +080015970
developera3511852023-06-14 14:12:59 +080015971 // TODO mgmtPowerControl, interworking, wps
15972 }
15973 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15974 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080015975}
15976
15977int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
15978{
developera3511852023-06-14 14:12:59 +080015979 char *token, *next;
15980 const char s[2] = ",";
15981 int count =0;
developer72fb0bb2023-01-11 09:46:29 +080015982
developera3511852023-06-14 14:12:59 +080015983 /* get the first token */
15984 token = strtok_r(pchannels, s, &next);
developer72fb0bb2023-01-11 09:46:29 +080015985
developera3511852023-06-14 14:12:59 +080015986 /* walk through other tokens */
15987 while( token != NULL && count < MAX_CHANNELS) {
15988 chlistptr->channels_list[count++] = atoi(token);
15989 token = strtok_r(NULL, s, &next);
15990 }
developer72fb0bb2023-01-11 09:46:29 +080015991
developera3511852023-06-14 14:12:59 +080015992 return count;
developer72fb0bb2023-01-11 09:46:29 +080015993}
15994
15995static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
15996{
developera3511852023-06-14 14:12:59 +080015997 INT status;
15998 wifi_channels_list_t *chlistp;
15999 CHAR output_string[64];
16000 CHAR pchannels[128];
16001 CHAR interface_name[16] = {0};
16002 wifi_band band;
developere40952c2023-06-15 18:46:43 +080016003 int res;
developer72fb0bb2023-01-11 09:46:29 +080016004
developera3511852023-06-14 14:12:59 +080016005 if(rcap == NULL)
16006 {
16007 return RETURN_ERR;
16008 }
developer72fb0bb2023-01-11 09:46:29 +080016009
developera3511852023-06-14 14:12:59 +080016010 rcap->numSupportedFreqBand = 1;
16011 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080016012
developera3511852023-06-14 14:12:59 +080016013 if (band == band_2_4)
16014 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
16015 else if (band == band_5)
16016 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
16017 else if (band == band_6)
16018 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
developer72fb0bb2023-01-11 09:46:29 +080016019
developera3511852023-06-14 14:12:59 +080016020 chlistp = &(rcap->channel_list[0]);
16021 memset(pchannels, 0, sizeof(pchannels));
developer72fb0bb2023-01-11 09:46:29 +080016022
developera3511852023-06-14 14:12:59 +080016023 /* possible number of radio channels */
16024 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
16025 {
16026 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
16027 }
16028 /* Number of channels and list*/
16029 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
developer72fb0bb2023-01-11 09:46:29 +080016030
developera3511852023-06-14 14:12:59 +080016031 /* autoChannelSupported */
16032 /* always ON with wifi_getRadioAutoChannelSupported */
16033 rcap->autoChannelSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080016034
developera3511852023-06-14 14:12:59 +080016035 /* DCSSupported */
16036 /* always ON with wifi_getRadioDCSSupported */
16037 rcap->DCSSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080016038
developera3511852023-06-14 14:12:59 +080016039 /* zeroDFSSupported - TBD */
16040 rcap->zeroDFSSupported = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080016041
developera3511852023-06-14 14:12:59 +080016042 /* Supported Country List*/
16043 memset(output_string, 0, sizeof(output_string));
16044 status = wifi_getRadioCountryCode(radioIndex, output_string);
16045 if( status != 0 ) {
16046 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
16047 return RETURN_ERR;
16048 } else {
16049 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
16050 }
16051 if(!strcmp(output_string,"US")){
16052 rcap->countrySupported[0] = wifi_countrycode_US;
16053 rcap->countrySupported[1] = wifi_countrycode_CA;
16054 } else if (!strcmp(output_string,"CA")) {
16055 rcap->countrySupported[0] = wifi_countrycode_CA;
16056 rcap->countrySupported[1] = wifi_countrycode_US;
16057 } else {
16058 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
16059 }
developer72fb0bb2023-01-11 09:46:29 +080016060
developera3511852023-06-14 14:12:59 +080016061 rcap->numcountrySupported = 2;
developer72fb0bb2023-01-11 09:46:29 +080016062
developera3511852023-06-14 14:12:59 +080016063 /* csi */
16064 rcap->csi.maxDevices = 8;
16065 rcap->csi.soudingFrameSupported = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080016066
developera3511852023-06-14 14:12:59 +080016067 wifi_GetInterfaceName(radioIndex, interface_name);
developere40952c2023-06-15 18:46:43 +080016068 res = snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
16069 if (os_snprintf_error(sizeof(interface_name), res)) {
16070 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16071 return RETURN_ERR;
16072 }
developer72fb0bb2023-01-11 09:46:29 +080016073
developera3511852023-06-14 14:12:59 +080016074 /* channelWidth - all supported bandwidths */
16075 int i=0;
16076 rcap->channelWidth[i] = 0;
16077 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
16078 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
16079 WIFI_CHANNELBANDWIDTH_40MHZ);
developer72fb0bb2023-01-11 09:46:29 +080016080
developera3511852023-06-14 14:12:59 +080016081 }
16082 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
16083 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
16084 WIFI_CHANNELBANDWIDTH_40MHZ |
16085 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
16086 }
developer72fb0bb2023-01-11 09:46:29 +080016087
16088
developera3511852023-06-14 14:12:59 +080016089 /* mode - all supported variants */
16090 // rcap->mode[i] = WIFI_80211_VARIANT_H;
16091 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
16092 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
16093 }
16094 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
16095 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
16096 }
16097 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
16098 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
16099 }
16100 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
16101 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
developer72fb0bb2023-01-11 09:46:29 +080016102
developera3511852023-06-14 14:12:59 +080016103 /* supportedBitRate - all supported bitrates */
16104 rcap->supportedBitRate[i] = 0;
16105 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
16106 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
16107 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
16108 }
16109 else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
16110 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
16111 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
16112 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
16113 }
developer72fb0bb2023-01-11 09:46:29 +080016114
16115
developera3511852023-06-14 14:12:59 +080016116 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
16117 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
16118 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
16119 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
16120 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
16121 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
16122 rcap->cipherSupported = 0;
16123 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
16124 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
developer72fb0bb2023-01-11 09:46:29 +080016125
developera3511852023-06-14 14:12:59 +080016126 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016127}
16128
16129INT wifi_getHalCapability(wifi_hal_capability_t *cap)
16130{
developera3511852023-06-14 14:12:59 +080016131 INT status = 0, radioIndex = 0;
16132 char output[MAX_BUF_SIZE] = {0};
16133 int iter = 0;
16134 unsigned int j = 0;
16135 int max_num_radios;
16136 wifi_interface_name_idex_map_t *iface_info = NULL;
developer72fb0bb2023-01-11 09:46:29 +080016137
developera3511852023-06-14 14:12:59 +080016138 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016139
developera3511852023-06-14 14:12:59 +080016140 memset(cap, 0, sizeof(wifi_hal_capability_t));
developer72fb0bb2023-01-11 09:46:29 +080016141
developera3511852023-06-14 14:12:59 +080016142 /* version */
16143 cap->version.major = WIFI_HAL_MAJOR_VERSION;
16144 cap->version.minor = WIFI_HAL_MINOR_VERSION;
developer72fb0bb2023-01-11 09:46:29 +080016145
developera3511852023-06-14 14:12:59 +080016146 /* number of radios platform property */
16147 wifi_getMaxRadioNumber(&max_num_radios);
16148 cap->wifi_prop.numRadios = max_num_radios;
developer72fb0bb2023-01-11 09:46:29 +080016149
developera3511852023-06-14 14:12:59 +080016150 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
16151 {
16152 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
16153 if (status != 0) {
16154 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
16155 return RETURN_ERR;
16156 }
developer72fb0bb2023-01-11 09:46:29 +080016157
developera3511852023-06-14 14:12:59 +080016158 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
16159 {
16160 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
16161 {
16162 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
16163 return RETURN_ERR;
16164 }
16165 iface_info = &cap->wifi_prop.interface_map[iter];
16166 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
16167 iface_info->rdk_radio_index = radioIndex;
16168 memset(output, 0, sizeof(output));
16169 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
16170 {
16171 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
16172 }
16173 // TODO: bridge name
16174 // TODO: vlan id
16175 // TODO: primary
16176 iface_info->index = array_index_to_vap_index(radioIndex, j);
16177 memset(output, 0, sizeof(output));
16178 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
16179 {
16180 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
16181 }
16182 iter++;
16183 }
16184 }
developer72fb0bb2023-01-11 09:46:29 +080016185
developera3511852023-06-14 14:12:59 +080016186 cap->BandSteeringSupported = FALSE;
16187 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16188 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016189}
16190
16191INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
16192{
developera3511852023-06-14 14:12:59 +080016193 struct params h_config={0};
16194 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080016195 int res;
developer72fb0bb2023-01-11 09:46:29 +080016196
developera3511852023-06-14 14:12:59 +080016197 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016198
developera3511852023-06-14 14:12:59 +080016199 h_config.name = "okc";
16200 h_config.value = okc_enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080016201
developere40952c2023-06-15 18:46:43 +080016202 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
16203 if (os_snprintf_error(sizeof(config_file), res)) {
16204 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16205 return RETURN_ERR;
16206 }
developera3511852023-06-14 14:12:59 +080016207 wifi_hostapdWrite(config_file, &h_config, 1);
16208 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080016209
developera3511852023-06-14 14:12:59 +080016210 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
16211 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016212}
16213
16214INT wifi_setSAEMFP(int ap_index, BOOL enable)
16215{
developera3511852023-06-14 14:12:59 +080016216 struct params h_config={0};
16217 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080016218 int res;
developer72fb0bb2023-01-11 09:46:29 +080016219
developera3511852023-06-14 14:12:59 +080016220 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016221
developera3511852023-06-14 14:12:59 +080016222 h_config.name = "sae_require_mfp";
16223 h_config.value = enable?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080016224
developere40952c2023-06-15 18:46:43 +080016225 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
16226 if (os_snprintf_error(sizeof(config_file), res)) {
16227 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16228 return RETURN_ERR;
16229 }
developera3511852023-06-14 14:12:59 +080016230 wifi_hostapdWrite(config_file, &h_config, 1);
16231 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080016232
developera3511852023-06-14 14:12:59 +080016233 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
16234 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016235}
16236
16237INT wifi_setSAEpwe(int ap_index, int sae_pwe)
16238{
developera3511852023-06-14 14:12:59 +080016239 struct params h_config={0};
16240 char config_file[64] = {0};
16241 char buf[128] = {0};
developere40952c2023-06-15 18:46:43 +080016242 int res;
developer72fb0bb2023-01-11 09:46:29 +080016243
developera3511852023-06-14 14:12:59 +080016244 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016245
developera3511852023-06-14 14:12:59 +080016246 h_config.name = "sae_pwe";
developere40952c2023-06-15 18:46:43 +080016247 res = snprintf(buf, sizeof(buf), "%d", sae_pwe);
16248 if (os_snprintf_error(sizeof(buf), res)) {
16249 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16250 return RETURN_ERR;
16251 }
16252
developera3511852023-06-14 14:12:59 +080016253 h_config.value = buf;
developer72fb0bb2023-01-11 09:46:29 +080016254
developere40952c2023-06-15 18:46:43 +080016255 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
16256 if (os_snprintf_error(sizeof(config_file), res)) {
16257 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16258 return RETURN_ERR;
16259 }
developera3511852023-06-14 14:12:59 +080016260 wifi_hostapdWrite(config_file, &h_config, 1);
16261 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080016262
developera3511852023-06-14 14:12:59 +080016263 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
16264 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016265}
16266
16267INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
16268{
developera3511852023-06-14 14:12:59 +080016269 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
16270 struct params h_config={0};
16271 char config_file[64] = {0};
developere40952c2023-06-15 18:46:43 +080016272 int res;
developer72fb0bb2023-01-11 09:46:29 +080016273
developera3511852023-06-14 14:12:59 +080016274 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016275
developera3511852023-06-14 14:12:59 +080016276 h_config.name = "wpa_disable_eapol_key_retries";
16277 h_config.value = disable_EAPOL_retries?"1":"0";
developer72fb0bb2023-01-11 09:46:29 +080016278
developere40952c2023-06-15 18:46:43 +080016279 res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
16280 if (os_snprintf_error(sizeof(config_file), res)) {
16281 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16282 return RETURN_ERR;
16283 }
developera3511852023-06-14 14:12:59 +080016284 wifi_hostapdWrite(config_file, &h_config, 1);
16285 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
developer72fb0bb2023-01-11 09:46:29 +080016286
developera3511852023-06-14 14:12:59 +080016287 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
16288 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016289}
16290
16291INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
16292{
developera3511852023-06-14 14:12:59 +080016293 char buf[128] = {0};
16294 char config_file[128] = {0};
16295 char cmd[MAX_CMD_SIZE] = {0};
16296 char password[65] = {0};
16297 char mfp[32] = {0};
16298 char wpa_mode[32] = {0};
16299 BOOL okc_enable = FALSE;
16300 BOOL sae_MFP = FALSE;
16301 BOOL disable_EAPOL_retries = TRUE;
16302 int sae_pwe = 0;
16303 struct params params = {0};
16304 wifi_band band = band_invalid;
developere40952c2023-06-15 18:46:43 +080016305 int res;
developer72fb0bb2023-01-11 09:46:29 +080016306
developera3511852023-06-14 14:12:59 +080016307 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016308
developera3511852023-06-14 14:12:59 +080016309 multiple_set = TRUE;
16310 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
16311 if (security->mode == wifi_security_mode_none) {
16312 strcpy(wpa_mode, "None");
16313 } else if (security->mode == wifi_security_mode_wpa_personal)
16314 strcpy(wpa_mode, "WPA-Personal");
16315 else if (security->mode == wifi_security_mode_wpa2_personal)
16316 strcpy(wpa_mode, "WPA2-Personal");
16317 else if (security->mode == wifi_security_mode_wpa_wpa2_personal)
16318 strcpy(wpa_mode, "WPA-WPA2-Personal");
16319 else if (security->mode == wifi_security_mode_wpa_enterprise)
16320 strcpy(wpa_mode, "WPA-Enterprise");
16321 else if (security->mode == wifi_security_mode_wpa2_enterprise)
16322 strcpy(wpa_mode, "WPA2-Enterprise");
16323 else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise)
16324 strcpy(wpa_mode, "WPA-WPA2-Enterprise");
16325 else if (security->mode == wifi_security_mode_wpa3_personal) {
16326 strcpy(wpa_mode, "WPA3-Personal");
16327 okc_enable = TRUE;
16328 sae_MFP = TRUE;
16329 sae_pwe = 2;
16330 disable_EAPOL_retries = FALSE;
16331 } else if (security->mode == wifi_security_mode_wpa3_transition) {
16332 strcpy(wpa_mode, "WPA3-Personal-Transition");
16333 okc_enable = TRUE;
16334 sae_MFP = TRUE;
16335 sae_pwe = 2;
16336 disable_EAPOL_retries = FALSE;
16337 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
16338 strcpy(wpa_mode, "WPA3-Enterprise");
16339 sae_MFP = TRUE;
16340 sae_pwe = 2;
16341 disable_EAPOL_retries = FALSE;
16342 } else if (security->mode == wifi_security_mode_enhanced_open) {
16343 strcpy(wpa_mode, "OWE");
16344 sae_MFP = TRUE;
16345 sae_pwe = 2;
16346 disable_EAPOL_retries = FALSE;
16347 }
developer72fb0bb2023-01-11 09:46:29 +080016348
developera3511852023-06-14 14:12:59 +080016349 band = wifi_index_to_band(ap_index);
16350 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
16351 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
16352 return RETURN_ERR;
16353 }
developer72fb0bb2023-01-11 09:46:29 +080016354
developera3511852023-06-14 14:12:59 +080016355 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
16356 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
16357 wifi_setSAEMFP(ap_index, sae_MFP);
16358 wifi_setSAEpwe(ap_index, sae_pwe);
16359 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
developer72fb0bb2023-01-11 09:46:29 +080016360
developera3511852023-06-14 14:12:59 +080016361 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
16362 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) {
16363 int key_len = strlen(security->u.key.key);
16364 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
16365 if (key_len == 64) { // set wpa_psk
16366 strncpy(password, security->u.key.key, 64); // 64 characters
16367 password[64] = '\0';
16368 wifi_setApSecurityPreSharedKey(ap_index, password);
developere40952c2023-06-15 18:46:43 +080016369 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
16370 if (os_snprintf_error(sizeof(cmd), res)) {
16371 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16372 return RETURN_ERR;
16373 }
developera3511852023-06-14 14:12:59 +080016374 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
16375 strncpy(password, security->u.key.key, 63);
16376 password[63] = '\0';
16377 wifi_setApSecurityKeyPassphrase(ap_index, password);
developere40952c2023-06-15 18:46:43 +080016378 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
developera3511852023-06-14 14:12:59 +080016379 } else
16380 return RETURN_ERR;
16381 _syscmd(cmd, buf, sizeof(buf));
16382 }
16383 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
16384 params.name = "sae_password";
16385 params.value = security->u.key.key;
16386 wifi_hostapdWrite(config_file, &params, 1);
16387 } else { // remove sae_password
developere40952c2023-06-15 18:46:43 +080016388 res = snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
16389 if (os_snprintf_error(sizeof(cmd), res)) {
16390 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16391 return RETURN_ERR;
16392 }
developera3511852023-06-14 14:12:59 +080016393 _syscmd(cmd, buf, sizeof(buf));
16394 }
16395 }
developer72fb0bb2023-01-11 09:46:29 +080016396
developera3511852023-06-14 14:12:59 +080016397 if (security->mode != wifi_security_mode_none) {
16398 memset(&params, 0, sizeof(params));
16399 params.name = "wpa_pairwise";
16400 if (security->encr == wifi_encryption_tkip)
16401 params.value = "TKIP";
16402 else if (security->encr == wifi_encryption_aes)
16403 params.value = "CCMP";
16404 else if (security->encr == wifi_encryption_aes_tkip)
16405 params.value = "TKIP CCMP";
16406 wifi_hostapdWrite(config_file, &params, 1);
16407 }
developer72fb0bb2023-01-11 09:46:29 +080016408
developera3511852023-06-14 14:12:59 +080016409 if (security->mfp == wifi_mfp_cfg_disabled)
16410 strcpy(mfp, "Disabled");
16411 else if (security->mfp == wifi_mfp_cfg_optional)
16412 strcpy(mfp, "Optional");
16413 else if (security->mfp == wifi_mfp_cfg_required)
16414 strcpy(mfp, "Required");
16415 wifi_setApSecurityMFPConfig(ap_index, mfp);
developer72fb0bb2023-01-11 09:46:29 +080016416
developera3511852023-06-14 14:12:59 +080016417 memset(&params, 0, sizeof(params));
16418 params.name = "transition_disable";
16419 if (security->wpa3_transition_disable == TRUE)
16420 params.value = "0x01";
16421 else
16422 params.value = "0x00";
16423 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080016424
developera3511852023-06-14 14:12:59 +080016425 memset(&params, 0, sizeof(params));
16426 params.name = "wpa_group_rekey";
developere40952c2023-06-15 18:46:43 +080016427 res = snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
16428 if (os_snprintf_error(sizeof(buf), res)) {
16429 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16430 return RETURN_ERR;
16431 }
developera3511852023-06-14 14:12:59 +080016432 params.value = buf;
16433 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080016434
developera3511852023-06-14 14:12:59 +080016435 memset(&params, 0, sizeof(params));
16436 params.name = "wpa_strict_rekey";
16437 params.value = security->strict_rekey?"1":"0";
16438 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080016439
developera3511852023-06-14 14:12:59 +080016440 memset(&params, 0, sizeof(params));
16441 params.name = "wpa_pairwise_update_count";
16442 if (security->eapol_key_retries == 0)
16443 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developere40952c2023-06-15 18:46:43 +080016444 res = snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
16445 if (os_snprintf_error(sizeof(buf), res)) {
16446 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
16447 return RETURN_ERR;
16448 }
developera3511852023-06-14 14:12:59 +080016449 params.value = buf;
16450 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080016451
developera3511852023-06-14 14:12:59 +080016452 memset(&params, 0, sizeof(params));
16453 params.name = "disable_pmksa_caching";
16454 params.value = security->disable_pmksa_caching?"1":"0";
16455 wifi_hostapdWrite(config_file, &params, 1);
developer72fb0bb2023-01-11 09:46:29 +080016456
developera3511852023-06-14 14:12:59 +080016457 if (multiple_set == FALSE) {
16458 wifi_setApEnable(ap_index, FALSE);
16459 wifi_setApEnable(ap_index, TRUE);
16460 }
developer72fb0bb2023-01-11 09:46:29 +080016461
developera3511852023-06-14 14:12:59 +080016462 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016463
developera3511852023-06-14 14:12:59 +080016464 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016465}
16466
16467INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
16468{
developera3511852023-06-14 14:12:59 +080016469 char buf[256] = {0};
16470 char config_file[128] = {0};
16471 int disable = 0;
16472 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080016473
developera3511852023-06-14 14:12:59 +080016474 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16475 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
16476 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
16477 security->mode = wifi_security_mode_none;
16478 if (strlen(buf) != 0) {
16479 if (!strcmp(buf, "WPA-Personal"))
16480 security->mode = wifi_security_mode_wpa_personal;
16481 else if (!strcmp(buf, "WPA2-Personal"))
16482 security->mode = wifi_security_mode_wpa2_personal;
16483 else if (!strcmp(buf, "WPA-WPA2-Personal"))
16484 security->mode = wifi_security_mode_wpa_wpa2_personal;
16485 else if (!strcmp(buf, "WPA-Enterprise"))
16486 security->mode = wifi_security_mode_wpa_enterprise;
16487 else if (!strcmp(buf, "WPA2-Enterprise"))
16488 security->mode = wifi_security_mode_wpa2_enterprise;
16489 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
16490 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
16491 else if (!strcmp(buf, "WPA3-Personal"))
16492 security->mode = wifi_security_mode_wpa3_personal;
16493 else if (!strcmp(buf, "WPA3-Personal-Transition"))
16494 security->mode = wifi_security_mode_wpa3_transition;
16495 else if (!strcmp(buf, "WPA3-Enterprise"))
16496 security->mode = wifi_security_mode_wpa3_enterprise;
16497 else if (!strcmp(buf, "OWE"))
16498 security->mode = wifi_security_mode_enhanced_open;
16499 }
developer72fb0bb2023-01-11 09:46:29 +080016500
developera3511852023-06-14 14:12:59 +080016501 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
16502 if (security->mode == wifi_security_mode_none)
16503 security->encr = wifi_encryption_none;
16504 else {
16505 if (strcmp(buf, "TKIP") == 0)
16506 security->encr = wifi_encryption_tkip;
16507 else if (strcmp(buf, "CCMP") == 0)
16508 security->encr = wifi_encryption_aes;
16509 else
16510 security->encr = wifi_encryption_aes_tkip;
16511 }
developer72fb0bb2023-01-11 09:46:29 +080016512
developera3511852023-06-14 14:12:59 +080016513 if (security->mode != wifi_security_mode_none) {
16514 memset(buf, 0, sizeof(buf));
16515 // wpa3 can use one or both configs as password, so we check sae_password first.
16516 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
16517 if (strlen(buf) != 0) {
16518 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
16519 security->u.key.type = wifi_security_key_type_sae;
16520 set_sae = TRUE;
16521 strncpy(security->u.key.key, buf, sizeof(buf));
16522 }
16523 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
16524 if (strlen(buf) != 0){
16525 if (set_sae == TRUE)
16526 security->u.key.type = wifi_security_key_type_psk_sae;
16527 else if (strlen(buf) == 64)
16528 security->u.key.type = wifi_security_key_type_psk;
16529 else
16530 security->u.key.type = wifi_security_key_type_pass;
16531 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
16532 }
16533 security->u.key.key[255] = '\0';
16534 }
developer72fb0bb2023-01-11 09:46:29 +080016535
developera3511852023-06-14 14:12:59 +080016536 memset(buf, 0, sizeof(buf));
16537 wifi_getApSecurityMFPConfig(ap_index, buf);
16538 if (strcmp(buf, "Disabled") == 0)
16539 security->mfp = wifi_mfp_cfg_disabled;
16540 else if (strcmp(buf, "Optional") == 0)
16541 security->mfp = wifi_mfp_cfg_optional;
16542 else if (strcmp(buf, "Required") == 0)
16543 security->mfp = wifi_mfp_cfg_required;
developer72fb0bb2023-01-11 09:46:29 +080016544
developera3511852023-06-14 14:12:59 +080016545 memset(buf, 0, sizeof(buf));
16546 security->wpa3_transition_disable = FALSE;
16547 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
16548 disable = strtol(buf, NULL, 16);
16549 if (disable != 0)
16550 security->wpa3_transition_disable = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080016551
developera3511852023-06-14 14:12:59 +080016552 memset(buf, 0, sizeof(buf));
16553 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
16554 if (strlen(buf) == 0)
16555 security->rekey_interval = 86400;
16556 else
16557 security->rekey_interval = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080016558
developera3511852023-06-14 14:12:59 +080016559 memset(buf, 0, sizeof(buf));
16560 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
16561 if (strlen(buf) == 0)
16562 security->strict_rekey = 1;
16563 else
16564 security->strict_rekey = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080016565
developera3511852023-06-14 14:12:59 +080016566 memset(buf, 0, sizeof(buf));
16567 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
16568 if (strlen(buf) == 0)
16569 security->eapol_key_retries = 4;
16570 else
16571 security->eapol_key_retries = strtol(buf, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080016572
developera3511852023-06-14 14:12:59 +080016573 memset(buf, 0, sizeof(buf));
16574 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
16575 if (strlen(buf) == 0)
16576 security->disable_pmksa_caching = FALSE;
16577 else
16578 security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE;
developer72fb0bb2023-01-11 09:46:29 +080016579
developera3511852023-06-14 14:12:59 +080016580 /* TODO
16581 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
16582 */
16583 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
16584 security->eap_identity_req_timeout = 0;
16585 security->eap_identity_req_retries = 0;
16586 security->eap_req_timeout = 0;
16587 security->eap_req_retries = 0;
16588 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16589 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016590}
16591
16592#endif /* WIFI_HAL_VERSION_3 */
16593
16594#ifdef WIFI_HAL_VERSION_3_PHASE2
16595INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
16596{
developera3511852023-06-14 14:12:59 +080016597 char interface_name[16] = {0};
16598 char cmd[128] = {0};
16599 char buf[128] = {0};
16600 char *mac_addr = NULL;
16601 BOOL status = FALSE;
16602 size_t len = 0;
developer72fb0bb2023-01-11 09:46:29 +080016603
developera3511852023-06-14 14:12:59 +080016604 if(ap_index > MAX_APS)
16605 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016606
developera3511852023-06-14 14:12:59 +080016607 *output_numDevices = 0;
16608 wifi_getApEnable(ap_index, &status);
16609 if (status == FALSE)
16610 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016611
developera3511852023-06-14 14:12:59 +080016612 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
16613 return RETURN_ERR;
16614 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
16615 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080016616
developera3511852023-06-14 14:12:59 +080016617 mac_addr = strtok(buf, "\n");
16618 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
16619 *output_numDevices = i + 1;
16620 fprintf(stderr, "mac_addr: %s\n", mac_addr);
16621 addr_ptr = output_deviceMacAddressArray[i];
16622 mac_addr_aton(addr_ptr, mac_addr);
16623 mac_addr = strtok(NULL, "\n");
16624 }
developer72fb0bb2023-01-11 09:46:29 +080016625
developera3511852023-06-14 14:12:59 +080016626 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016627}
16628#else
16629INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
16630{
developera3511852023-06-14 14:12:59 +080016631 char interface_name[16] = {0};
16632 char cmd[128];
16633 BOOL status = false;
developer72fb0bb2023-01-11 09:46:29 +080016634
developera3511852023-06-14 14:12:59 +080016635 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
16636 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016637
developera3511852023-06-14 14:12:59 +080016638 output_buf[0] = '\0';
developer72fb0bb2023-01-11 09:46:29 +080016639
developera3511852023-06-14 14:12:59 +080016640 wifi_getApEnable(ap_index,&status);
16641 if (!status)
16642 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016643
developera3511852023-06-14 14:12:59 +080016644 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
16645 return RETURN_ERR;
16646 sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
16647 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080016648
developera3511852023-06-14 14:12:59 +080016649 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016650}
16651#endif
16652
16653INT wifi_getProxyArp(INT apIndex, BOOL *enable)
16654{
developera3511852023-06-14 14:12:59 +080016655 char output[16]={'\0'};
16656 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080016657
developera3511852023-06-14 14:12:59 +080016658 if (!enable)
16659 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080016660
developera3511852023-06-14 14:12:59 +080016661 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
16662 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080016663
developera3511852023-06-14 14:12:59 +080016664 if (strlen(output) == 0)
16665 *enable = FALSE;
16666 else if (strncmp(output, "1", 1) == 0)
16667 *enable = TRUE;
16668 else
16669 *enable = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080016670
developera3511852023-06-14 14:12:59 +080016671 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
16672 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016673}
16674
16675INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
16676{
developera3511852023-06-14 14:12:59 +080016677 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
16678 return RETURN_ERR;
16679 *output_enable=TRUE;
16680 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016681}
16682
16683INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
16684{
developera3511852023-06-14 14:12:59 +080016685 char cmd[128] = {0};
16686 char buf[128] = {0};
16687 char line[128] = {0};
16688 FILE *f = NULL;
16689 int index = 0;
16690 int exp = 0;
16691 int mantissa = 0;
16692 int duration = 0;
16693 int radio_index = 0;
16694 int max_radio_num = 0;
16695 uint twt_wake_interval = 0;
16696 int phyId = 0;
16697 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080016698
developera3511852023-06-14 14:12:59 +080016699 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +080016700
developera3511852023-06-14 14:12:59 +080016701 radio_index = ap_index % max_radio_num;
developer72fb0bb2023-01-11 09:46:29 +080016702
developera3511852023-06-14 14:12:59 +080016703 phyId = radio_index_to_phy(radio_index);
16704 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
16705 _syscmd(cmd, buf, sizeof(buf));
16706 *numSessionReturned = strtol(buf, NULL, 10) - 1;
16707 if (*numSessionReturned > maxNumberSessions)
16708 *numSessionReturned = maxNumberSessions;
16709 else if (*numSessionReturned < 1) {
16710 *numSessionReturned = 0;
16711 return RETURN_OK;
16712 }
developer72fb0bb2023-01-11 09:46:29 +080016713
developera3511852023-06-14 14:12:59 +080016714 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
16715 if ((f = popen(cmd, "r")) == NULL) {
16716 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
16717 return RETURN_ERR;
16718 }
developer72fb0bb2023-01-11 09:46:29 +080016719
developera3511852023-06-14 14:12:59 +080016720 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
16721 while((fgets(line, sizeof(line), f)) != NULL) {
16722 char *tmp = NULL;
16723 strcpy(buf, line);
16724 tmp = strtok(buf, " ");
16725 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
16726 tmp = strtok(NULL, " ");
16727 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
16728 tmp = strtok(NULL, " ");
16729 if (strstr(tmp, "t")) {
16730 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
16731 }
16732 if (strstr(tmp, "a")) {
16733 twtSessions[index].twtParameters.operation.announced = TRUE;
16734 }
16735 tmp = strtok(NULL, " ");
16736 exp = strtol(tmp, NULL, 10);
16737 tmp = strtok(NULL, " ");
16738 mantissa = strtol(tmp, NULL, 10);
16739 tmp = strtok(NULL, " ");
16740 duration = strtol(tmp, NULL, 10);
developer72fb0bb2023-01-11 09:46:29 +080016741
developera3511852023-06-14 14:12:59 +080016742 // only implicit supported
16743 twtSessions[index].twtParameters.operation.implicit = TRUE;
16744 // only individual agreement supported
16745 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
developer72fb0bb2023-01-11 09:46:29 +080016746
developera3511852023-06-14 14:12:59 +080016747 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
16748 twt_wake_interval = mantissa * (1 << exp);
16749 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
16750 // Overflow handling
16751 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
16752 } else {
16753 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
16754 }
16755 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
16756 index++;
16757 }
developer72fb0bb2023-01-11 09:46:29 +080016758
developera3511852023-06-14 14:12:59 +080016759 pclose(f);
16760 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16761 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080016762}
developercc5cbfb2023-06-13 18:29:52 +080016763
16764INT wifi_enableGreylistAccessControl(BOOL enable)
16765{
16766 char inf_name[IFNAMSIZ] = {0};
16767 int if_idx, ret = 0;
16768 struct nl_msg *msg = NULL;
16769 struct nlattr * msg_data = NULL;
16770 struct mtk_nl80211_param param;
16771 struct unl unl_ins;
16772 unsigned short apIndex = 0;
16773
16774 for (apIndex = 0; apIndex < MAX_APS; apIndex++) {
16775 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
16776 continue;
16777
16778 if_idx = if_nametoindex(inf_name);
16779 if (!if_idx) {
16780 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
16781 continue;
16782 }
16783
16784 /*init mtk nl80211 vendor cmd*/
16785 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
16786 param.if_type = NL80211_ATTR_IFINDEX;
16787 param.if_idx = if_idx;
16788 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
16789 if (ret) {
16790 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
16791 return RETURN_ERR;
16792 }
16793
16794 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, enable == FALSE ? 0 : 1)) {
16795 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
16796 nlmsg_free(msg);
16797 mtk_nl80211_deint(&unl_ins);
16798 continue;
16799 }
16800
16801 /*send mtk nl80211 vendor msg*/
16802 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
16803 if (ret) {
16804 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
16805 mtk_nl80211_deint(&unl_ins);
16806 continue;
16807 }
16808 /*deinit mtk nl80211 vendor msg*/
16809 mtk_nl80211_deint(&unl_ins);
16810 wifi_debug(DEBUG_NOTICE, " %s cmd success.\n", inf_name);
16811 }
16812
16813 return RETURN_OK;
16814}