blob: 91e5276dc8981e7372a9f76a07a9c940a5320e41 [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:
31Copyright (c) 2007, 2008 Johannes Berg
32Copyright (c) 2007 Andy Lutomirski
33Copyright (c) 2007 Mike Kershaw
34Copyright (c) 2008-2009 Luis R. Rodriguez
35Licensed 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>
66#define MAC_ALEN 6
67
68#define MAX_BUF_SIZE 256
69#define MAX_CMD_SIZE 256
developerb149d9d2023-06-06 16:14:22 +080070#define MAX_SUB_CMD_SIZE 200
71
developer72fb0bb2023-01-11 09:46:29 +080072#define IF_NAME_SIZE 16
73#define CONFIG_PREFIX "/nvram/hostapd"
74#define ACL_PREFIX "/nvram/hostapd-acl"
75#define DENY_PREFIX "/nvram/hostapd-deny"
76//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
77#define SOCK_PREFIX "/var/run/hostapd/wifi"
78#define VAP_STATUS_FILE "/nvram/vap-status"
79#define ESSID_FILE "/tmp/essid"
80#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
81#define CHANNEL_STATS_FILE "/tmp/channel_stats"
82#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
83#define VLAN_FILE "/nvram/hostapd.vlan"
84#define PSK_FILE "/nvram/hostapd"
85#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080086#define POWER_PERCENTAGE "/tmp/POWER"
87#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
88/*LOGAN_DAT_FILE: may be different on customer's platform.*/
89#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +080090#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +080091
developer72fb0bb2023-01-11 09:46:29 +080092#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +080093#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +080094
developer72fb0bb2023-01-11 09:46:29 +080095#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +080096#define BASE_PHY_INDEX 1
97#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +080098
99/*
100 MAX_APS - Number of all AP available in system
101 2x Home AP
102 2x Backhaul AP
103 2x Guest AP
104 2x Secure Onboard AP
105 2x Service AP
106
107*/
108
109
110#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800111
112#define PREFIX_WIFI2G "ra"
113#define PREFIX_WIFI5G "rai"
114#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800115
developer47cc27a2023-05-17 23:09:58 +0800116#define PREFIX_SSID_2G "RDKB_2G"
117#define PREFIX_SSID_5G "RDKB_5G"
118#define PREFIX_SSID_6G "RDKB_6G"
119
developer72fb0bb2023-01-11 09:46:29 +0800120#ifndef RADIO_PREFIX
121#define RADIO_PREFIX "wlan"
122#endif
123
124#define MAX_ASSOCIATED_STA_NUM 2007
125
126//Uncomment to enable debug logs
127//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800128enum {
129 DEBUG_OFF = 0,
130 DEBUG_ERROR = 1,
131 DEBUG_WARN = 2,
132 DEBUG_NOTICE = 3,
133 DEBUG_INFO = 4
134};
135int wifi_debug_level = DEBUG_NOTICE;
136#define wifi_debug(level, fmt, args...) \
137{ \
138 if (level <= wifi_debug_level) \
139 { \
developer2edaf012023-05-24 14:24:53 +0800140 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800141 } \
142}
developer72fb0bb2023-01-11 09:46:29 +0800143
144#ifdef WIFI_DEBUG
145#define wifi_dbg_printf printf
146#define WIFI_ENTRY_EXIT_DEBUG printf
147#else
developer2f79c922023-06-02 17:33:42 +0800148#define wifi_dbg_printf(format, args...)
149#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
developer72fb0bb2023-01-11 09:46:29 +0800150#endif
151
152#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
153#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
154#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
155#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
156#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
157#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
158#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
159#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
160#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
161#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
162
163#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
164
165#define BW_FNAME "/nvram/bw_file.txt"
166
167#define PS_MAX_TID 16
168
developer96b38512023-02-22 11:17:45 +0800169#define MAX_CARD_INDEX 3
170
developer72fb0bb2023-01-11 09:46:29 +0800171static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
172 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
173 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
174 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
175 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
176 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
177 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
178 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
179 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
180 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
181 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
182 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
183 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
184 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
185 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
186 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
187 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
188};
189
190typedef unsigned long long u64;
191
192/* Enum to define WiFi Bands */
193typedef enum
194{
195 band_invalid = -1,
196 band_2_4 = 0,
197 band_5 = 1,
198 band_6 = 2,
199} wifi_band;
200
developer17038e62023-03-02 14:43:43 +0800201char* wifi_band_str[] = {
202 "2G",
203 "5G",
204 "6G",
205};
206
developer72fb0bb2023-01-11 09:46:29 +0800207typedef enum {
208 WIFI_MODE_A = 0x01,
209 WIFI_MODE_B = 0x02,
210 WIFI_MODE_G = 0x04,
211 WIFI_MODE_N = 0x08,
212 WIFI_MODE_AC = 0x10,
213 WIFI_MODE_AX = 0x20,
developera1255e42023-05-13 17:45:02 +0800214 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800215} wifi_ieee80211_Mode;
216
developer2f79c922023-06-02 17:33:42 +0800217typedef enum {
developerd1824452023-05-18 12:30:04 +0800218 HT_BW_20,
219 HT_BW_40,
developer2f79c922023-06-02 17:33:42 +0800220} ht_config_bw;
developerd1824452023-05-18 12:30:04 +0800221
developer2f79c922023-06-02 17:33:42 +0800222typedef enum {
developerd1824452023-05-18 12:30:04 +0800223 VHT_BW_2040,
224 VHT_BW_80,
225 VHT_BW_160,
226 VHT_BW_8080,
developer2f79c922023-06-02 17:33:42 +0800227} vht_config_bw;
developerd1824452023-05-18 12:30:04 +0800228
developer2f79c922023-06-02 17:33:42 +0800229typedef enum {
developerd1824452023-05-18 12:30:04 +0800230 EHT_BW_20,
231 EHT_BW_40,
232 EHT_BW_80,
233 EHT_BW_160,
234 EHT_BW_320,
developer2f79c922023-06-02 17:33:42 +0800235} eht_config_bw;
developerd1824452023-05-18 12:30:04 +0800236
developer72fb0bb2023-01-11 09:46:29 +0800237#ifdef WIFI_HAL_VERSION_3
238
239// Return number of elements in array
240#ifndef ARRAY_SIZE
241#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
242#endif /* ARRAY_SIZE */
243
244#ifndef ARRAY_AND_SIZE
245#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
246#endif /* ARRAY_AND_SIZE */
247
248#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
249
250typedef struct {
251 int32_t value;
252 int32_t param;
253 intptr_t key;
254 intptr_t data;
255} wifi_secur_list;
256
257static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
258static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
259wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
260wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
261char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
262static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developer47cc27a2023-05-17 23:09:58 +0800263static void wifi_PrepareDefaultHostapdConfigs(void);
264static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800265static void wifi_dat_file_reset_by_radio(char radio_idx);
developer262f4cb2023-05-24 12:22:04 +0800266static int util_get_sec_chan_offset(int channel, const char* ht_mode);
developer2f79c922023-06-02 17:33:42 +0800267int hostapd_raw_add_bss(int apIndex);
268int hostapd_raw_remove_bss(int apIndex);
developer47cc27a2023-05-17 23:09:58 +0800269
developer49b17232023-05-19 16:35:19 +0800270/*type define the nl80211 call back func*/
271typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
272
273/**
274*struct mtk_nl80211_param
275* init mtk nl80211 using parameters
276* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
277* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
278* @if_idx: the index should match the interface or wiphy.
279* Note: NA
280**/
281struct mtk_nl80211_param {
282 unsigned int sub_cmd;
283 int if_type;
284 int if_idx;
285};
286
287/**
developer121a8e72023-05-22 09:19:39 +0800288*struct mtk_nl80211_cb_data
289* init mtk nl80211 call back parameters
290* @out_buf: store the mtk vendor output msg for wifi hal buffer.
291* @out_len: the output buffer length.
292* Note: NA
293**/
294struct mtk_nl80211_cb_data {
295 char * out_buf;
296 unsigned int out_len;
297};
298
299/**
developer49b17232023-05-19 16:35:19 +0800300*mtk_nl80211_init
301* init mtk nl80211 netlink and init the vendor msg common part.
302* @nl: netlink, just init it.
303* @msg: netlink message will alloc it.
304* the msg send success/fails is not free by app
305* only the nla_put etc api fails should use nlmsg_free.
306* @msg_data: vendor data msg attr pointer.
307* @param: init using interface and sub_cmd parameter.
308*
309*init the netlink context and mtk netlink vendor msg.
310*
311*return:
312* 0: success
313* other: fail
314**/
315
316int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
317 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
318 /*sanity check here*/
319 if (!nl || !param) {
320 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800321 "[%s][%d]:nl(%p) or param(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800322 __func__, __LINE__, nl, param);
323 return -1;
324 }
325 /*if_type check*/
326 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
327 (void)fprintf(stderr,
328 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
329 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
330 return -1;
331 }
332 /*init the nl*/
333 if (unl_genl_init(nl, "nl80211") < 0) {
334 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
335 __func__, __LINE__);
336 return -1;
337 }
338 /*init the msg*/
339 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
340
341 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
342 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
343 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
344 (void)fprintf(stderr,
345 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
346 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
347 goto err;
348 }
349
350 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
351 if (!*msg_data) {
352 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
353 __func__, __LINE__);
354 goto err;
355 }
356
357 return 0;
358err:
developer49b17232023-05-19 16:35:19 +0800359 nlmsg_free(*msg);
360 unl_free(nl);
361 return -1;
362}
363
364/**
365*mtk_nl80211_send
366* set the vendor cmd call back and sent the vendor msg.
367* @nl: netlink.
368* @msg: netlink message.
369* @msg_data: vendor data msg attr pointer.
370* @handler: if the msg have call back shoud add the call back func
371* the event msg will handle by the call back func(exp:get cmd)
372* other set it as NULL(exp:set cmd).
373* @arg:call back func arg parameter.
374*add end of the netlink msg, set the call back and send msg
375*
376*return:
377* 0: success
378* other: fail
379**/
380int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
381 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
382 int ret = 0;
383 /*sanity check*/
384 if (!nl || !msg || !msg_data) {
385 (void)fprintf(stderr,
developerdaf24792023-06-06 11:40:04 +0800386 "[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
developer49b17232023-05-19 16:35:19 +0800387 __func__, __LINE__, nl, msg, msg_data);
388 return -1;
389 }
390 /*end the msg attr of vendor data*/
391 nla_nest_end(msg, msg_data);
392 /*send the msg and set call back */
393 ret = unl_genl_request(nl, msg, handler, arg);
394 if (ret)
395 (void)fprintf(stderr, "send nl80211 cmd fails\n");
396 return ret;
397}
398
399/**
400*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800401* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800402* @nl: netlink.
403*
developer2edaf012023-05-24 14:24:53 +0800404*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800405*
406*return:
407* 0: success
408**/
409
410int mtk_nl80211_deint(struct unl *nl) {
411 unl_free(nl);
412 return 0;
413}
414
developer22e0c672023-06-07 15:25:37 +0800415static inline int os_snprintf_error(size_t size, int res)
416{
417 return res < 0 || (unsigned int) res >= size;
418}
419
developer72fb0bb2023-01-11 09:46:29 +0800420wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
421{
422 wifi_secur_list *item;
423 int i;
424
425 for (item = list,i = 0;i < list_sz; item++, i++) {
426 if ((int)(item->key) == key) {
427 return item;
428 }
429 }
430
431 return NULL;
432}
433
434char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
435{
436 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
437
438 if (!item) {
439 return "";
440 }
441
442 return (char *)(item->data);
443}
444
445wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
446{
447 wifi_secur_list *item;
448 int i;
449
450 for (item = list,i = 0;i < list_sz; item++, i++) {
451 if (strcmp((char *)(item->data), str) == 0) {
452 return item;
453 }
454 }
455
456 return NULL;
457}
458#endif /* WIFI_HAL_VERSION_3 */
459
developer96b38512023-02-22 11:17:45 +0800460
461static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800462char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
463char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
464#define MAX_SSID_LEN 64
465char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800466int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800467
468static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
469static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
470
developer96b38512023-02-22 11:17:45 +0800471
472static int
473get_value(const char *conf_file, const char *param, char *value, int len)
474{
475 FILE *fp;
476 int ret = -1;
477 int param_len = strlen(param);
478 int buf_len;
479 char buf[256];
480
481 fp = fopen(conf_file, "r");
482 if (!fp) {
483 return -1;
484 }
485
486 while (fgets(buf, sizeof(buf), fp)) {
487 buf_len = strlen(buf);
488 if (buf[buf_len - 1] == '\n') {
489 buf_len--;
490 buf[buf_len] = '\0';
491 }
492 if ((buf_len > param_len) &&
493 (strncmp(buf, param, param_len) == 0) &&
494 (buf[param_len] == '=')) {
495
496 if (buf_len == (param_len + 1)) {
497 value[0] = '\0';
498 ret = 0;
499 } else {
500 ret = snprintf(value, len, "%s", buf + (param_len + 1));
501 }
502 fclose(fp);
503 return ret;
504 }
505 }
506 fclose(fp);
507 return -1;
508}
509
510static int
511get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
512{
513 char buf[256];
514 int ret;
515 char *save_ptr = NULL;
516 char *tok = NULL;
517
518 ret = get_value(conf_file, param, buf, sizeof(buf));
519 if (ret < 0)
520 return ret;
521
522 tok = strtok_r(buf, ";", &save_ptr);
523 do {
524 if (idx == 0 || tok == NULL)
525 break;
526 else
527 idx--;
528
529 tok = strtok_r(NULL, ";", &save_ptr);
530 } while (tok != NULL);
531
532 if (tok) {
533 ret = snprintf(value, len, "%s", tok);
534 } else {
535 ret = 0;
536 value[0] = '\0';
537 }
538
539 return ret;
540}
541
542
developer72fb0bb2023-01-11 09:46:29 +0800543#ifdef HAL_NETLINK_IMPL
544typedef struct {
545 int id;
546 struct nl_sock* socket;
547 struct nl_cb* cb;
548} Netlink;
549
550static int mac_addr_aton(unsigned char *mac_addr, char *arg)
551{
developerdaf24792023-06-06 11:40:04 +0800552 unsigned char mac_addr_int[6]={};
developer72fb0bb2023-01-11 09:46:29 +0800553 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);
554 mac_addr[0] = mac_addr_int[0];
555 mac_addr[1] = mac_addr_int[1];
556 mac_addr[2] = mac_addr_int[2];
557 mac_addr[3] = mac_addr_int[3];
558 mac_addr[4] = mac_addr_int[4];
559 mac_addr[5] = mac_addr_int[5];
560 return 0;
561}
562
563static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
564{
565 unsigned int mac_addr_int[6]={};
566 mac_addr_int[0] = arg[0];
567 mac_addr_int[1] = arg[1];
568 mac_addr_int[2] = arg[2];
569 mac_addr_int[3] = arg[3];
570 mac_addr_int[4] = arg[4];
571 mac_addr_int[5] = arg[5];
572 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]);
573 return;
574}
575
576static int ieee80211_frequency_to_channel(int freq)
577{
578 /* see 802.11-2007 17.3.8.3.2 and Annex J */
579 if (freq == 2484)
580 return 14;
581 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
582 else if (freq == 5935)
583 return 2;
584 else if (freq < 2484)
585 return (freq - 2407) / 5;
586 else if (freq >= 4910 && freq <= 4980)
587 return (freq - 4000) / 5;
588 else if (freq < 5950)
589 return (freq - 5000) / 5;
590 else if (freq <= 45000) /* DMG band lower limit */
591 /* see 802.11ax D6.1 27.3.23.2 */
592 return (freq - 5950) / 5;
593 else if (freq >= 58320 && freq <= 70200)
594 return (freq - 56160) / 2160;
595 else
596 return 0;
597}
598
599static int initSock80211(Netlink* nl) {
600 nl->socket = nl_socket_alloc();
601 if (!nl->socket) {
602 fprintf(stderr, "Failing to allocate the sock\n");
603 return -ENOMEM;
604 }
605
606 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
607
608 if (genl_connect(nl->socket)) {
609 fprintf(stderr, "Failed to connect\n");
610 nl_close(nl->socket);
611 nl_socket_free(nl->socket);
612 return -ENOLINK;
613 }
614
615 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
616 if (nl->id< 0) {
617 fprintf(stderr, "interface not found.\n");
618 nl_close(nl->socket);
619 nl_socket_free(nl->socket);
620 return -ENOENT;
621 }
622
623 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
624 if ((!nl->cb)) {
625 fprintf(stderr, "Failed to allocate netlink callback.\n");
626 nl_close(nl->socket);
627 nl_socket_free(nl->socket);
628 return ENOMEM;
629 }
630
631 return nl->id;
632}
633
634static int nlfree(Netlink *nl)
635{
636 nl_cb_put(nl->cb);
637 nl_close(nl->socket);
638 nl_socket_free(nl->socket);
639 return 0;
640}
641
642static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
643 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
644 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
645 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
646};
647
648static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
649};
650
651static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
652};
653
654typedef struct _wifi_channelStats_loc {
655 INT array_size;
656 INT ch_number;
657 BOOL ch_in_pool;
658 INT ch_noise;
659 BOOL ch_radar_noise;
660 INT ch_max_80211_rssi;
661 INT ch_non_80211_noise;
662 INT ch_utilization;
663 ULLONG ch_utilization_total;
664 ULLONG ch_utilization_busy;
665 ULLONG ch_utilization_busy_tx;
666 ULLONG ch_utilization_busy_rx;
667 ULLONG ch_utilization_busy_self;
668 ULLONG ch_utilization_busy_ext;
669} wifi_channelStats_t_loc;
670
671typedef struct wifi_device_info {
672 INT wifi_devIndex;
673 UCHAR wifi_devMacAddress[6];
674 CHAR wifi_devIPAddress[64];
675 BOOL wifi_devAssociatedDeviceAuthentiationState;
676 INT wifi_devSignalStrength;
677 INT wifi_devTxRate;
678 INT wifi_devRxRate;
679} wifi_device_info_t;
680
681#endif
682
683//For 5g Alias Interfaces
developer72fb0bb2023-01-11 09:46:29 +0800684static BOOL Radio_flag = TRUE;
685//wifi_setApBeaconRate(1, beaconRate);
686
687BOOL multiple_set = FALSE;
688
689struct params
690{
691 char * name;
692 char * value;
693};
694
695static int _syscmd(char *cmd, char *retBuf, int retBufSize)
696{
697 FILE *f;
698 char *ptr = retBuf;
699 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
700
701 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
702 if((f = popen(cmd, "r")) == NULL) {
703 fprintf(stderr,"\npopen %s error\n", cmd);
704 return RETURN_ERR;
705 }
706
707 while(!feof(f))
708 {
709 *ptr = 0;
710 if(bufSize>=128) {
711 bufbytes=128;
712 } else {
713 bufbytes=bufSize-1;
714 }
715
716 fgets(ptr,bufbytes,f);
717 readbytes=strlen(ptr);
718
719 if(!readbytes)
720 break;
721
722 bufSize-=readbytes;
723 ptr += readbytes;
724 }
725 cmd_ret = pclose(f);
726 retBuf[retBufSize-1]=0;
727 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
728
729 return cmd_ret >> 8;
730}
731
732INT radio_index_to_phy(int radioIndex)
733{
developer17038e62023-03-02 14:43:43 +0800734 /* TODO */
735 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800736}
737
738INT wifi_getMaxRadioNumber(INT *max_radio_num)
739{
740 char cmd[64] = {0};
741 char buf[4] = {0};
742
743 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
744
745 snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
746 _syscmd(cmd, buf, sizeof(buf));
747 *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10);
748
749 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
750
751 return RETURN_OK;
752}
753
developer17038e62023-03-02 14:43:43 +0800754wifi_band radio_index_to_band(int radioIndex)
755{
developer745f0bd2023-03-06 14:32:53 +0800756 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800757}
758
developer72fb0bb2023-01-11 09:46:29 +0800759wifi_band wifi_index_to_band(int apIndex)
760{
761 char cmd[128] = {0};
762 char buf[64] = {0};
763 int nl80211_band = 0;
764 int i = 0;
765 int phyIndex = 0;
766 int radioIndex = 0;
767 int max_radio_num = 0;
768 wifi_band band = band_invalid;
769
770 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
771
772 wifi_getMaxRadioNumber(&max_radio_num);
773 radioIndex = apIndex % max_radio_num;
774 phyIndex = radio_index_to_phy(radioIndex);
775 while(i < 10){
776 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
777 _syscmd(cmd, buf, sizeof(buf));
778 nl80211_band = strtol(buf, NULL, 10);
779 if (nl80211_band == 1)
780 band = band_2_4;
781 else if (nl80211_band == 2)
782 band = band_5;
783 else if (nl80211_band == 4) // band == 3 is 60GHz
784 band = band_6;
785
786 if(band != band_invalid)
787 break;
developer69b61b02023-03-07 17:17:44 +0800788
developer72fb0bb2023-01-11 09:46:29 +0800789 i++;
790 sleep(1);
791 }
792
793 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
794 return band;
795}
796
797static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
798{
developer7e4a2a62023-04-06 19:56:03 +0800799 char cmd[MAX_CMD_SIZE] = {0};
800 char buf[MAX_BUF_SIZE] = {0};
801 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +0800802
developer7e4a2a62023-04-06 19:56:03 +0800803 ret = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
804 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800805
developer7e4a2a62023-04-06 19:56:03 +0800806 if (ret < 0) {
807 printf("%s: snprintf error!", __func__);
808 return -1;
809 }
810
811 ret = _syscmd(cmd, buf, sizeof(buf));
812 if ((ret != 0) && (strlen(buf) == 0)) {
813 printf("%s: _syscmd error!", __func__);
814 return -1;
815 }
816
817 snprintf(output, output_size, "%s", buf);
818
819 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800820}
821
822static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
823{
developer7e4a2a62023-04-06 19:56:03 +0800824 char cmd[MAX_CMD_SIZE] = {0};
825 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +0800826
developer7e4a2a62023-04-06 19:56:03 +0800827 for (int i = 0; i < item_count; i++) {
developer72fb0bb2023-01-11 09:46:29 +0800828 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +0800829 if (strlen(buf) == 0) /*no such item, insert it*/
developera1255e42023-05-13 17:45:02 +0800830 snprintf(cmd, sizeof(cmd), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file);
developer7e4a2a62023-04-06 19:56:03 +0800831 else /*find the item, update it*/
developer72fb0bb2023-01-11 09:46:29 +0800832 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 +0800833
developer72fb0bb2023-01-11 09:46:29 +0800834 if(_syscmd(cmd, buf, sizeof(buf)))
835 return -1;
836 }
837
developera1255e42023-05-13 17:45:02 +0800838 return 0;
839}
developerfde01262023-05-22 15:15:24 +0800840
developera1255e42023-05-13 17:45:02 +0800841static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
842{
843 char cmd[MAX_CMD_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800844 int ret = 0;
developerfde01262023-05-22 15:15:24 +0800845 int len;
846
847 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
848 if (ret < 0) {
849 printf("%s: snprintf error!", __func__);
850 return -1;
851 }
852
853 ret = _syscmd(cmd, output, output_size);
854 if ((ret != 0) && (strlen(output) == 0)) {
855 printf("%s: _syscmd error!", __func__);
856 return -1;
857 }
developera1255e42023-05-13 17:45:02 +0800858
developerfde01262023-05-22 15:15:24 +0800859 len = strlen(output);
860 if ((len > 0) && (output[len - 1] == '\n')) {
861 output[len - 1] = '\0';
862 }
863
864 return 0;
865}
developera1255e42023-05-13 17:45:02 +0800866
developera1255e42023-05-13 17:45:02 +0800867static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
868{
developerfde01262023-05-22 15:15:24 +0800869 int ret;
developera1255e42023-05-13 17:45:02 +0800870 char cmd[MAX_CMD_SIZE] = {0};
871 char buf[MAX_BUF_SIZE] = {0};
872
873 for (int i = 0; i < item_count; i++) {
developerfde01262023-05-22 15:15:24 +0800874 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
875 if (ret < 0) {
876 printf("%s: snprintf error!", __func__);
877 return -1;
878 }
developera1255e42023-05-13 17:45:02 +0800879
880 if(_syscmd(cmd, buf, sizeof(buf)))
881 return -1;
882 }
883
884 return 0;
885}
886
developerfde01262023-05-22 15:15:24 +0800887static int wifi_l1ProfileRead(char *param, char *output, int output_size)
888{
developerfde01262023-05-22 15:15:24 +0800889 int ret;
890
891 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
892 if (!param || !output || (output_size <= 0)) {
893 fprintf(stderr, "%s: invalid parameters", __func__);
894 return RETURN_ERR;
895 }
896
897 ret = wifi_datfileRead(l1profile, param, output, output_size);
898 if (ret != 0) {
899 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, l1profile, ret);
900 return RETURN_ERR;
901 }
902
903 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
904 return RETURN_OK;
905}
906
907static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
908{
909 char option[64];
910 char card_profile_path[64];
911 int ret;
912
913 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
914
915 if (!param || !output || (output_size <= 0)) {
916 fprintf(stderr, "%s: invalid parameters", __func__);
917 return RETURN_ERR;
918 }
919
920 snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
921 ret = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
922 if (ret != 0) {
923 fprintf(stderr, "%s: wifi_l1ProfileRead %s failed, ret:%d", __func__, option, ret);
924 return RETURN_ERR;
925 }
926
927 ret = wifi_datfileRead(card_profile_path, param, output, output_size);
928 if (ret != 0) {
929 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, card_profile_path, ret);
930 return RETURN_ERR;
931 }
932
933 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
934 return RETURN_OK;
935}
936
937static int wifi_BandProfileRead(int card_idx,
938 int radio_idx,
939 char *param,
940 char *output,
941 int output_size,
942 char *default_value)
943{
944 char option[64];
945 char band_profile_path[64];
946 int ret;
947
948 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
949 if (!param || !output || (output_size <= 0)) {
950 fprintf(stderr, "%s: invalid parameters", __func__);
951 return RETURN_ERR;
952 }
953
954 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
955 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
956 if (ret != 0) {
developerdaf24792023-06-06 11:40:04 +0800957 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option, ret);
developerfde01262023-05-22 15:15:24 +0800958 return RETURN_ERR;
959 }
960
961 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
962 if (ret != 0) {
963 if (default_value) {
964 snprintf(output, output_size, "%s", default_value);
965 } else {
966 output[0] = '\0';
967 }
968 }
969
970 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
971 return RETURN_OK;
972}
973
developer72fb0bb2023-01-11 09:46:29 +0800974//For Getting Current Interface Name from corresponding hostapd configuration
975static int wifi_GetInterfaceName(int apIndex, char *interface_name)
976{
977 char config_file[128] = {0};
978
979 if (interface_name == NULL)
980 return RETURN_ERR;
981
982 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
983
984 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
985 wifi_hostapdRead(config_file, "interface", interface_name, 16);
986 if (strlen(interface_name) == 0)
987 return RETURN_ERR;
988
989 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
990 return RETURN_OK;
991}
992
developera1255e42023-05-13 17:45:02 +0800993static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
994{
995 char interface_name[IF_NAME_SIZE] = {0};
996 char cmd[MAX_BUF_SIZE]={'\0'};
997 char buf[MAX_CMD_SIZE]={'\0'};
998 UCHAR channel = 0;
999
1000 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1001 return RETURN_ERR;
1002 /*interface name to channel number*/
1003 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1004 _syscmd(cmd, buf, sizeof(buf));
1005 channel = atoi(buf);
1006 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
1007 /*count dev number with the same channel*/
1008 snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1009 _syscmd(cmd, buf, sizeof(buf));
1010 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1011 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1012 return RETURN_OK;
1013}
developer72fb0bb2023-01-11 09:46:29 +08001014
1015static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1016{
1017 char interface_name[16] = {0};
1018 if (multiple_set == TRUE)
1019 return RETURN_OK;
1020 char cmd[MAX_CMD_SIZE]="", output[32]="";
1021 FILE *fp;
1022 int i;
1023 //NOTE RELOAD should be done in ApplySSIDSettings
1024 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1025 return RETURN_ERR;
1026 for(i=0; i<item_count; i++, list++)
1027 {
developerf6a87542023-05-16 15:47:28 +08001028 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
developer72fb0bb2023-01-11 09:46:29 +08001029 if((fp = popen(cmd, "r"))==NULL)
1030 {
1031 perror("popen failed");
1032 return -1;
1033 }
1034 if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2))
1035 {
1036 pclose(fp);
1037 perror("fgets failed");
1038 return -1;
1039 }
1040 pclose(fp);
1041 }
1042 return 0;
1043}
1044
developer7e4a2a62023-04-06 19:56:03 +08001045static int wifi_quick_reload_ap(int apIndex)
1046{
1047 char interface_name[IF_NAME_SIZE] = {0};
1048 char cmd[MAX_CMD_SIZE] = {0};
1049 char buf[MAX_BUF_SIZE] = {0};
1050
1051 if (multiple_set == TRUE)
1052 return RETURN_OK;
1053
1054 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1055 return RETURN_ERR;
1056
1057 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1058 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1059 return RETURN_ERR;
1060
1061 return RETURN_OK;
1062}
1063
developer72fb0bb2023-01-11 09:46:29 +08001064static int wifi_reloadAp(int apIndex)
1065{
1066 char interface_name[16] = {0};
developer22e0c672023-06-07 15:25:37 +08001067 int res;
1068
developer72fb0bb2023-01-11 09:46:29 +08001069 if (multiple_set == TRUE)
1070 return RETURN_OK;
1071 char cmd[MAX_CMD_SIZE]="";
1072 char buf[MAX_BUF_SIZE]="";
1073
1074 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1075 return RETURN_ERR;
developer22e0c672023-06-07 15:25:37 +08001076 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1077 if (os_snprintf_error(sizeof(cmd), res)) {
1078 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1079 return RETURN_ERR;
1080 }
developer72fb0bb2023-01-11 09:46:29 +08001081 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1082 return RETURN_ERR;
1083
developer22e0c672023-06-07 15:25:37 +08001084 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
1085 if (os_snprintf_error(sizeof(cmd), res)) {
1086 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1087 return RETURN_ERR;
1088 }
developer72fb0bb2023-01-11 09:46:29 +08001089 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1090 return RETURN_ERR;
1091
developer22e0c672023-06-07 15:25:37 +08001092 res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
1093 if (os_snprintf_error(sizeof(cmd), res)) {
1094 wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
1095 return RETURN_ERR;
1096 }
developer72fb0bb2023-01-11 09:46:29 +08001097 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1098 return RETURN_ERR;
1099
1100 return RETURN_OK;
1101}
1102
1103INT File_Reading(CHAR *file, char *Value)
1104{
1105 FILE *fp = NULL;
1106 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1107 int count = 0;
1108
1109 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1110 fp = popen(file,"r");
1111 if(fp == NULL)
1112 return RETURN_ERR;
1113
1114 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1115 {
1116 for(count=0;buf[count]!='\n';count++)
1117 copy_buf[count]=buf[count];
1118 copy_buf[count]='\0';
1119 }
1120 strcpy(Value,copy_buf);
1121 pclose(fp);
1122 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1123
1124 return RETURN_OK;
1125}
1126
1127void wifi_RestartHostapd_2G()
1128{
1129 int Public2GApIndex = 4;
1130
1131 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1132 wifi_setApEnable(Public2GApIndex, FALSE);
1133 wifi_setApEnable(Public2GApIndex, TRUE);
1134 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1135}
1136
1137void wifi_RestartHostapd_5G()
1138{
1139 int Public5GApIndex = 5;
1140
1141 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1142 wifi_setApEnable(Public5GApIndex, FALSE);
1143 wifi_setApEnable(Public5GApIndex, TRUE);
1144 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1145}
1146
1147void wifi_RestartPrivateWifi_2G()
1148{
1149 int PrivateApIndex = 0;
1150
1151 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1152 wifi_setApEnable(PrivateApIndex, FALSE);
1153 wifi_setApEnable(PrivateApIndex, TRUE);
1154 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1155}
1156
1157void wifi_RestartPrivateWifi_5G()
1158{
1159 int Private5GApIndex = 1;
1160
1161 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1162 wifi_setApEnable(Private5GApIndex, FALSE);
1163 wifi_setApEnable(Private5GApIndex, TRUE);
1164 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1165}
1166
1167static int writeBandWidth(int radioIndex,char *bw_value)
1168{
1169 char buf[MAX_BUF_SIZE];
1170 char cmd[MAX_CMD_SIZE];
1171
1172 snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1173 if(_syscmd(cmd, buf, sizeof(buf)))
1174 {
1175 snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1176 _syscmd(cmd, buf, sizeof(buf));
1177 return RETURN_OK;
1178 }
1179
1180 sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1181 _syscmd(cmd,buf,sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001182 return RETURN_OK;
1183}
1184
1185// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1186INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1187{
1188 struct params params={'\0'};
1189 char config_file[MAX_BUF_SIZE] = {0};
1190 char buf[MAX_BUF_SIZE] = {'\0'};
1191
1192 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1193 // Copy the numeric value
1194 if (strlen (beaconRate) >= 5) {
1195 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1196 buf[strlen(beaconRate) - 4] = '\0';
1197 } else if (strlen(beaconRate) > 0)
1198 strcpy(buf, beaconRate);
1199 else
1200 return RETURN_ERR;
1201
1202 params.name = "beacon_rate";
1203 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1204 if (strncmp(buf, "5.5", 3) == 0) {
1205 snprintf(buf, sizeof(buf), "55");
1206 params.value = buf;
1207 } else {
1208 strcat(buf, "0");
1209 params.value = buf;
1210 }
1211
1212 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1213 wifi_hostapdWrite(config_file, &params, 1);
1214 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1215 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1216
1217 return RETURN_OK;
1218}
1219
1220INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1221{
1222 char config_file[128] = {'\0'};
developer5a333cf2023-06-06 18:18:50 +08001223 char temp_output[MAX_BUF_SIZE] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08001224 char buf[128] = {'\0'};
1225 char cmd[128] = {'\0'};
1226 int rate = 0;
1227 int phyId = 0;
1228
1229 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1230 if (NULL == beaconRate)
1231 return RETURN_ERR;
1232
1233 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1234 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1235 phyId = radio_index_to_phy(radioIndex);
1236 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1237 if(strlen(buf) > 0) {
1238 if (strncmp(buf, "55", 2) == 0)
1239 snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
1240 else {
1241 rate = strtol(buf, NULL, 10)/10;
1242 snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
1243 }
1244 } else {
1245 // config not set, so we would use lowest rate as default
1246 sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1247 _syscmd(cmd, buf, sizeof(buf));
1248 snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
1249 }
developerdaf24792023-06-06 11:40:04 +08001250 strncpy(beaconRate, temp_output, strlen(temp_output));
developer72fb0bb2023-01-11 09:46:29 +08001251 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1252
1253 return RETURN_OK;
1254}
1255
1256INT wifi_setLED(INT radioIndex, BOOL enable)
1257{
1258 return 0;
1259}
1260INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
1261{
1262 return RETURN_OK;
1263}
1264/**********************************************************************************
1265 *
developer69b61b02023-03-07 17:17:44 +08001266 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001267 *
1268**********************************************************************************/
1269//---------------------------------------------------------------------------------------------------
1270//Wifi system api
1271//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 +08001272INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001273{
1274 if(!output_string)
1275 return RETURN_ERR;
1276 snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1277
1278 return RETURN_OK;
1279}
1280
1281
1282/* wifi_factoryReset() function */
1283/**
developer69b61b02023-03-07 17:17:44 +08001284* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001285* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1286*
1287* @param None
1288*
1289* @return The status of the operation.
1290* @retval RETURN_OK if successful.
1291* @retval RETURN_ERR if any error is detected
1292*
1293* @execution Synchronous
1294* @sideeffect None
1295*
1296* @note This function must not suspend and must not invoke any blocking system
1297* calls. It should probably just send a message to a driver event handler task.
1298*
1299*/
1300INT wifi_factoryReset()
1301{
developer47cc27a2023-05-17 23:09:58 +08001302 char cmd[MAX_CMD_SIZE] = {0};
1303 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08001304
developer47cc27a2023-05-17 23:09:58 +08001305 /*delete running hostapd conf files*/
1306 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
1307 snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1308 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001309
developer47cc27a2023-05-17 23:09:58 +08001310 wifi_PrepareDefaultHostapdConfigs();
1311 wifi_psk_file_reset();
1312
1313 memset(cmd, 0, MAX_CMD_SIZE);
1314 memset(buf, 0, MAX_BUF_SIZE);
1315
1316 snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1317 _syscmd(cmd, buf, sizeof(buf));
1318
1319 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001320}
1321
1322/* wifi_factoryResetRadios() function */
1323/**
1324* @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.
1325*
1326* @param None
1327* @return The status of the operation
1328* @retval RETURN_OK if successful
1329* @retval RETURN_ERR if any error is detected
1330*
1331* @execution Synchronous
1332*
1333* @sideeffect None
1334*
1335* @note This function must not suspend and must not invoke any blocking system
1336* calls. It should probably just send a message to a driver event handler task.
1337*
1338*/
1339INT wifi_factoryResetRadios()
1340{
1341 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1342 return RETURN_OK;
1343
1344 return RETURN_ERR;
1345}
1346
developerfead3972023-05-25 20:15:02 +08001347ULONG get_radio_reset_cnt(int radioIndex)
1348{
1349 char cmd[MAX_CMD_SIZE] = {0};
1350 char buf[MAX_BUF_SIZE] = {0};
1351 ULONG reset_count = 0;
1352
1353 snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
1354 RADIO_RESET_FILE, radioIndex);
1355 _syscmd(cmd, buf, sizeof(buf));
1356
1357 if (strlen(buf) == 0)
1358 return 0;
1359 else {
1360 reset_count = atol(buf);
1361 return reset_count;
1362 }
1363}
1364void update_radio_reset_cnt(int radioIndex)
1365{
1366 char cmd[MAX_CMD_SIZE] = {0};
1367 char buf[MAX_BUF_SIZE] = {0};
1368 ULONG reset_count = 0;
1369
1370 snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
1371 RADIO_RESET_FILE, radioIndex);
1372 _syscmd(cmd, buf, sizeof(buf));
1373
1374 if (strlen(buf) == 0)
1375 snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
1376 else {
1377 reset_count = atol(buf);
1378 reset_count++;
1379 snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
1380 }
1381 _syscmd(cmd, buf, sizeof(buf));
1382}
developer72fb0bb2023-01-11 09:46:29 +08001383
1384/* wifi_factoryResetRadio() function */
1385/**
1386* @description Restore selected radio parameters without touching access point parameters
1387*
1388* @param radioIndex - Index of Wi-Fi Radio channel
1389*
1390* @return The status of the operation.
1391* @retval RETURN_OK if successful.
1392* @retval RETURN_ERR if any error is detected
1393*
1394* @execution Synchronous.
1395* @sideeffect None.
1396*
1397* @note This function must not suspend and must not invoke any blocking system
1398* calls. It should probably just send a message to a driver event handler task.
1399*
1400*/
1401INT wifi_factoryResetRadio(int radioIndex) //RDKB
1402{
developer47cc27a2023-05-17 23:09:58 +08001403 char cmd[MAX_CMD_SIZE] = {0};
1404 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08001405
developer47cc27a2023-05-17 23:09:58 +08001406 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001407
developerb2977562023-05-24 17:54:12 +08001408 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001409
developerb2977562023-05-24 17:54:12 +08001410 /*reset gi setting*/
1411 snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001412 _syscmd(cmd, buf, sizeof(buf));
1413
developerb2977562023-05-24 17:54:12 +08001414 /*TBD: check mbss issue*/
1415 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08001416 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08001417
developer47cc27a2023-05-17 23:09:58 +08001418 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1419 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001420}
1421
1422/* wifi_initRadio() function */
1423/**
1424* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001425* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001426* different hardware implementations may have different initilization requirements.
1427* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1428*
1429* @return The status of the operation.
1430* @retval RETURN_OK if successful.
1431* @retval RETURN_ERR if any error is detected
1432*
1433* @execution Synchronous.
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_initRadio(INT radioIndex)
1441{
1442 //TODO: Initializes the wifi subsystem (for specified radio)
1443 return RETURN_OK;
1444}
1445void macfilter_init()
1446{
1447 char count[4]={'\0'};
1448 char buf[253]={'\0'};
1449 char tmp[19]={'\0'};
1450 int dev_count,block,mac_entry=0;
1451 char res[4]={'\0'};
1452 char acl_file_path[64] = {'\0'};
1453 FILE *fp = NULL;
1454 int index=0;
1455 char iface[10]={'\0'};
1456 char config_file[MAX_BUF_SIZE] = {0};
1457
1458
1459 sprintf(acl_file_path,"/tmp/mac_filter.sh");
1460
1461 fp=fopen(acl_file_path,"w+");
1462 if (fp == NULL) {
1463 fprintf(stderr, "%s: failed to open file %s.\n", __func__, acl_file_path);
developer17038e62023-03-02 14:43:43 +08001464 return;
developer72fb0bb2023-01-11 09:46:29 +08001465 }
1466 sprintf(buf,"#!/bin/sh \n");
1467 fprintf(fp,"%s\n",buf);
1468
1469 system("chmod 0777 /tmp/mac_filter.sh");
1470
1471 for(index=0;index<=1;index++)
1472 {
1473 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index);
1474 wifi_hostapdRead(config_file, "interface", iface, sizeof(iface));
1475 sprintf(buf,"syscfg get %dcountfilter",index);
1476 _syscmd(buf,count,sizeof(count));
1477 mac_entry=atoi(count);
1478
1479 sprintf(buf,"syscfg get %dblockall",index);
1480 _syscmd(buf,res,sizeof(res));
1481 block = atoi(res);
1482
1483 //Allow only those macs mentioned in ACL
1484 if(block==1)
1485 {
1486 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1487 fprintf(fp,"%s\n",buf);
1488 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1489 {
1490 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1491 _syscmd(buf,tmp,sizeof(tmp));
1492 fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp);
1493 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp);
1494 fprintf(fp,"%s\n",buf);
1495 }
1496 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp);
1497 fprintf(fp,"%s\n",buf);
1498 }
1499
1500 //Block all the macs mentioned in ACL
1501 else if(block==2)
1502 {
1503 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1504 fprintf(fp,"%s\n",buf);
1505
1506 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1507 {
1508 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1509 _syscmd(buf,tmp,sizeof(tmp));
1510 fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp);
1511 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp);
1512 fprintf(fp,"%s\n",buf);
1513 }
1514 }
1515 }
1516 fclose(fp);
1517}
1518
developer17038e62023-03-02 14:43:43 +08001519
1520static void
1521wifi_ParseProfile(void)
1522{
1523 int i;
1524 int max_radio_num = 0;
1525 int card_idx;
1526 int band_idx;
1527 int phy_idx = 0;
developer745f0bd2023-03-06 14:32:53 +08001528 int wireless_mode = 0;
developer17038e62023-03-02 14:43:43 +08001529 char buf[MAX_BUF_SIZE] = {0};
1530 char chip_name[12];
1531 char card_profile[MAX_BUF_SIZE] = {0};
1532 char band_profile[MAX_BUF_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001533
1534 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1535
1536 memset(main_prefix, 0, sizeof(main_prefix));
1537 memset(ext_prefix, 0, sizeof(ext_prefix));
1538 memset(default_ssid, 0, sizeof(default_ssid));
developer745f0bd2023-03-06 14:32:53 +08001539 for (i = 0; i < MAX_NUM_RADIOS; i++)
1540 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001541
1542 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1543 /* LOG */
1544 return;
1545 }
1546
1547 for (card_idx = 0; card_idx < 3; card_idx++) {
1548 snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1549 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1550 break;
1551 }
1552 snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1553 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1554 break;
1555 }
1556 for (band_idx = 0; band_idx < 3; band_idx++) {
1557 snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1558 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1559 /* LOG */
1560 break;
1561 }
1562
1563 snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1564 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1565 /* LOG */
1566 }
1567
1568 snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1569 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1570 /* LOG */
1571 }
1572
1573 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1574 /* LOG */
1575 }
developer745f0bd2023-03-06 14:32:53 +08001576 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1577 /* LOG */
1578 }
1579
1580 wireless_mode = atoi(buf);
1581 switch (wireless_mode) {
1582 case 22:
1583 case 16:
1584 case 6:
1585 case 4:
1586 case 1:
1587 radio_band[phy_idx] = band_2_4;
1588 break;
1589 case 23:
1590 case 17:
1591 case 14:
1592 case 11:
1593 case 2:
1594 radio_band[phy_idx] = band_5;
1595 break;
1596 case 24:
1597 case 18:
1598 radio_band[phy_idx] = band_6;
1599 break;
1600 }
developer17038e62023-03-02 14:43:43 +08001601 phy_idx++;
1602 }
1603 }
1604
1605 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1606}
1607
1608static void
1609wifi_PrepareDefaultHostapdConfigs(void)
1610{
developer0132ed92023-03-21 13:48:53 +08001611 int radio_idx;
1612 int bss_idx;
1613 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001614 char buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001615 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer0132ed92023-03-21 13:48:53 +08001616 char ssid[MAX_BUF_SIZE] = {0};
1617 char interface[32] = {0};
1618 char ret_buf[MAX_BUF_SIZE] = {0};
1619 char psk_file[64] = {0};
1620 struct params params[3];
developer17038e62023-03-02 14:43:43 +08001621
developer0132ed92023-03-21 13:48:53 +08001622 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1623 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001624
developer0132ed92023-03-21 13:48:53 +08001625 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001626 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001627
developer47cc27a2023-05-17 23:09:58 +08001628 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
developere740c2a2023-05-23 18:34:32 +08001629 snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
developer47cc27a2023-05-17 23:09:58 +08001630 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001631
developer47cc27a2023-05-17 23:09:58 +08001632 if (radio_idx == band_2_4) {
1633 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1634 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1635 } else if (radio_idx == band_5) {
1636 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1637 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1638 } else if (radio_idx == band_6) {
1639 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1640 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1641 }
developer17038e62023-03-02 14:43:43 +08001642
developer47cc27a2023-05-17 23:09:58 +08001643 /* fix wpa_psk_file path */
1644 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
developer17038e62023-03-02 14:43:43 +08001645
developer47cc27a2023-05-17 23:09:58 +08001646 params[0].name = "ssid";
1647 params[0].value = ssid;
1648 params[1].name = "interface";
1649 params[1].value = interface;
1650 params[2].name = "wpa_psk_file";
1651 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001652
developer47cc27a2023-05-17 23:09:58 +08001653 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001654 }
1655 }
1656 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001657}
1658
1659static void
developer17038e62023-03-02 14:43:43 +08001660wifi_BringDownInterfacesForRadio(int radio_idx)
1661{
developer17038e62023-03-02 14:43:43 +08001662 char cmd[MAX_BUF_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001663 char ret_buf[MAX_BUF_SIZE]={'\0'};
1664
1665 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001666
developer8a3bbbf2023-03-15 17:47:23 +08001667 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1668 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1669
developer17038e62023-03-02 14:43:43 +08001670 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1671}
1672
1673
1674static void
1675wifi_BringDownInterfaces(void)
1676{
1677 int radio_idx;
developer17038e62023-03-02 14:43:43 +08001678 int band_idx;
developer17038e62023-03-02 14:43:43 +08001679
1680 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1681 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1682 band_idx = radio_index_to_band(radio_idx);
1683 if (band_idx < 0) {
1684 break;
1685 }
1686 wifi_BringDownInterfacesForRadio(radio_idx);
1687 }
1688 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1689}
1690
developerb2977562023-05-24 17:54:12 +08001691static void wifi_dat_file_reset_by_radio(char radio_idx)
1692{
developerb149d9d2023-06-06 16:14:22 +08001693 char cmd[MAX_CMD_SIZE * 2] = {0};
developerb2977562023-05-24 17:54:12 +08001694 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001695 char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
1696 char dat_file[MAX_SUB_CMD_SIZE]= {0};
developerb2977562023-05-24 17:54:12 +08001697
1698 snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1699 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
developerb149d9d2023-06-06 16:14:22 +08001700 snprintf(cmd, (MAX_CMD_SIZE * 2), "cp -rf %s %s", rom_dat_file, dat_file);
developerb2977562023-05-24 17:54:12 +08001701 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1702
1703}
1704
developer47cc27a2023-05-17 23:09:58 +08001705static void wifi_psk_file_reset()
1706{
1707 char cmd[MAX_CMD_SIZE] = {0};
1708 char ret_buf[MAX_BUF_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08001709 char psk_file[MAX_SUB_CMD_SIZE]= {0};
developer47cc27a2023-05-17 23:09:58 +08001710 char vap_idx = 0;
1711
1712 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
1713 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1714
1715 if (access(psk_file, F_OK) != 0) {
1716 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1717 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1718 } else {
1719 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1720 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1721 }
1722 }
developerb2977562023-05-24 17:54:12 +08001723}
1724
developer8a3bbbf2023-03-15 17:47:23 +08001725static void wifi_vap_status_reset()
1726{
1727 char cmd[MAX_CMD_SIZE] = {0};
1728 char ret_buf[MAX_BUF_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08001729 int radio_idx = 0;
developer8a3bbbf2023-03-15 17:47:23 +08001730 char bss_idx = 0;
developer8666b312023-03-24 14:05:31 +08001731
developer8a3bbbf2023-03-15 17:47:23 +08001732 if (access(VAP_STATUS_FILE, F_OK) != 0) {
1733 snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
1734 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1735 } else {
1736 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
1737 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1738 }
1739
1740 memset(cmd, 0, MAX_CMD_SIZE);
1741 memset(ret_buf, 0, MAX_BUF_SIZE);
1742
1743 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
1744 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
1745 snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
1746 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1747 }
1748
developerfead3972023-05-25 20:15:02 +08001749}
1750
1751static void wifi_radio_reset_count_reset()
1752{
1753 char cmd[MAX_CMD_SIZE] = {0};
1754 char ret_buf[MAX_BUF_SIZE] = {0};
1755
1756 if (access(VAP_STATUS_FILE, F_OK) != 0) {
1757 snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE);
1758 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1759 } else {
1760 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE);
1761 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1762 }
developer8a3bbbf2023-03-15 17:47:23 +08001763}
developer17038e62023-03-02 14:43:43 +08001764
developer72fb0bb2023-01-11 09:46:29 +08001765// Initializes the wifi subsystem (all radios)
1766INT wifi_init() //RDKB
1767{
developer96b38512023-02-22 11:17:45 +08001768 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developercc9a4f32023-05-30 17:40:02 +08001769 static int CallOnce = 1;
developer96b38512023-02-22 11:17:45 +08001770 //Not intitializing macfilter for Turris-Omnia Platform for now
1771 //macfilter_init();
developercc9a4f32023-05-30 17:40:02 +08001772 if (CallOnce) {
1773 wifi_ParseProfile();
1774 wifi_PrepareDefaultHostapdConfigs();
1775 wifi_psk_file_reset();
1776 //system("/usr/sbin/iw reg set US");
1777 system("systemctl start hostapd.service");
1778 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08001779
developercc9a4f32023-05-30 17:40:02 +08001780 wifi_vap_status_reset();
1781 wifi_radio_reset_count_reset();
1782 CallOnce = 0;
1783 }
developer96b38512023-02-22 11:17:45 +08001784
1785 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001786
1787 return RETURN_OK;
1788}
1789
1790/* wifi_reset() function */
1791/**
1792* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08001793* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08001794* different hardware implementations may have different requirements.
1795* Parameters : None
1796*
1797* @return The status of the operation.
1798* @retval RETURN_OK if successful.
1799* @retval RETURN_ERR if any error is detected
1800*
1801* @execution Synchronous.
1802* @sideeffect None.
1803*
1804* @note This function must not suspend and must not invoke any blocking system
1805* calls. It should probably just send a message to a driver event handler task.
1806*
1807*/
1808INT wifi_reset()
1809{
developer17038e62023-03-02 14:43:43 +08001810
1811 wifi_BringDownInterfaces();
1812 sleep(2);
1813
developer96b38512023-02-22 11:17:45 +08001814 //TODO: resets the wifi subsystem, deletes all APs
1815 system("systemctl stop hostapd.service");
1816 sleep(2);
developer17038e62023-03-02 14:43:43 +08001817
developer96b38512023-02-22 11:17:45 +08001818 system("systemctl start hostapd.service");
1819 sleep(5);
developer17038e62023-03-02 14:43:43 +08001820
1821 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08001822 wifi_psk_file_reset();
developer17038e62023-03-02 14:43:43 +08001823 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08001824
1825 wifi_vap_status_reset();
1826
developer72fb0bb2023-01-11 09:46:29 +08001827 return RETURN_OK;
1828}
1829
1830/* wifi_down() function */
1831/**
1832* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08001833* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08001834* different hardware implementations may have different requirements.
1835*
1836* @param None
1837*
1838* @return The status of the operation
1839* @retval RETURN_OK if successful
1840* @retval RETURN_ERR if any error is detected
1841*
1842* @execution Synchronous
1843* @sideeffect None
1844*
1845* @note This function must not suspend and must not invoke any blocking system
1846* calls. It should probably just send a message to a driver event handler task.
1847*
1848*/
1849INT wifi_down()
1850{
developer96b38512023-02-22 11:17:45 +08001851 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
developerb2977562023-05-24 17:54:12 +08001852 int max_num_radios = 0;
1853 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08001854
developerb2977562023-05-24 17:54:12 +08001855 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
1856 wifi_setRadioEnable(radioIndex, FALSE);
1857
developer72fb0bb2023-01-11 09:46:29 +08001858 return RETURN_OK;
1859}
1860
1861
1862/* wifi_createInitialConfigFiles() function */
1863/**
1864* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08001865* and content of these files are implementation dependent. This function call is
1866* used to trigger this task if necessary. Some implementations may not need this
1867* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08001868* do nothing and return RETURN_OK.
1869*
1870* @param None
1871*
1872* @return The status of the operation
1873* @retval RETURN_OK if successful
1874* @retval RETURN_ERR if any error is detected
1875*
1876* @execution Synchronous
1877* @sideeffect None
1878*
1879* @note This function must not suspend and must not invoke any blocking system
1880* calls. It should probably just send a message to a driver event handler task.
1881*
1882*/
1883INT wifi_createInitialConfigFiles()
1884{
1885 //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)
1886 return RETURN_OK;
1887}
1888
developer7e4a2a62023-04-06 19:56:03 +08001889/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08001890INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
1891{
developerfde01262023-05-22 15:15:24 +08001892 int ret;
developer72fb0bb2023-01-11 09:46:29 +08001893
developerfde01262023-05-22 15:15:24 +08001894 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08001895
developerfde01262023-05-22 15:15:24 +08001896 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
1897 if (ret != 0) {
1898 fprintf(stderr, "%s: wifi_BandProfileRead CountryCode failed\n", __func__);
1899 return RETURN_ERR;
1900 }
developer7e4a2a62023-04-06 19:56:03 +08001901
developerfde01262023-05-22 15:15:24 +08001902 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08001903
developerfde01262023-05-22 15:15:24 +08001904 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001905}
1906
1907INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
1908{
developer7e4a2a62023-04-06 19:56:03 +08001909 /*Set wifi config. Wait for wifi reset to apply*/
developer7e4a2a62023-04-06 19:56:03 +08001910 struct params params;
1911 char config_file[MAX_BUF_SIZE] = {0};
1912 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08001913
developer7e4a2a62023-04-06 19:56:03 +08001914 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001915
developer7e4a2a62023-04-06 19:56:03 +08001916 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
1917 printf("%s: input para error!!!\n", __func__);
1918 return RETURN_ERR;
1919 }
developer72fb0bb2023-01-11 09:46:29 +08001920
developerc79e9172023-06-06 19:48:03 +08001921 if (!strlen(CountryCode)) {
1922 memcpy(CountryCode, "US", strlen("US")); /*default set the code to US*/
1923 CountryCode[2] = '\0';
1924 }
developer72fb0bb2023-01-11 09:46:29 +08001925
developer7e4a2a62023-04-06 19:56:03 +08001926 params.name = "country_code";
1927 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08001928
developer7e4a2a62023-04-06 19:56:03 +08001929 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1930 ret = wifi_hostapdWrite(config_file, &params, 1);
1931
1932 if (ret) {
1933 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
1934 __func__, ret);
1935 }
1936
1937 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1938
1939 if (ret) {
1940 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
1941 __func__, ret);
1942 }
1943
1944 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1945
1946 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001947}
1948
1949INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
1950{
1951 char interface_name[16] = {0};
1952 char channel_util_file[64] = {0};
1953 char cmd[128] = {0};
1954 char buf[128] = {0};
developer2f79c922023-06-02 17:33:42 +08001955 char *line = NULL;
developer72fb0bb2023-01-11 09:46:29 +08001956 char *param = NULL, *value = NULL;
1957 int read = 0;
1958 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
1959 unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
1960 size_t len = 0;
1961 FILE *f = NULL;
1962
1963 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1964
1965 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
1966 return RETURN_ERR;
1967 snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
1968 _syscmd(cmd, buf, sizeof(buf));
1969 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
1970
1971 memset(cmd, 0, sizeof(cmd));
1972 memset(buf, 0, sizeof(buf));
1973 snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
1974 if ((f = popen(cmd, "r")) == NULL) {
1975 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
1976 return RETURN_ERR;
1977 }
1978
1979 read = getline(&line, &len, f);
1980 while (read != -1) {
1981 param = strtok(line, ":\t");
1982 value = strtok(NULL, " ");
1983 if(strstr(param, "frequency") != NULL) {
1984 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
1985 }
1986 if(strstr(param, "noise") != NULL) {
1987 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
1988 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
1989 }
1990 if(strstr(param, "channel active time") != NULL) {
1991 ActiveTime = strtol(value, NULL, 10);
1992 }
1993 if(strstr(param, "channel busy time") != NULL) {
1994 BusyTime = strtol(value, NULL, 10);
1995 }
1996 if(strstr(param, "channel transmit time") != NULL) {
1997 TransmitTime = strtol(value, NULL, 10);
1998 }
1999 read = getline(&line, &len, f);
2000 }
2001 pclose(f);
2002
2003 // The file should store the last active, busy and transmit time
2004 snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2005 f = fopen(channel_util_file, "r");
2006 if (f != NULL) {
2007 read = getline(&line, &len, f);
2008 preActiveTime = strtol(line, NULL, 10);
2009 read = getline(&line, &len, f);
2010 preBusyTime = strtol(line, NULL, 10);
2011 read = getline(&line, &len, f);
2012 preTransmitTime = strtol(line, NULL, 10);
2013 fclose(f);
2014 }
2015
2016 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2017 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
2018
2019 f = fopen(channel_util_file, "w");
2020 if (f != NULL) {
2021 fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime);
2022 fclose(f);
2023 }
2024 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2025 return RETURN_OK;
2026}
2027
2028/**********************************************************************************
2029 *
2030 * Wifi radio level function prototypes
2031 *
2032**********************************************************************************/
2033
2034//Get the total number of radios in this wifi subsystem
2035INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2036{
2037 if (NULL == output)
2038 return RETURN_ERR;
2039 *output = MAX_NUM_RADIOS;
2040
2041 return RETURN_OK;
2042}
2043
developer69b61b02023-03-07 17:17:44 +08002044//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002045INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2046{
2047 if (NULL == output)
2048 return RETURN_ERR;
2049 *output = MAX_APS;
2050
2051 return RETURN_OK;
2052}
2053
2054//Get the Radio enable config parameter
2055INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
2056{
developer56fbedb2023-05-30 16:47:05 +08002057 char interface_name[16] = {0};
2058 char buf[128] = {0}, cmd[128] = {0};
2059 int apIndex;
2060 int max_radio_num = 0;
developer3a85ab82023-05-25 11:59:38 +08002061
developer56fbedb2023-05-30 16:47:05 +08002062 if (NULL == output_bool)
2063 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002064
developer56fbedb2023-05-30 16:47:05 +08002065 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08002066
developer56fbedb2023-05-30 16:47:05 +08002067 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002068
developer56fbedb2023-05-30 16:47:05 +08002069 if (radioIndex >= max_radio_num)
2070 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002071
developer56fbedb2023-05-30 16:47:05 +08002072 /* loop all interface in radio, if any is enable, reture true, else return false */
2073 for(apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num)
2074 {
2075 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2076 continue;
2077 memset(cmd, 0, sizeof(cmd));
2078 sprintf(cmd, "ifconfig %s 2> /dev/null | grep UP", interface_name);
2079 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? FALSE : TRUE;
2080 if (*output_bool == TRUE)
2081 break;
2082 }
2083
2084 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002085}
2086
developere82c0ca2023-05-10 16:25:35 +08002087typedef long time_t;
2088static time_t radio_up_time[MAX_NUM_RADIOS];
2089
developer72fb0bb2023-01-11 09:46:29 +08002090INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2091{
2092 char interface_name[16] = {0};
2093 char cmd[MAX_CMD_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08002094 char buf[MAX_BUF_SIZE] = {0};
developer2f79c922023-06-02 17:33:42 +08002095 int apIndex;
developer69b61b02023-03-07 17:17:44 +08002096 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +08002097 int phyId = 0;
2098
2099 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2100
2101 phyId = radio_index_to_phy(radioIndex);
2102
2103 wifi_getMaxRadioNumber(&max_radio_num);
2104
developer8a3bbbf2023-03-15 17:47:23 +08002105 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002106
2107 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2108 return RETURN_ERR;
2109
2110 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002111 _syscmd(cmd, buf, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +08002112 memset(cmd, 0, sizeof(cmd));
2113 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
2114 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002115 if(strncmp(buf, "OK", 2))
2116 fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002117 } else {
developere82c0ca2023-05-10 16:25:35 +08002118 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developer72fb0bb2023-01-11 09:46:29 +08002119 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2120 return RETURN_ERR;
2121
developer8a3bbbf2023-03-15 17:47:23 +08002122 memset(cmd, 0, MAX_CMD_SIZE);
2123 memset(buf, 0, MAX_BUF_SIZE);
2124
developer72fb0bb2023-01-11 09:46:29 +08002125 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2126 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002127
2128 if(*buf == '1') {
developer56fbedb2023-05-30 16:47:05 +08002129 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
2130 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002131
2132 memset(cmd, 0, MAX_CMD_SIZE);
2133 memset(buf, 0, MAX_BUF_SIZE);
2134
developer72fb0bb2023-01-11 09:46:29 +08002135 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
2136 phyId, apIndex);
2137 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002138
developer72fb0bb2023-01-11 09:46:29 +08002139 }
2140 }
developere82c0ca2023-05-10 16:25:35 +08002141 time(&radio_up_time[radioIndex]);
developer72fb0bb2023-01-11 09:46:29 +08002142 }
2143
2144 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2145 return RETURN_OK;
2146}
2147
2148//Get the Radio enable status
2149INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2150{
2151 if (NULL == output_bool)
2152 return RETURN_ERR;
2153
2154 return wifi_getRadioEnable(radioIndex, output_bool);
2155}
2156
2157//Get the Radio Interface name from platform, eg "wlan0"
2158INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2159{
2160 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2161 return RETURN_ERR;
2162 return wifi_GetInterfaceName(radioIndex, output_string);
2163}
2164
2165//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2166//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.
2167INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2168{
2169 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2170 // For max bit rate, we should always choose the best MCS
2171 char mode[64] = {0};
2172 char channel_bandwidth_str[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002173 UINT mode_map = 0;
2174 UINT num_subcarrier = 0;
2175 UINT code_bits = 0;
2176 float code_rate = 0; // use max code rate
2177 int NSS = 0;
2178 UINT Symbol_duration = 0;
developer69b61b02023-03-07 17:17:44 +08002179 UINT GI_duration = 0;
developer72fb0bb2023-01-11 09:46:29 +08002180 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2181 BOOL enable = FALSE;
2182 float bit_rate = 0;
developera1255e42023-05-13 17:45:02 +08002183 int ant_bitmap = 0;
developer72fb0bb2023-01-11 09:46:29 +08002184
2185 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2186 if (NULL == output_string)
2187 return RETURN_ERR;
2188
2189 wifi_getRadioEnable(radioIndex, &enable);
2190 if (enable == FALSE) {
2191 snprintf(output_string, 64, "0 Mb/s");
2192 return RETURN_OK;
2193 }
2194
2195 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
2196 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
2197 return RETURN_ERR;
2198 }
2199
2200 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
2201 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
2202 return RETURN_ERR;
2203 }
2204
2205 if (gi == wifi_guard_interval_3200)
2206 GI_duration = 32;
2207 else if (gi == wifi_guard_interval_1600)
2208 GI_duration = 16;
2209 else if (gi == wifi_guard_interval_800)
2210 GI_duration = 8;
2211 else // auto, 400
2212 GI_duration = 4;
2213
2214 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
2215 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
2216 return RETURN_ERR;
2217 }
2218
2219 if (strstr(channel_bandwidth_str, "80+80") != NULL)
2220 strcpy(channel_bandwidth_str, "160");
2221
2222 if (mode_map & WIFI_MODE_AX) {
2223 if (strstr(channel_bandwidth_str, "160") != NULL)
2224 num_subcarrier = 1960;
2225 else if (strstr(channel_bandwidth_str, "80") != NULL)
2226 num_subcarrier = 980;
2227 else if (strstr(channel_bandwidth_str, "40") != NULL)
2228 num_subcarrier = 468;
2229 else if (strstr(channel_bandwidth_str, "20") != NULL)
2230 num_subcarrier = 234;
2231 code_bits = 10;
2232 code_rate = (float)5/6;
2233 Symbol_duration = 128;
developera1255e42023-05-13 17:45:02 +08002234 GI_duration = 8;/*HE no GI 400ns*/
developer72fb0bb2023-01-11 09:46:29 +08002235 } else if (mode_map & WIFI_MODE_AC) {
2236 if (strstr(channel_bandwidth_str, "160") != NULL)
2237 num_subcarrier = 468;
2238 else if (strstr(channel_bandwidth_str, "80") != NULL)
2239 num_subcarrier = 234;
2240 else if (strstr(channel_bandwidth_str, "40") != NULL)
2241 num_subcarrier = 108;
2242 else if (strstr(channel_bandwidth_str, "20") != NULL)
2243 num_subcarrier = 52;
2244 code_bits = 8;
2245 code_rate = (float)5/6;
2246 Symbol_duration = 32;
2247 } else if (mode_map & WIFI_MODE_N) {
2248 if (strstr(channel_bandwidth_str, "160") != NULL)
2249 num_subcarrier = 468;
2250 else if (strstr(channel_bandwidth_str, "80") != NULL)
2251 num_subcarrier = 234;
2252 else if (strstr(channel_bandwidth_str, "40") != NULL)
2253 num_subcarrier = 108;
2254 else if (strstr(channel_bandwidth_str, "20") != NULL)
2255 num_subcarrier = 52;
2256 code_bits = 6;
2257 code_rate = (float)3/4;
2258 Symbol_duration = 32;
2259 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2260 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
2261 snprintf(output_string, 64, "65 Mb/s");
2262 return RETURN_OK;
2263 } else {
2264 snprintf(output_string, 64, "0 Mb/s");
2265 return RETURN_OK;
2266 }
2267
2268 // Spatial streams
developera1255e42023-05-13 17:45:02 +08002269 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +08002270 fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
2271 return RETURN_ERR;
2272 }
developera1255e42023-05-13 17:45:02 +08002273 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2274 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002275
2276 // multiple 10 is to align duration unit (0.1 us)
2277 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
2278 snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
developera1255e42023-05-13 17:45:02 +08002279 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2280 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
developer72fb0bb2023-01-11 09:46:29 +08002281 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2282
2283 return RETURN_OK;
2284}
2285#if 0
2286INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2287{
2288 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2289 char cmd[64];
2290 char buf[1024];
2291 int apIndex;
2292
developer69b61b02023-03-07 17:17:44 +08002293 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002294 return RETURN_ERR;
2295
2296 apIndex=(radioIndex==0)?0:1;
2297
2298 snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name);
2299 _syscmd(cmd,buf, sizeof(buf));
2300
2301 snprintf(output_string, 64, "%s", buf);
2302 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2303 return RETURN_OK;
2304}
2305#endif
2306
2307
2308//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2309//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.
2310INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2311{
2312 wifi_band band = band_invalid;
2313
2314 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2315 if (NULL == output_string)
2316 return RETURN_ERR;
2317
2318 band = wifi_index_to_band(radioIndex);
2319
2320 memset(output_string, 0, 10);
2321 if (band == band_2_4)
2322 strcpy(output_string, "2.4GHz");
2323 else if (band == band_5)
2324 strcpy(output_string, "5GHz");
2325 else if (band == band_6)
2326 strcpy(output_string, "6GHz");
2327 else
2328 return RETURN_ERR;
2329 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2330
2331 return RETURN_OK;
2332#if 0
2333 char buf[MAX_BUF_SIZE]={'\0'};
2334 char str[MAX_BUF_SIZE]={'\0'};
2335 char cmd[MAX_CMD_SIZE]={'\0'};
2336 char *ch=NULL;
2337 char *ch2=NULL;
2338
2339 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2340 if (NULL == output_string)
2341 return RETURN_ERR;
2342
2343
2344 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2345
2346 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2347 {
2348 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2349 return RETURN_ERR;
2350 }
2351 ch=strchr(buf,'\n');
2352 *ch='\0';
2353 ch=strchr(buf,'=');
2354 if(ch==NULL)
2355 return RETURN_ERR;
2356
2357
2358 ch++;
2359
2360 /* prepend 0 for channel with single digit. for ex, 6 would be 06 */
2361 strcpy(buf,"0");
2362 if(strlen(ch) == 1)
2363 ch=strcat(buf,ch);
2364
2365
2366 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2367
2368 if(_syscmd(cmd,str,64) == RETURN_ERR)
2369 {
2370 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2371 return RETURN_ERR;
2372 }
2373
2374
2375 ch2=strchr(str,'\n');
2376 //replace \n with \0
2377 *ch2='\0';
2378 ch2=strchr(str,'=');
2379 if(ch2==NULL)
2380 {
2381 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2382 return RETURN_ERR;
2383 }
2384 else
2385 wifi_dbg_printf("%s",ch2+1);
2386
2387
2388 ch2++;
2389
2390
2391 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch);
2392
2393 memset(buf,'\0',sizeof(buf));
2394 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2395 {
2396 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2397 return RETURN_ERR;
2398 }
2399 if (strstr(buf,"2.4") != NULL )
2400 strcpy(output_string,"2.4GHz");
2401 else if(strstr(buf,"5.") != NULL )
2402 strcpy(output_string,"5GHz");
2403 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2404
2405 return RETURN_OK;
2406#endif
2407}
2408
2409//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2410//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.
2411INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2412{
2413 wifi_band band = band_invalid;
2414 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2415 if (NULL == output_string)
2416 return RETURN_ERR;
2417 band = wifi_index_to_band(radioIndex);
2418
developer69b61b02023-03-07 17:17:44 +08002419 if (band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08002420 snprintf(output_string, 64, "2.4GHz");
2421 else if (band == band_5)
developer69b61b02023-03-07 17:17:44 +08002422 snprintf(output_string, 64, "5GHz");
developer72fb0bb2023-01-11 09:46:29 +08002423 else if (band == band_6)
2424 snprintf(output_string, 64, "6GHz");
2425
2426 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2427
2428 return RETURN_OK;
2429#if 0
2430 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2431 char buf[MAX_BUF_SIZE]={'\0'};
2432 char str[MAX_BUF_SIZE]={'\0'};
2433 char cmd[MAX_CMD_SIZE]={'\0'};
2434 char *ch=NULL;
2435 char *ch2=NULL;
2436 char ch1[5]="0";
2437
2438 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2439
2440 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2441 {
2442 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2443 return RETURN_ERR;
2444 }
2445
2446 ch=strchr(buf,'\n');
2447 *ch='\0';
2448 ch=strchr(buf,'=');
2449 if(ch==NULL)
2450 return RETURN_ERR;
2451 ch++;
2452
2453 if(strlen(ch)==1)
2454 {
2455 strcat(ch1,ch);
2456
2457 }
2458 else
2459 {
2460 strcpy(ch1,ch);
2461 }
2462
2463
2464
2465 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2466 if(_syscmd(cmd,str,64) == RETURN_ERR)
2467 {
2468 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2469 return RETURN_ERR;
2470 }
2471
2472
2473 ch2=strchr(str,'\n');
2474 //replace \n with \0
2475 *ch2='\0';
2476 ch2=strchr(str,'=');
2477 if(ch2==NULL)
2478 {
2479 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2480 return RETURN_ERR;
2481 }
2482 else
2483 wifi_dbg_printf("%s",ch2+1);
2484 ch2++;
2485
2486
2487 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1);
2488 memset(buf,'\0',sizeof(buf));
2489 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2490 {
2491 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2492 return RETURN_ERR;
2493 }
2494
2495
2496 if(strstr(buf,"2.4")!=NULL)
2497 {
2498 strcpy(output_string,"2.4GHz");
2499 }
2500 if(strstr(buf,"5.")!=NULL)
2501 {
2502 strcpy(output_string,"5GHz");
2503 }
2504 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2505 return RETURN_OK;
2506#endif
2507}
2508
2509//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2510//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.
2511INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2512{
2513 char cmd[128]={0};
2514 char buf[128]={0};
2515 char temp_output[128] = {0};
2516 wifi_band band;
2517 int phyId = 0;
2518
2519 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08002520 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002521 return RETURN_ERR;
2522
2523 band = wifi_index_to_band(radioIndex);
2524 if (band == band_2_4) {
2525 strcat(temp_output, "b,g,");
2526 } else if (band == band_5) {
2527 strcat(temp_output, "a,");
2528 }
2529 phyId = radio_index_to_phy(radioIndex);
2530 // ht capabilities
2531 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);
2532 _syscmd(cmd, buf, sizeof(buf));
2533 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
2534 strcat(temp_output, "n,");
2535 }
2536
2537 // vht capabilities
2538 if (band == band_5) {
2539 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2540 _syscmd(cmd, buf, sizeof(buf));
2541 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
2542 strcat(temp_output, "ac,");
2543 }
2544 }
2545
2546 // he capabilities
2547 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);
2548 _syscmd(cmd, buf, sizeof(buf));
2549 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2550 strcat(temp_output, "ax,");
2551 }
2552
developere82c0ca2023-05-10 16:25:35 +08002553 // eht capabilities
2554 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);
2555 _syscmd(cmd, buf, sizeof(buf));
2556 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2557 strcat(temp_output, "be,");
2558 }
2559
developer72fb0bb2023-01-11 09:46:29 +08002560 // Remove the last comma
2561 if (strlen(temp_output) != 0)
2562 temp_output[strlen(temp_output)-1] = '\0';
2563 strncpy(output_string, temp_output, strlen(temp_output));
2564 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2565 return RETURN_OK;
2566}
2567
2568//Get the radio operating mode, and pure mode flag. eg: "ac"
2569//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.
2570INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
2571{
2572 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2573 if (NULL == output_string)
2574 return RETURN_ERR;
2575
2576 if (radioIndex == 0) {
2577 snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
2578 *gOnly = FALSE;
2579 *nOnly = TRUE;
2580 *acOnly = FALSE;
2581 } else {
2582 snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
2583 *gOnly = FALSE;
2584 *nOnly = FALSE;
2585 *acOnly = FALSE;
2586 }
2587 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2588
2589 return RETURN_OK;
2590#if 0
2591 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2592 char buf[64] = {0};
2593 char config_file[MAX_BUF_SIZE] = {0};
2594
developer69b61b02023-03-07 17:17:44 +08002595 if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly))
developer72fb0bb2023-01-11 09:46:29 +08002596 return RETURN_ERR;
2597
2598 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2599 wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf));
2600
2601 wifi_dbg_printf("\nhw_mode=%s\n",buf);
developer69b61b02023-03-07 17:17:44 +08002602 if (strlen(buf) == 0)
developer72fb0bb2023-01-11 09:46:29 +08002603 {
2604 wifi_dbg_printf("\nwifi_hostapdRead returned none\n");
2605 return RETURN_ERR;
2606 }
2607 if(strcmp(buf,"g")==0)
2608 {
2609 wifi_dbg_printf("\nG\n");
2610 *gOnly=TRUE;
2611 *nOnly=FALSE;
2612 *acOnly=FALSE;
2613 }
2614 else if(strcmp(buf,"n")==0)
2615 {
2616 wifi_dbg_printf("\nN\n");
2617 *gOnly=FALSE;
2618 *nOnly=TRUE;
2619 *acOnly=FALSE;
2620 }
2621 else if(strcmp(buf,"ac")==0)
2622 {
2623 wifi_dbg_printf("\nac\n");
2624 *gOnly=FALSE;
2625 *nOnly=FALSE;
2626 *acOnly=TRUE;
2627 }
2628 /* hostapd-5G.conf has "a" as hw_mode */
2629 else if(strcmp(buf,"a")==0)
2630 {
2631 wifi_dbg_printf("\na\n");
2632 *gOnly=FALSE;
2633 *nOnly=FALSE;
2634 *acOnly=FALSE;
2635 }
2636 else
2637 wifi_dbg_printf("\nInvalid Mode %s\n", buf);
2638
2639 //for a,n mode
2640 if(radioIndex == 1)
2641 {
2642 wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf));
2643 if(strcmp(buf,"1")==0)
2644 {
2645 strncpy(output_string, "n", 1);
2646 *nOnly=FALSE;
2647 }
2648 }
2649
2650 wifi_dbg_printf("\nReturning from getRadioStandard\n");
2651 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2652 return RETURN_OK;
2653#endif
2654}
2655
developer0f10c772023-05-16 21:43:39 +08002656enum WIFI_MODE {
2657 WMODE_INVALID = 0,
2658 WMODE_A = 1 << 0,
2659 WMODE_B = 1 << 1,
2660 WMODE_G = 1 << 2,
2661 WMODE_GN = 1 << 3,
2662 WMODE_AN = 1 << 4,
2663 WMODE_AC = 1 << 5,
2664 WMODE_AX_24G = 1 << 6,
2665 WMODE_AX_5G = 1 << 7,
2666 WMODE_AX_6G = 1 << 8,
2667 WMODE_BE_24G = 1 << 9,
2668 WMODE_BE_5G = 1 << 10,
2669 WMODE_BE_6G = 1 << 11,
2670 /*
2671 * total types of supported wireless mode,
2672 * add this value once yow add new type
2673 */
2674 WMODE_COMP = 12,
2675};
2676
2677#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08002678
2679int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08002680{
developerfead3972023-05-25 20:15:02 +08002681 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2682 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
2683 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2684 unsigned int *phymode;
2685 int err = 0;
2686 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08002687
developerfead3972023-05-25 20:15:02 +08002688 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08002689 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developerfead3972023-05-25 20:15:02 +08002690 return NL_SKIP;
2691 }
developer72fb0bb2023-01-11 09:46:29 +08002692
developerfead3972023-05-25 20:15:02 +08002693 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2694 genlmsg_attrlen(gnlh, 0), NULL);
2695 if (err < 0) {
2696 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
2697 return NL_SKIP;
2698 }
developer0f10c772023-05-16 21:43:39 +08002699
developerfead3972023-05-25 20:15:02 +08002700 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2701 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
2702 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2703 if (err < 0)
2704 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08002705
developerfead3972023-05-25 20:15:02 +08002706 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
2707 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
2708
2709 memset(cb_data->out_buf, 0, cb_data->out_len);
2710 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
2711 }
2712 } else
2713 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
2714
2715 return NL_OK;
2716}
developer0f10c772023-05-16 21:43:39 +08002717
developerfead3972023-05-25 20:15:02 +08002718void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
2719{
2720 wifi_band band;
2721 unsigned char radio_mode_tem_len;
2722
2723 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08002724 // puremode is a bit map
developer72fb0bb2023-01-11 09:46:29 +08002725 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08002726 memset(output_string, 0, RADIO_MODE_LEN);
2727
2728 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2729
2730 switch (band) {
2731 case band_2_4:
2732 if (phymode & WMODE_B) {
2733 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
2734 *pureMode |= WIFI_MODE_B;
2735 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2736 }
2737 if (phymode & WMODE_G) {
2738 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
2739 *pureMode |= WIFI_MODE_G;
2740 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2741 }
2742 if (phymode & WMODE_GN) {
2743 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2744 *pureMode |= WIFI_MODE_N;
2745 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2746 }
2747 if (phymode & WMODE_AX_24G) {
2748 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2749 *pureMode |= WIFI_MODE_AX;
2750 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2751 }
2752 if (phymode & WMODE_BE_24G) {
2753 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2754 *pureMode |= WIFI_MODE_BE;
2755 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2756 }
2757 break;
2758 case band_5:
2759 if (phymode & WMODE_A) {
2760 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
2761 *pureMode |= WIFI_MODE_A;
2762 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2763 }
2764 if (phymode & WMODE_AN) {
2765 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
2766 *pureMode |= WIFI_MODE_N;
2767 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2768 }
2769 if (phymode & WMODE_AC) {
2770 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
2771 *pureMode |= WIFI_MODE_AC;
2772 }
2773 if (phymode & WMODE_AX_5G) {
2774 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2775 *pureMode |= WIFI_MODE_AX;
2776 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2777 }
2778 if (phymode & WMODE_BE_5G) {
2779 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2780 *pureMode |= WIFI_MODE_BE;
2781 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2782 }
2783 break;
2784 case band_6:
2785 if (phymode & WMODE_AX_6G) {
2786 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
2787 *pureMode |= WIFI_MODE_AX;
2788 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2789 }
2790 if (phymode & WMODE_BE_6G) {
2791 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
2792 *pureMode |= WIFI_MODE_BE;
2793 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
2794 }
2795 break;
2796 default:
2797 fprintf(stderr, "%s band_idx invalid\n", __func__);
2798 break;
2799 }
2800
2801 /* Remove the last comma */
2802 if (strlen(output_string) != 0)
2803 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08002804
developerfead3972023-05-25 20:15:02 +08002805}
2806
2807INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
2808{
2809 unsigned int phymode;
2810 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08002811 int ret = -1;
2812 unsigned int if_idx = 0;
2813 struct unl unl_ins;
2814 struct nl_msg *msg = NULL;
2815 struct nlattr * msg_data = NULL;
2816 struct mtk_nl80211_param param;
2817 struct mtk_nl80211_cb_data cb_data;
2818
2819 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerdaf24792023-06-06 11:40:04 +08002820 if (NULL == output_string || NULL == pureMode)
2821 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08002822
2823 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2824 return RETURN_ERR;
2825
2826 if_idx = if_nametoindex(interface_name);
2827 if (!if_idx) {
2828 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
2829 return RETURN_ERR;
2830 }
2831 /*init mtk nl80211 vendor cmd*/
2832 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
2833 param.if_type = NL80211_ATTR_IFINDEX;
2834 param.if_idx = if_idx;
2835
2836 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
2837 if (ret) {
2838 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
2839 return RETURN_ERR;
2840 }
2841
2842 /*add mtk vendor cmd data*/
2843 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
2844 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
2845 nlmsg_free(msg);
2846 goto err;
2847 }
2848
2849 /*send mtk nl80211 vendor msg*/
2850 cb_data.out_buf = (char *)&phymode;
2851 cb_data.out_len = sizeof(unsigned int);
2852
2853 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
2854
2855 if (ret) {
2856 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
2857 goto err;
2858 }
2859 /*deinit mtk nl80211 vendor msg*/
2860 mtk_nl80211_deint(&unl_ins);
2861
2862 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
2863 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
2864
developer72fb0bb2023-01-11 09:46:29 +08002865 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2866 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08002867err:
2868 mtk_nl80211_deint(&unl_ins);
2869 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
2870 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002871}
2872
2873// Set the radio operating mode, and pure mode flag.
2874INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
2875{
developer69b61b02023-03-07 17:17:44 +08002876 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002877 if (strcmp (channelMode,"11A") == 0)
2878 {
2879 writeBandWidth(radioIndex,"20MHz");
2880 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2881 printf("\nChannel Mode is 802.11a (5GHz)\n");
2882 }
2883 else if (strcmp (channelMode,"11NAHT20") == 0)
2884 {
2885 writeBandWidth(radioIndex,"20MHz");
2886 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2887 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
2888 }
2889 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
2890 {
2891 writeBandWidth(radioIndex,"40MHz");
2892 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2893 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
2894 }
2895 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
2896 {
2897 writeBandWidth(radioIndex,"40MHz");
2898 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2899 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
2900 }
2901 else if (strcmp (channelMode,"11ACVHT20") == 0)
2902 {
2903 writeBandWidth(radioIndex,"20MHz");
2904 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2905 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
2906 }
2907 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
2908 {
2909 writeBandWidth(radioIndex,"40MHz");
2910 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2911 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
2912 }
2913 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
2914 {
2915 writeBandWidth(radioIndex,"40MHz");
2916 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2917 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
2918 }
2919 else if (strcmp (channelMode,"11ACVHT80") == 0)
2920 {
2921 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
2922 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
2923 }
2924 else if (strcmp (channelMode,"11ACVHT160") == 0)
2925 {
2926 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
2927 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
developer69b61b02023-03-07 17:17:44 +08002928 }
developer72fb0bb2023-01-11 09:46:29 +08002929 else if (strcmp (channelMode,"11B") == 0)
2930 {
2931 writeBandWidth(radioIndex,"20MHz");
2932 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2933 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
2934 }
2935 else if (strcmp (channelMode,"11G") == 0)
2936 {
2937 writeBandWidth(radioIndex,"20MHz");
2938 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2939 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
2940 }
2941 else if (strcmp (channelMode,"11NGHT20") == 0)
2942 {
2943 writeBandWidth(radioIndex,"20MHz");
2944 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
2945 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
2946 }
2947 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
2948 {
2949 writeBandWidth(radioIndex,"40MHz");
2950 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2951 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
2952 }
2953 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
2954 {
2955 writeBandWidth(radioIndex,"40MHz");
2956 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
2957 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
2958 }
developer69b61b02023-03-07 17:17:44 +08002959 else
developer72fb0bb2023-01-11 09:46:29 +08002960 {
2961 return RETURN_ERR;
2962 }
2963 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2964
2965 return RETURN_OK;
2966}
2967
developer0f10c772023-05-16 21:43:39 +08002968typedef enum _RT_802_11_PHY_MODE {
2969 PHY_11BG_MIXED = 0,
2970 PHY_11B = 1,
2971 PHY_11A = 2,
2972 PHY_11ABG_MIXED = 3,
2973 PHY_11G = 4,
2974 PHY_11ABGN_MIXED = 5, /* both band 5 */
2975 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
2976 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
2977 PHY_11AN_MIXED = 8, /* 5G band 8 */
2978 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
2979 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
2980 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
2981 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
2982 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
2983 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
2984 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
2985 PHY_11AX_24G = 16,
2986 PHY_11AX_5G = 17,
2987 PHY_11AX_6G = 18,
2988 PHY_11AX_24G_6G = 19,
2989 PHY_11AX_5G_6G = 20,
2990 PHY_11AX_24G_5G_6G = 21,
2991 PHY_11BE_24G = 22,
2992 PHY_11BE_5G = 23,
2993 PHY_11BE_6G = 24,
2994 PHY_11BE_24G_6G = 25,
2995 PHY_11BE_5G_6G = 26,
2996 PHY_11BE_24G_5G_6G = 27,
2997 PHY_MODE_MAX,
2998} RT_802_11_PHY_MODE;
2999
3000unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3001{
3002 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003003 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003004
3005 band_idx = radio_index_to_band(radioIndex);
3006
3007 switch (band_idx) {
3008 case band_2_4:
3009 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3010 wireless_mode = PHY_11GN_MIXED;
3011 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3012 wireless_mode = PHY_11BGN_MIXED;
3013 if (pureMode & WIFI_MODE_AX)
3014 wireless_mode = PHY_11AX_24G;
3015 if (pureMode & WIFI_MODE_BE)
3016 wireless_mode = PHY_11BE_24G;
3017 break;
3018 case band_5:
3019 if (pureMode == WIFI_MODE_N)
3020 wireless_mode = PHY_11N_5G;
3021 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3022 wireless_mode = PHY_11VHT_N_MIXED;
3023 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3024 wireless_mode = PHY_11VHT_N_A_MIXED;
3025 if (pureMode & WIFI_MODE_AX)
3026 wireless_mode = PHY_11AX_5G;
3027 if (pureMode & WIFI_MODE_BE)
3028 wireless_mode = PHY_11BE_5G;
3029 break;
3030 case band_6:
3031 if (pureMode & WIFI_MODE_AX)
3032 wireless_mode = PHY_11AX_6G;
3033 if (pureMode & WIFI_MODE_BE)
3034 wireless_mode = PHY_11BE_6G;
3035 break;
3036 default:
3037 fprintf(stderr, "%s band_idx invalid\n", __func__);
3038 break;
3039 }
3040
3041 return wireless_mode;
3042}
3043
developer72fb0bb2023-01-11 09:46:29 +08003044// Set the radio operating mode, and pure mode flag.
3045INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3046{
developerfead3972023-05-25 20:15:02 +08003047 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003048
developer0f10c772023-05-16 21:43:39 +08003049 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003050 int ret = -1;
3051 unsigned int if_idx = 0;
3052 struct unl unl_ins;
3053 struct nl_msg *msg = NULL;
3054 struct nlattr * msg_data = NULL;
3055 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003056
developer0f10c772023-05-16 21:43:39 +08003057 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003058
developer0f10c772023-05-16 21:43:39 +08003059 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003060
developer0f10c772023-05-16 21:43:39 +08003061 if (wireless_mode == PHY_MODE_MAX) {
3062 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3063 return RETURN_ERR;
3064 }
developer72fb0bb2023-01-11 09:46:29 +08003065
developer0f10c772023-05-16 21:43:39 +08003066 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3067 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003068
3069 if_idx = if_nametoindex(interface_name);
3070 if (!if_idx) {
3071 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3072 return RETURN_ERR;
3073 }
3074 /*init mtk nl80211 vendor cmd*/
3075 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3076 param.if_type = NL80211_ATTR_IFINDEX;
3077 param.if_idx = if_idx;
3078
3079 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3080 if (ret) {
3081 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3082 return RETURN_ERR;
3083 }
3084
3085 /*add mtk vendor cmd data*/
3086 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3087 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3088 nlmsg_free(msg);
3089 goto err;
3090 }
3091 /*send mtk nl80211 vendor msg*/
3092 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3093 if (ret) {
3094 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3095 goto err;
3096 }
3097 /*deinit mtk nl80211 vendor msg*/
3098 mtk_nl80211_deint(&unl_ins);
3099 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003100
developer0f10c772023-05-16 21:43:39 +08003101 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3102
3103 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003104err:
3105 mtk_nl80211_deint(&unl_ins);
3106 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3107 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003108}
3109
3110INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3111{
developerfead3972023-05-25 20:15:02 +08003112 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003113 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003114 char dat_file[MAX_BUF_SIZE] = {0};
3115 struct params params={0};
3116
3117 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3118
3119 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3120
3121 if (wireless_mode == PHY_MODE_MAX) {
3122 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3123 return RETURN_ERR;
3124 }
3125
3126 params.name = "WirelessMode";
3127 snprintf(buf, sizeof(buf), "%d", wireless_mode);
3128 params.value = buf;
3129
3130 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3131 wifi_datfileWrite(dat_file, &params, 1);
3132
developer72fb0bb2023-01-11 09:46:29 +08003133 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3134
3135 return RETURN_OK;
3136}
3137
3138INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3139
3140 char config_file[64] = {0};
3141 char buf[64] = {0};
3142 struct params params = {0};
3143 wifi_band band = band_invalid;
3144
3145 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3146
3147 band = wifi_index_to_band(radioIndex);
3148
3149 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3150 return RETURN_ERR;
3151 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3152 return RETURN_ERR;
3153 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3154 return RETURN_ERR;
3155
3156 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3157 params.name = "hw_mode";
3158 params.value = hw_mode;
3159 wifi_hostapdWrite(config_file, &params, 1);
3160 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3161
3162 if (band == band_2_4) {
3163 if (strncmp(hw_mode, "b", 1) == 0) {
3164 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
3165 snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3166 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3167 snprintf(buf, sizeof(buf), "%s", "1,2");
3168 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3169 } else {
3170 // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
3171
3172 snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3173 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3174 snprintf(buf, sizeof(buf), "%s", "6,12,24");
3175 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3176 }
3177 }
3178
3179 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3180 return RETURN_OK;
3181}
3182
3183INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3184{
3185 char config_file[64] = {0};
3186 struct params params = {0};
3187 wifi_band band = band_invalid;
3188
3189 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3190
3191 band = wifi_index_to_band(radioIndex);
3192 if (band != band_2_4)
3193 return RETURN_OK;
3194
3195 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3196 params.name = "noscan";
3197 params.value = noscan;
3198 wifi_hostapdWrite(config_file, &params, 1);
3199 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3200
3201 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3202 return RETURN_OK;
3203}
3204
3205//Get the list of supported channel. eg: "1-11"
3206//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.
3207INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3208{
3209 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08003210 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08003211 return RETURN_ERR;
3212 char cmd[256] = {0};
3213 char buf[128] = {0};
3214 BOOL dfs_enable = false;
3215 int phyId = 0;
3216
3217 // Parse possible channel number and separate them with commas.
3218 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3219 phyId = radio_index_to_phy(radioIndex);
3220 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3221 if (dfs_enable)
3222 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);
developer69b61b02023-03-07 17:17:44 +08003223 else
developer72fb0bb2023-01-11 09:46:29 +08003224 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);
3225
3226 _syscmd(cmd,buf,sizeof(buf));
developerc79e9172023-06-06 19:48:03 +08003227 strncpy(output_string, buf, strlen(buf) < sizeof(buf) ? strlen(buf) : sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003228
3229 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3230 return RETURN_OK;
3231}
developerd1824452023-05-18 12:30:04 +08003232//Getting current radio extension channel
3233INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3234{
3235 CHAR buf[150] = {0};
developerd1824452023-05-18 12:30:04 +08003236
3237 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer262f4cb2023-05-24 12:22:04 +08003238 if (strncmp(buf, "Below", 5) == 0) //below
developerd1824452023-05-18 12:30:04 +08003239 strcpy(Value,"BelowControlChannel");
developer262f4cb2023-05-24 12:22:04 +08003240 if(strncmp(buf, "Above", 5) == 0) //above
developerd1824452023-05-18 12:30:04 +08003241 strcpy(Value,"AboveControlChannel");
3242 return RETURN_OK;
3243}
developerf6a87542023-05-16 15:47:28 +08003244
developer72fb0bb2023-01-11 09:46:29 +08003245//Get the list for used channel. eg: "1,6,9,11"
3246//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.
3247INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3248{
3249 char interface_name[16] = {0};
3250 char cmd[128] = {0};
3251 char buf[128] = {0};
3252 char config_file[64] = {0};
3253 int channel = 0;
3254 int freq = 0;
3255 int bandwidth = 0;
3256 int center_freq = 0;
3257 int center_channel = 0;
3258 int channel_delta = 0;
3259 wifi_band band = band_invalid;
3260
3261 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3262
3263 if (NULL == output_string)
3264 return RETURN_ERR;
3265
3266 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3267 return RETURN_ERR;
3268 sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3269 _syscmd(cmd, buf, sizeof(buf));
3270 if (strlen(buf) == 0) {
3271 fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__);
3272 return RETURN_ERR;
3273 }
3274 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
3275
3276 if (bandwidth == 20) {
3277 snprintf(output_string, 256, "%d", channel);
3278 return RETURN_OK;
3279 }
3280
3281 center_channel = ieee80211_frequency_to_channel(center_freq);
3282
3283 band = wifi_index_to_band(radioIndex);
3284 if (band == band_2_4 && bandwidth == 40) {
developerd1824452023-05-18 12:30:04 +08003285 sprintf(config_file, "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08003286 memset(buf, 0, sizeof(buf));
3287 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
3288
3289 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
3290 snprintf(output_string, 256, "%d,%d", channel, channel+4);
3291 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
3292 snprintf(output_string, 256, "%d,%d", channel-4, channel);
3293 } else {
3294 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
3295 return RETURN_ERR;
3296 }
3297 } else if (band == band_5 || band == band_6){
3298 // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel.
developerd1824452023-05-18 12:30:04 +08003299 // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6.
developer72fb0bb2023-01-11 09:46:29 +08003300 channel_delta = (bandwidth-20)/10;
developerd1824452023-05-18 12:30:04 +08003301 memset(output_string, 0, 256);
3302 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3303 // If i is not the last channel, we add a comma.
3304 snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
3305 strncat(output_string, buf, strlen(buf));
3306 }
developer72fb0bb2023-01-11 09:46:29 +08003307 } else
3308 return RETURN_ERR;
3309
3310 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3311 return RETURN_OK;
3312}
3313
developer69b61b02023-03-07 17:17:44 +08003314//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003315INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003316{
3317 char channel_str[16] = {0};
3318 char config_file[128] = {0};
developer47a56bf2023-05-30 13:38:57 +08003319 char buf[MAX_BUF_SIZE] = {0};
3320 char cmd[MAX_CMD_SIZE] = {0};
3321 char interface_name[IF_NAME_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08003322 wifi_band band = band_invalid;
developer47a56bf2023-05-30 13:38:57 +08003323 ULONG iwChannel = 0;
3324
developer72fb0bb2023-01-11 09:46:29 +08003325 if (output_ulong == NULL)
3326 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003327 band = wifi_index_to_band(radioIndex);
3328 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3329 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
developer72fb0bb2023-01-11 09:46:29 +08003330 *output_ulong = strtoul(channel_str, NULL, 10);
developer47a56bf2023-05-30 13:38:57 +08003331 if (*output_ulong == 0) {
3332 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3333 return RETURN_ERR;
3334 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
3335 _syscmd(cmd,buf,sizeof(buf));
3336 sscanf(buf, "%lu", &iwChannel);
3337 *output_ulong = iwChannel;
3338 }
developer72fb0bb2023-01-11 09:46:29 +08003339
3340 return RETURN_OK;
3341}
3342
developer72fb0bb2023-01-11 09:46:29 +08003343INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
3344{
3345 char cmd[1024] = {0}, buf[5] = {0};
3346 char interface_name[16] = {0};
3347
3348 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3349 if (NULL == output_ulong)
3350 return RETURN_ERR;
3351
developer47a56bf2023-05-30 13:38:57 +08003352 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08003353 return RETURN_ERR;
developer47a56bf2023-05-30 13:38:57 +08003354
3355 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08003356 _syscmd(cmd,buf,sizeof(buf));
3357 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
3358 if (*output_ulong == 0) {
3359 return RETURN_ERR;
3360 }
3361
3362 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3363 return RETURN_OK;
3364}
developer72fb0bb2023-01-11 09:46:29 +08003365//Storing the previous channel value
3366INT wifi_storeprevchanval(INT radioIndex)
3367{
3368 char buf[256] = {0};
3369 char output[4]={'\0'};
3370 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08003371 wifi_band band = band_invalid;
3372
3373 band = wifi_index_to_band(radioIndex);
3374 if (band == band_invalid) {
3375 return RETURN_ERR;
3376 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
3377 }
3378 snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
3379 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
3380
3381 if(band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08003382 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003383 else if(band == band_5)
developer72fb0bb2023-01-11 09:46:29 +08003384 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003385 else
3386 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
developer72fb0bb2023-01-11 09:46:29 +08003387 system(buf);
3388 Radio_flag = FALSE;
3389 return RETURN_OK;
3390}
3391
3392//Set the running channel number
3393INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
3394{
3395 // We only write hostapd config here
3396 char str_channel[8]={0};
3397 char *list_channel;
developer72fb0bb2023-01-11 09:46:29 +08003398 char possible_channels[256] = {0};
developerd1824452023-05-18 12:30:04 +08003399 char config_file_dat[128] = {0};
developerd1824452023-05-18 12:30:04 +08003400 struct params dat = {0};
3401 struct params acs = {0};
3402 wifi_band band = band_invalid;
3403 bool acs_channel = false;
developer72fb0bb2023-01-11 09:46:29 +08003404
3405 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3406
developerd1824452023-05-18 12:30:04 +08003407 if (channel == 0)
3408 acs_channel = true;
developer72fb0bb2023-01-11 09:46:29 +08003409 // Check valid
3410 sprintf(str_channel, "%lu", channel);
3411
developerd1824452023-05-18 12:30:04 +08003412
developer72fb0bb2023-01-11 09:46:29 +08003413 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
3414 list_channel = strtok(possible_channels, ",");
3415 while(true)
3416 {
3417 if(list_channel == NULL) { // input not in the list
3418 fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel);
3419 return RETURN_ERR;
3420 }
3421 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
3422 break;
3423 list_channel = strtok(NULL, ",");
3424 }
developerd1824452023-05-18 12:30:04 +08003425 /*
developer72fb0bb2023-01-11 09:46:29 +08003426 list.name = "channel";
3427 list.value = str_channel;
3428 wifi_getMaxRadioNumber(&max_radio_num);
3429 for(int i=0; i<=MAX_APS/max_radio_num;i++)
3430 {
3431 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3432 wifi_hostapdWrite(config_file, &list, 1);
3433 }
developerd1824452023-05-18 12:30:04 +08003434 */
3435 dat.name = "Channel";
3436 dat.value = str_channel;
3437 band = wifi_index_to_band(radioIndex);
3438 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3439 wifi_datfileWrite(config_file_dat, &dat, 1);
3440 if (acs_channel == true) {
3441 acs.name = "AutoChannelSelect";
3442 acs.value = "3";
3443 } else {
3444 acs.name = "AutoChannelSelect";
3445 acs.value = "0";
3446 }
3447 wifi_datfileWrite(config_file_dat, &acs, 1);
developerc0772e62023-05-18 15:10:48 +08003448 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003449 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3450 return RETURN_OK;
3451}
3452
3453INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
3454{
3455 struct params list[2];
3456 char str_idx[16];
3457 char config_file[64];
3458 int max_num_radios = 0;
3459 wifi_band band = band_invalid;
3460
3461 band = wifi_index_to_band(radioIndex);
3462 if (band == band_2_4)
3463 return RETURN_OK;
3464
3465 snprintf(str_idx, sizeof(str_idx), "%lu", channel);
3466 list[0].name = "vht_oper_centr_freq_seg0_idx";
3467 list[0].value = str_idx;
3468 list[1].name = "he_oper_centr_freq_seg0_idx";
3469 list[1].value = str_idx;
3470
3471 wifi_getMaxRadioNumber(&max_num_radios);
3472 for(int i=0; i<=MAX_APS/max_num_radios; i++)
3473 {
3474 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
3475 if (band == band_6)
3476 wifi_hostapdWrite(config_file, &list[1], 1);
3477 else
3478 wifi_hostapdWrite(config_file, list, 2);
3479 }
3480
3481 return RETURN_OK;
3482}
3483
3484//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
3485//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
3486INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
3487{
3488 //Set to wifi config only. Wait for wifi reset to apply.
developer72fb0bb2023-01-11 09:46:29 +08003489 ULONG Value = 0;
developer47a56bf2023-05-30 13:38:57 +08003490 char config_file_dat[128] = {0};
3491 struct params acs = {0};
3492 wifi_band band = band_invalid;
3493
3494 if(enable == TRUE) {
developer72fb0bb2023-01-11 09:46:29 +08003495 wifi_setRadioChannel(radioIndex,Value);
developer47a56bf2023-05-30 13:38:57 +08003496 } else {
3497 acs.name = "AutoChannelSelect";
3498 acs.value = "0";
3499 band = wifi_index_to_band(radioIndex);
3500 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3501 wifi_datfileWrite(config_file_dat, &acs, 1);
developer72fb0bb2023-01-11 09:46:29 +08003502 }
3503 return RETURN_OK;
3504}
3505
3506INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
3507{
3508 if (output_bool == NULL)
3509 return RETURN_ERR;
3510
3511 *output_bool = TRUE;
3512
3513 return RETURN_OK;
3514}
3515
3516INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
3517{
developer69b61b02023-03-07 17:17:44 +08003518 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003519 return RETURN_ERR;
3520 *output_bool=FALSE;
3521 return RETURN_OK;
3522}
3523
3524INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
3525{
developer69b61b02023-03-07 17:17:44 +08003526 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003527 return RETURN_ERR;
3528 *output_bool=FALSE;
3529 return RETURN_OK;
3530}
3531
3532INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
3533{
3534 //Set to wifi config only. Wait for wifi reset to apply.
3535 return RETURN_OK;
3536}
3537
3538INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
3539{
3540 return RETURN_OK;
3541}
3542
3543INT wifi_factoryResetAP(int apIndex)
3544{
developerb149d9d2023-06-06 16:14:22 +08003545 char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08003546 char cmd[MAX_CMD_SIZE] = {0};
3547 char ret_buf[MAX_BUF_SIZE] = {0};
3548 int radio_idx = 0;
3549 int bss_idx = 0;
3550 char ssid[32] = {0};
3551 char interface[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +08003552 char psk_file[MAX_SUB_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08003553 struct params params[3] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003554
3555 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3556
developer47cc27a2023-05-17 23:09:58 +08003557 /*del old config file*/
3558 snprintf(ap_config_file, MAX_CMD_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
3559 snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
3560 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003561
developer47cc27a2023-05-17 23:09:58 +08003562 memset(cmd, 0, sizeof(cmd));
3563 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003564
developer47cc27a2023-05-17 23:09:58 +08003565 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
3566
3567 /*prepare new config file*/
developere740c2a2023-05-23 18:34:32 +08003568 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
developer47cc27a2023-05-17 23:09:58 +08003569 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3570
3571 if (radio_idx == band_2_4) {
3572 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
3573 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
3574 } else if (radio_idx == band_5) {
3575 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
3576 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
3577 } else if (radio_idx == band_6) {
3578 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
3579 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
3580 }
3581
3582 /* fix wpa_psk_file path */
3583 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
3584
3585 params[0].name = "ssid";
3586 params[0].value = ssid;
3587 params[1].name = "interface";
3588 params[1].value = interface;
3589 params[2].name = "wpa_psk_file";
3590 params[2].value = psk_file;
3591
3592 wifi_hostapdWrite(ap_config_file, params, 3);
3593
3594 /*clear psk file*/
3595 memset(cmd, 0, sizeof(cmd));
3596 memset(ret_buf, 0, sizeof(ret_buf));
3597
3598 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
3599
3600 if (access(psk_file, F_OK) != 0) {
3601 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
3602 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3603 } else {
3604 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
3605 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3606 }
3607
developer429ba832023-05-31 11:03:35 +08003608 wifi_setApEnable(apIndex, FALSE);
3609 wifi_setApEnable(apIndex, TRUE);
developer47cc27a2023-05-17 23:09:58 +08003610 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3611
3612 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003613}
3614
3615//To set Band Steering AP group
3616//To-do
3617INT wifi_setBandSteeringApGroup(char *ApGroup)
3618{
3619 return RETURN_OK;
3620}
3621
3622INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
3623{
3624 char config_file[128] = {'\0'};
3625 char buf[128] = {'\0'};
3626
3627 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3628 if (dtimInterval == NULL)
3629 return RETURN_ERR;
3630
3631 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer885b56c2023-05-22 15:02:46 +08003632 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003633
3634 if (strlen(buf) == 0) {
3635 *dtimInterval = 2;
3636 } else {
3637 *dtimInterval = strtoul(buf, NULL, 10);
3638 }
3639
3640 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3641 return RETURN_OK;
3642}
3643
3644INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
3645{
3646 struct params params={0};
3647 char config_file[MAX_BUF_SIZE] = {'\0'};
3648 char buf[MAX_BUF_SIZE] = {'\0'};
3649
3650 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3651 if (dtimInterval < 1 || dtimInterval > 255) {
3652 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
3653 return RETURN_ERR;
3654 }
developer69b61b02023-03-07 17:17:44 +08003655
developer72fb0bb2023-01-11 09:46:29 +08003656 params.name = "dtim_period";
3657 snprintf(buf, sizeof(buf), "%d", dtimInterval);
3658 params.value = buf;
3659
3660 sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex);
3661 wifi_hostapdWrite(config_file, &params, 1);
3662 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3663
3664 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3665 return RETURN_OK;
3666}
3667
3668//Check if the driver support the Dfs
3669INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
3670{
3671 wifi_band band = band_invalid;
developer69b61b02023-03-07 17:17:44 +08003672 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003673 return RETURN_ERR;
3674 *output_bool=FALSE;
3675
3676 band = wifi_index_to_band(radioIndex);
3677 if (band == band_5)
3678 *output_bool = TRUE;
3679 return RETURN_OK;
3680}
3681
3682//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.
3683//The value of this parameter is a comma seperated list of channel number
3684INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
3685{
developer69b61b02023-03-07 17:17:44 +08003686 if (NULL == output_pool)
developer72fb0bb2023-01-11 09:46:29 +08003687 return RETURN_ERR;
3688 if (radioIndex==1)
developer69b61b02023-03-07 17:17:44 +08003689 return RETURN_OK;//TODO need to handle for 5GHz band, i think
developer72fb0bb2023-01-11 09:46:29 +08003690 snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
3691
3692 return RETURN_OK;
3693}
3694
3695INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
3696{
3697 //Set to wifi config. And apply instantly.
3698 return RETURN_OK;
3699}
3700
3701INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
3702{
developer69b61b02023-03-07 17:17:44 +08003703 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
developer72fb0bb2023-01-11 09:46:29 +08003704 return RETURN_ERR;
3705 *output_interval_seconds=1800;
3706 *output_dwell_milliseconds=40;
3707
3708 return RETURN_OK;
3709}
3710
3711INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
3712{
3713 //Set to wifi config. And apply instantly.
3714 return RETURN_OK;
3715}
3716
3717INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
3718{
3719 if (output_bool == NULL)
3720 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08003721 *output_bool = true;
3722 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003723}
3724
3725INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
3726{
3727 return RETURN_OK;
3728}
3729
3730//Get the Dfs enable status
3731INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
3732{
3733 char buf[16] = {0};
developerd1824452023-05-18 12:30:04 +08003734 char config_file_dat[128] = {0};
developerd1824452023-05-18 12:30:04 +08003735 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003736
3737 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3738
3739 if (output_bool == NULL)
3740 return RETURN_ERR;
developerf6a87542023-05-16 15:47:28 +08003741 *output_bool = TRUE; // default
developerd1824452023-05-18 12:30:04 +08003742 band = wifi_index_to_band(radioIndex);
3743 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3744
developer262f4cb2023-05-24 12:22:04 +08003745 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08003746
3747 if (strncmp(buf, "0", 1) == 0)
3748 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08003749 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3750 return RETURN_OK;
3751}
3752
3753//Set the Dfs enable status
3754INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
3755{
developerd1824452023-05-18 12:30:04 +08003756 char config_dat_file[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003757 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08003758 struct params dat = {0};
3759 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003760
3761 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3762
3763 f = fopen(DFS_ENABLE_FILE, "w");
3764 if (f == NULL)
3765 return RETURN_ERR;
3766 fprintf(f, "%d", enable);
3767 fclose(f);
3768
developer72fb0bb2023-01-11 09:46:29 +08003769 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
3770
developerd1824452023-05-18 12:30:04 +08003771 dat.name = "DfsEnable";
developer262f4cb2023-05-24 12:22:04 +08003772 dat.value = enable?"1":"0";
developerd1824452023-05-18 12:30:04 +08003773 band = wifi_index_to_band(radioIndex);
3774 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3775 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08003776 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3777 return RETURN_OK;
3778}
3779
3780//Check if the driver support the AutoChannelRefreshPeriod
3781INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
3782{
developer69b61b02023-03-07 17:17:44 +08003783 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003784 return RETURN_ERR;
3785 *output_bool=FALSE; //not support
3786
3787 return RETURN_OK;
3788}
3789
3790//Get the ACS refresh period in seconds
3791INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
3792{
developer69b61b02023-03-07 17:17:44 +08003793 if (NULL == output_ulong)
developer72fb0bb2023-01-11 09:46:29 +08003794 return RETURN_ERR;
3795 *output_ulong=300;
3796
3797 return RETURN_OK;
3798}
3799
3800//Set the ACS refresh period in seconds
3801INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
3802{
3803 return RETURN_ERR;
3804}
3805
3806//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
3807//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.
3808INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
3809{
developer5a333cf2023-06-06 18:18:50 +08003810 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003811 char extchannel[128] = {0};
developer8666b312023-03-24 14:05:31 +08003812 char interface_name[64] = {0};
3813 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08003814 BOOL radio_enable = FALSE;
3815 wifi_band band;
3816
3817 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3818
developerd1824452023-05-18 12:30:04 +08003819 if (NULL == output_string) {
3820 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003821 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003822 }
3823 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
3824 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003825 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003826 }
3827 if (radio_enable != TRUE) {
3828 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003829 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08003830 }
developer8666b312023-03-24 14:05:31 +08003831 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3832 return RETURN_ERR;
3833 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08003834
developer8666b312023-03-24 14:05:31 +08003835 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
3836 ret = _syscmd(cmd, buf, sizeof(buf));
3837 len = strlen(buf);
3838 if((ret != 0) || (len == 0))
3839 {
3840 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
3841 return RETURN_ERR;
3842 }
3843
developer72fb0bb2023-01-11 09:46:29 +08003844 band = wifi_index_to_band(radioIndex);
developer8666b312023-03-24 14:05:31 +08003845 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
developer72fb0bb2023-01-11 09:46:29 +08003846 wifi_getRadioExtChannel(radioIndex, extchannel);
developer8666b312023-03-24 14:05:31 +08003847 if (strncmp(extchannel, "Auto", 4) != 0) // not auto means we have set HT40+/-
3848 snprintf(buf, sizeof(buf), "40");
developer72fb0bb2023-01-11 09:46:29 +08003849 }
developer8666b312023-03-24 14:05:31 +08003850 snprintf(output_string, 64, "%sMHz", buf);
developer72fb0bb2023-01-11 09:46:29 +08003851 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3852
3853 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003854}
3855
3856enum mwctl_chan_width {
3857 MWCTL_CHAN_WIDTH_20,
3858 MWCTL_CHAN_WIDTH_40,
3859 MWCTL_CHAN_WIDTH_80,
3860 MWCTL_CHAN_WIDTH_160,
3861 MWCTL_CHAN_WIDTH_320,
3862};
3863
3864struct bw_option {
3865 unsigned int bandwith;
3866 enum mwctl_chan_width mode;
3867};
3868
3869struct bw_option bw_opt[] = {
3870 {20, MWCTL_CHAN_WIDTH_20},
3871 {40, MWCTL_CHAN_WIDTH_40},
3872 {80, MWCTL_CHAN_WIDTH_80},
3873 {160, MWCTL_CHAN_WIDTH_160},
3874 {320, MWCTL_CHAN_WIDTH_320},
3875};
3876
3877INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
3878{
3879 int ret = -1;
3880 int i;
3881 struct unl unl_ins;
3882 struct nl_msg *msg = NULL;
3883 struct nlattr * msg_data = NULL;
3884 struct mtk_nl80211_param param;
3885 bool b_match = FALSE;
3886
3887 /*init mtk nl80211 vendor cmd*/
3888 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
3889 param.if_type = NL80211_ATTR_WIPHY;
3890 param.if_idx = radio_index_to_phy(radioIndex);
3891
3892 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3893 if (ret) {
3894 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3895 return RETURN_ERR;
3896 }
3897
3898 /*add mtk vendor cmd data*/
3899 if (channel != NULL)
3900 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
3901 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
3902 nlmsg_free(msg);
3903 goto err;
3904 }
3905
3906 if (bandwidth != NULL) {
3907 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
3908 if (bw_opt[i].bandwith == *bandwidth) {
3909 b_match = true;
3910 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
3911 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
3912 nlmsg_free(msg);
3913 goto err;
3914 }
3915 break;
3916 }
3917 }
3918
3919 if (!b_match) {
3920 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
3921 nlmsg_free(msg);
3922 goto err;
3923 }
3924 }
3925
3926 /*send mtk nl80211 vendor msg*/
3927 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3928 if (ret) {
3929 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3930 goto err;
3931 }
3932 /*deinit mtk nl80211 vendor msg*/
3933 mtk_nl80211_deint(&unl_ins);
3934 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
3935 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3936
3937 return RETURN_OK;
3938err:
3939 mtk_nl80211_deint(&unl_ins);
3940 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3941 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003942}
developerfead3972023-05-25 20:15:02 +08003943
developer72fb0bb2023-01-11 09:46:29 +08003944//Set the Operating Channel Bandwidth.
3945INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
3946{
3947 char config_file[128];
developerd1824452023-05-18 12:30:04 +08003948 char ht_value[16];
3949 char vht_value[16];
3950 char eht_value[16];
3951 struct params dat[3];
3952 wifi_band band = band_invalid;
developerfead3972023-05-25 20:15:02 +08003953 unsigned int bw = 20;
3954 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08003955
3956 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3957
3958 if(NULL == bandwidth)
3959 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003960 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003961
developerd1824452023-05-18 12:30:04 +08003962 if(strstr(bandwidth,"320") != NULL) {
3963 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
3964 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
3965 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developer262f4cb2023-05-24 12:22:04 +08003966 bw = 320;
developerd1824452023-05-18 12:30:04 +08003967 } else if(strstr(bandwidth,"160") != NULL) {
3968 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
3969 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
3970 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developer262f4cb2023-05-24 12:22:04 +08003971 bw = 160;
developerd1824452023-05-18 12:30:04 +08003972 } else if(strstr(bandwidth,"80") != NULL) {
3973 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
3974 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
3975 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developer262f4cb2023-05-24 12:22:04 +08003976 bw = 80;
developerd1824452023-05-18 12:30:04 +08003977 } else if(strstr(bandwidth,"40") != NULL) {
3978 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
3979 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
3980 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developerfead3972023-05-25 20:15:02 +08003981 bw = 40;
developerd1824452023-05-18 12:30:04 +08003982 } else if(strstr(bandwidth,"20") != NULL) {
3983 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
3984 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
3985 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developer262f4cb2023-05-24 12:22:04 +08003986 bw = 20;
developerd1824452023-05-18 12:30:04 +08003987 } else {
developer72fb0bb2023-01-11 09:46:29 +08003988 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
3989 return RETURN_ERR;
3990 }
3991
developerd1824452023-05-18 12:30:04 +08003992 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3993 dat[0].name = "HT_BW";
3994 dat[0].value = ht_value;
3995 dat[1].name = "VHT_BW";
3996 dat[1].value = vht_value;
3997 dat[2].name = "EHT_ApBw";
3998 dat[2].value = eht_value;
3999 wifi_datfileWrite(config_file, dat, 3);
developerfead3972023-05-25 20:15:02 +08004000 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
4001 if (ret != RETURN_OK) {
4002 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
4003 return RETURN_ERR;
4004 }
developer72fb0bb2023-01-11 09:46:29 +08004005
4006 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4007 return RETURN_OK;
4008}
4009
developer72fb0bb2023-01-11 09:46:29 +08004010//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
4011//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.
4012INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
4013{
4014 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004015 char config_dat_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004016 char mode_str[16] = {0};
4017 char buf[64] = {0};
developerd1824452023-05-18 12:30:04 +08004018 char cmd[MAX_CMD_SIZE] = {0};
4019 char interface_name[64] = {0};
4020 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08004021 wifi_band band;
developerd1824452023-05-18 12:30:04 +08004022 ULONG channel = 0;
4023 int centr_channel = 0;
developer72fb0bb2023-01-11 09:46:29 +08004024 UINT mode_map = 0;
developerd1824452023-05-18 12:30:04 +08004025 int freq=0;
developer72fb0bb2023-01-11 09:46:29 +08004026
4027 if (output_string == NULL)
4028 return RETURN_ERR;
4029
4030 wifi_getRadioMode(radioIndex, mode_str, &mode_map);
4031
4032 band = wifi_index_to_band(radioIndex);
4033 if (band == band_invalid)
4034 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004035 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4036 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004037
4038 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4039
4040 snprintf(output_string, 64, "Auto");
developer23e71282023-01-18 10:25:19 +08004041 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
developerd1824452023-05-18 12:30:04 +08004042 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
4043 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4044 wifi_halgetRadioExtChannel(config_dat_file, output_string);
developer23e71282023-01-18 10:25:19 +08004045 if (!(mode_map&WIFI_MODE_N))
developer72fb0bb2023-01-11 09:46:29 +08004046 snprintf(output_string, 64, "Auto");
4047 } else {
4048 // 5G and 6G band with ac or ax mode.
4049 wifi_getRadioChannel(radioIndex, &channel);
developerd1824452023-05-18 12:30:04 +08004050 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
4051
4052 ret = _syscmd(cmd, buf, sizeof(buf));
4053 len = strlen(buf);
4054 if((ret != 0) || (len == 0))
4055 {
4056 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4057 return RETURN_ERR;
4058 }
4059 sscanf(buf, "%d", &freq);
4060 centr_channel = ieee80211_frequency_to_channel(freq);
4061 if (centr_channel > (int)channel)
developer72fb0bb2023-01-11 09:46:29 +08004062 snprintf(output_string, 64, "AboveControlChannel");
4063 else
4064 snprintf(output_string, 64, "BelowControlChannel");
4065 }
4066
4067 return RETURN_OK;
4068}
4069
4070//Set the extension channel.
4071INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08004072{
developer72fb0bb2023-01-11 09:46:29 +08004073 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4074 struct params params={0};
4075 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004076 char config_dat_file[64] = {0};
4077 char ext_channel[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004078 char buf[128] = {0};
4079 char cmd[128] = {0};
4080 int max_radio_num =0, ret = 0, bandwidth = 0;
developer2f79c922023-06-02 17:33:42 +08004081 unsigned long channel = 0;
developer72fb0bb2023-01-11 09:46:29 +08004082 bool stbcEnable = FALSE;
4083 params.name = "ht_capab";
4084 wifi_band band;
4085
4086 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4087 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
4088 _syscmd(cmd, buf, sizeof(buf));
4089 if (strlen(buf) != 0)
4090 stbcEnable = TRUE;
4091 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
4092 return RETURN_ERR;
4093 bandwidth = strtol(buf, NULL, 10);
4094 // TDK expected to get error with 20MHz
developer262f4cb2023-05-24 12:22:04 +08004095 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
developer72fb0bb2023-01-11 09:46:29 +08004096 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
4097 return RETURN_ERR;
4098
4099 band = wifi_index_to_band(radioIndex);
4100 if (band == band_invalid)
4101 return RETURN_ERR;
4102
4103 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
4104 return RETURN_ERR;
4105
developer262f4cb2023-05-24 12:22:04 +08004106 snprintf(buf, sizeof(buf), "HT%d", bandwidth);
4107 ret = util_get_sec_chan_offset(channel, buf);
4108 if (ret == -EINVAL)
4109 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004110
4111 if(NULL!= strstr(string,"Above")) {
developer262f4cb2023-05-24 12:22:04 +08004112 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
4113 return RETURN_OK;
4114 strcpy(ext_channel, "Above");
developer72fb0bb2023-01-11 09:46:29 +08004115 } else if(NULL!= strstr(string,"Below")) {
developer262f4cb2023-05-24 12:22:04 +08004116 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
4117 return RETURN_OK;
4118 strcpy(ext_channel, "Below");
4119 } else {
developerd1824452023-05-18 12:30:04 +08004120 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08004121 return RETURN_ERR;
4122 }
developerd1824452023-05-18 12:30:04 +08004123 params.name = "HT_EXTCHA";
developer72fb0bb2023-01-11 09:46:29 +08004124 params.value = ext_channel;
4125
developerd1824452023-05-18 12:30:04 +08004126 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4127 wifi_datfileWrite(config_dat_file, &params, 1);
4128
developer72fb0bb2023-01-11 09:46:29 +08004129 wifi_getMaxRadioNumber(&max_radio_num);
4130 for(int i=0; i<=MAX_APS/max_radio_num; i++)
4131 {
4132 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
developer72fb0bb2023-01-11 09:46:29 +08004133 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
4134 }
4135
4136 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
4137 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4138 return RETURN_OK;
4139}
4140
4141//Get the guard interval value. eg "400nsec" or "800nsec"
4142//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.
4143INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
4144{
4145 wifi_guard_interval_t GI;
4146
4147 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4148
4149 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
4150 return RETURN_ERR;
4151
4152 if (GI == wifi_guard_interval_400)
4153 strcpy(output_string, "400nsec");
4154 else if (GI == wifi_guard_interval_800)
4155 strcpy(output_string, "800nsec");
4156 else if (GI == wifi_guard_interval_1600)
4157 strcpy(output_string, "1600nsec");
4158 else if (GI == wifi_guard_interval_3200)
4159 strcpy(output_string, "3200nsec");
4160 else
4161 strcpy(output_string, "Auto");
4162
4163 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4164 return RETURN_OK;
4165}
4166
4167//Set the guard interval value.
4168INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
4169{
4170 wifi_guard_interval_t GI;
4171 int ret = 0;
4172
4173 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4174
4175 if (strcmp(string, "400nsec") == 0)
4176 GI = wifi_guard_interval_400;
4177 else if (strcmp(string , "800nsec") == 0)
4178 GI = wifi_guard_interval_800;
4179 else if (strcmp(string , "1600nsec") == 0)
4180 GI = wifi_guard_interval_1600;
4181 else if (strcmp(string , "3200nsec") == 0)
4182 GI = wifi_guard_interval_3200;
4183 else
4184 GI = wifi_guard_interval_auto;
4185
4186 ret = wifi_setGuardInterval(radioIndex, GI);
4187
4188 if (ret == RETURN_ERR) {
4189 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
4190 return RETURN_ERR;
4191 }
4192
4193 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4194 return RETURN_OK;
4195}
4196
4197//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
4198INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
4199{
4200 char buf[32]={0};
4201 char mcs_file[64] = {0};
developerb149d9d2023-06-06 16:14:22 +08004202 char cmd[MAX_CMD_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +08004203 UINT mode_bitmap = 0;
developer72fb0bb2023-01-11 09:46:29 +08004204
4205 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4206 if(output_int == NULL)
4207 return RETURN_ERR;
4208 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4209
4210 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
4211 _syscmd(cmd, buf, sizeof(buf));
4212 if (strlen(buf) > 0)
4213 *output_int = strtol(buf, NULL, 10);
4214 else {
4215 // output the max MCS for the current radio mode
4216 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
4217 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
4218 return RETURN_ERR;
4219 }
4220 if (mode_bitmap & WIFI_MODE_AX) {
4221 *output_int = 11;
4222 } else if (mode_bitmap & WIFI_MODE_AC) {
4223 *output_int = 9;
4224 } else if (mode_bitmap & WIFI_MODE_N) {
4225 *output_int = 7;
4226 }
4227 }
4228 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4229
4230 return RETURN_OK;
4231}
4232
4233//Set the Modulation Coding Scheme index
4234INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
4235{
developera1255e42023-05-13 17:45:02 +08004236 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
4237 because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
developer72fb0bb2023-01-11 09:46:29 +08004238 char config_file[64] = {0};
4239 char set_value[16] = {0};
4240 char mcs_file[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004241 struct params set_config = {0};
4242 FILE *f = NULL;
developera1255e42023-05-13 17:45:02 +08004243 INT nss = 0;
4244 int ant_bitmap = 0;
4245 unsigned short cal_value = 0;
4246 UCHAR tval = 0, i = 0;
developer72fb0bb2023-01-11 09:46:29 +08004247
4248 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4249
4250 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4251
4252 // -1 means auto
4253 if (MCS > 15 || MCS < -1) {
4254 fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS);
4255 return RETURN_ERR;
4256 }
developera1255e42023-05-13 17:45:02 +08004257 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
4258 for(; ant_bitmap > 0; ant_bitmap >>= 1)
4259 nss += 1;
4260 //printf("%s:nss = %d\n", __func__, nss);
4261 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
4262 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
developer72fb0bb2023-01-11 09:46:29 +08004263 if (MCS > 9 || MCS == -1)
developera1255e42023-05-13 17:45:02 +08004264 tval = 2;/*one stream value*/
developer72fb0bb2023-01-11 09:46:29 +08004265 else if (MCS > 7)
developera1255e42023-05-13 17:45:02 +08004266 tval = 1;
developer72fb0bb2023-01-11 09:46:29 +08004267 else
developera1255e42023-05-13 17:45:02 +08004268 tval = 0;
4269 for (i = 0; i < nss; i++)
4270 cal_value |= (tval << (2*i));
4271 snprintf(set_value, sizeof(set_value), "%x", cal_value);
4272 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
4273 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
developer72fb0bb2023-01-11 09:46:29 +08004274 set_config.value = set_value;
4275
4276 wifi_hostapdWrite(config_file, &set_config, 1);
4277 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
4278
4279 // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
4280 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4281 f = fopen(mcs_file, "w");
4282 if (f == NULL) {
4283 fprintf(stderr, "%s: fopen failed\n", __func__);
4284 return RETURN_ERR;
4285 }
4286 fprintf(f, "%d", MCS);
4287 fclose(f);
4288
4289 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4290 return RETURN_OK;
4291}
4292
4293//Get supported Transmit Power list, eg : "0,25,50,75,100"
4294//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.
4295INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
4296{
4297 if (NULL == output_list)
4298 return RETURN_ERR;
4299 snprintf(output_list, 64,"0,25,50,75,100");
4300 return RETURN_OK;
4301}
4302
4303//Get current Transmit Power in dBm units.
4304//The transmite power level is in units of full power for this radio.
4305INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
4306{
4307 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +08004308 char cmd[MAX_CMD_SIZE]={0};
developer72fb0bb2023-01-11 09:46:29 +08004309 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08004310 char pwr_file[128]={0};
4311
developer72fb0bb2023-01-11 09:46:29 +08004312 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4313
4314 if(output_ulong == NULL)
4315 return RETURN_ERR;
4316
4317 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4318 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004319/*
developer72fb0bb2023-01-11 09:46:29 +08004320 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
4321 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004322 *output_ulong = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +08004323*/
4324 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4325 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
4326 _syscmd(cmd, buf, sizeof(buf));
4327 if (strlen(buf) > 0)
4328 *output_ulong = strtol(buf, NULL, 10);
4329 else
4330 *output_ulong = 100;
developer72fb0bb2023-01-11 09:46:29 +08004331 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4332 return RETURN_OK;
4333}
4334
4335//Set Transmit Power
4336//The transmite power level is in units of full power for this radio.
4337INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
4338{
4339 char interface_name[16] = {0};
4340 char *support;
developer72fb0bb2023-01-11 09:46:29 +08004341 char buf[128]={0};
4342 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08004343 char pwr_file[128]={0};
4344 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08004345 int if_idx, ret = 0;
4346 struct nl_msg *msg = NULL;
4347 struct nlattr * msg_data = NULL;
4348 struct mtk_nl80211_param param;
4349 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +08004350
4351 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4352
4353 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4354 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004355 // Get the Tx power supported list and check that is the input in the list
4356 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4357 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4358 support = strtok(buf, ",");
4359 while(true)
4360 {
4361 if(support == NULL) { // input not in the list
4362 wifi_dbg_printf("Input value is invalid.\n");
4363 return RETURN_ERR;
4364 }
4365 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4366 break;
4367 }
4368 support = strtok(NULL, ",");
4369 }
developerfead3972023-05-25 20:15:02 +08004370
4371 if_idx = if_nametoindex(interface_name);
4372 /*init mtk nl80211 vendor cmd*/
4373 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
4374 param.if_type = NL80211_ATTR_IFINDEX;
4375 param.if_idx = if_idx;
4376 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4377 if (ret) {
4378 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4379 return RETURN_ERR;
4380 }
4381 /*add mtk vendor cmd data*/
4382 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
4383 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4384 nlmsg_free(msg);
4385 goto err;
4386 }
4387
4388 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
4389 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4390 nlmsg_free(msg);
4391 goto err;
4392 }
4393
4394 /*send mtk nl80211 vendor msg*/
4395 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4396 if (ret) {
4397 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4398 goto err;
4399 }
4400 /*deinit mtk nl80211 vendor msg*/
4401 mtk_nl80211_deint(&unl_ins);
4402 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
4403
developera1255e42023-05-13 17:45:02 +08004404 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4405 f = fopen(pwr_file, "w");
4406 if (f == NULL) {
4407 fprintf(stderr, "%s: fopen failed\n", __func__);
4408 return RETURN_ERR;
4409 }
developerdaf24792023-06-06 11:40:04 +08004410 fprintf(f, "%lu", TransmitPower);
developera1255e42023-05-13 17:45:02 +08004411 fclose(f);
4412/* snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
developer72fb0bb2023-01-11 09:46:29 +08004413 _syscmd(cmd, buf, sizeof(buf));
4414 maximum_tx = strtol(buf, NULL, 10);
4415
4416 // Get the Tx power supported list and check that is the input in the list
4417 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4418 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4419 support = strtok(buf, ",");
4420 while(true)
4421 {
4422 if(support == NULL) { // input not in the list
4423 wifi_dbg_printf("Input value is invalid.\n");
4424 return RETURN_ERR;
4425 }
4426 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4427 break;
4428 }
4429 support = strtok(NULL, ",");
4430 }
4431 txpower = TransmitPower*maximum_tx/100;
4432 phyId = radio_index_to_phy(radioIndex);
4433 snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower);
4434 _syscmd(cmd, buf, sizeof(buf));
4435 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +08004436*/
4437 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004438err:
4439 mtk_nl80211_deint(&unl_ins);
4440 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4441 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004442}
4443
4444//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
4445INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
4446{
developer69b61b02023-03-07 17:17:44 +08004447 if (NULL == Supported)
developer72fb0bb2023-01-11 09:46:29 +08004448 return RETURN_ERR;
4449 *Supported = TRUE;
4450
4451 return RETURN_OK;
4452}
4453
4454//Get 80211h feature enable
4455INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
4456{
4457 char buf[64]={'\0'};
4458 char config_file[64] = {'\0'};
4459
4460 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4461 if(enable == NULL)
4462 return RETURN_ERR;
4463
4464 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
developerd1824452023-05-18 12:30:04 +08004465 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
4466 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004467
4468 if (strncmp(buf, "1", 1) == 0)
4469 *enable = TRUE;
4470 else
4471 *enable = FALSE;
4472
4473 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4474 return RETURN_OK;
4475}
4476
4477//Set 80211h feature enable
4478INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
4479{
4480 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4481 struct params params={'\0'};
developerd1824452023-05-18 12:30:04 +08004482 struct params dat={0};
developer72fb0bb2023-01-11 09:46:29 +08004483 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08004484 char config_dat_file[MAX_BUF_SIZE] = {0};
4485 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004486
4487 params.name = "ieee80211h";
4488
4489 if (enable) {
4490 params.value = "1";
4491 } else {
4492 params.value = "0";
4493 }
4494
developerd1824452023-05-18 12:30:04 +08004495 dat.name = "IEEE80211H";
4496 dat.value = params.value;
4497
4498 band = wifi_index_to_band(radioIndex);
4499 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4500 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer69b61b02023-03-07 17:17:44 +08004501
developerd1824452023-05-18 12:30:04 +08004502 wifi_hostapdWrite(config_file, &params, 1);
4503 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08004504 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4505 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4506 return RETURN_OK;
4507}
4508
4509//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.
4510INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
4511{
4512 if (NULL == output)
4513 return RETURN_ERR;
4514 *output=100;
4515
4516 return RETURN_OK;
4517}
4518
4519//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.
4520INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
4521{
4522 if (NULL == output)
4523 return RETURN_ERR;
4524 *output = -99;
4525
4526 return RETURN_OK;
4527}
4528
4529INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
4530{
4531 return RETURN_ERR;
4532}
4533
4534
4535//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
4536INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
4537{
4538 char interface_name[16] = {0};
4539 char cmd[MAX_BUF_SIZE]={'\0'};
4540 char buf[MAX_CMD_SIZE]={'\0'};
4541
4542 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4543 if(output == NULL)
4544 return RETURN_ERR;
4545
4546 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4547 return RETURN_ERR;
4548 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
4549 _syscmd(cmd, buf, sizeof(buf));
4550 *output = atoi(buf);
4551
4552 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4553 return RETURN_OK;
4554}
developer69b61b02023-03-07 17:17:44 +08004555
developer72fb0bb2023-01-11 09:46:29 +08004556INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
4557{
4558 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4559 struct params params={'\0'};
4560 char buf[MAX_BUF_SIZE] = {'\0'};
4561 char config_file[MAX_BUF_SIZE] = {'\0'};
4562
4563 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
4564 return RETURN_ERR;
4565
4566 params.name = "beacon_int";
4567 snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
4568 params.value = buf;
4569
4570 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4571 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08004572
developer72fb0bb2023-01-11 09:46:29 +08004573 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4574 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4575 return RETURN_OK;
4576}
4577
4578//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.
4579INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
4580{
4581 //TODO: need to revisit below implementation
4582 char *temp;
4583 char temp_output[128] = {0};
4584 char temp_TransmitRates[64] = {0};
4585 char config_file[64] = {0};
4586
4587 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4588 if (NULL == output)
4589 return RETURN_ERR;
4590 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4591 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08004592
developer72fb0bb2023-01-11 09:46:29 +08004593 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
4594 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
4595 } else {
4596 temp = strtok(temp_TransmitRates," ");
4597 while(temp!=NULL)
4598 {
4599 // Convert 100 kbps to Mbps
4600 temp[strlen(temp)-1]=0;
4601 if((temp[0]=='5') && (temp[1]=='\0'))
4602 {
4603 temp="5.5";
4604 }
4605 strcat(temp_output,temp);
4606 temp = strtok(NULL," ");
4607 if(temp!=NULL)
4608 {
4609 strcat(temp_output,",");
4610 }
4611 }
4612 strcpy(output,temp_output);
4613 }
4614 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4615 return RETURN_OK;
4616}
4617
4618INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
4619{
4620 char *temp;
4621 char temp1[128];
4622 char temp_output[128];
4623 char temp_TransmitRates[128];
4624 char set[128];
4625 char sub_set[128];
4626 int set_count=0,subset_count=0;
4627 int set_index=0,subset_index=0;
4628 char *token;
4629 int flag=0, i=0;
4630 struct params params={'\0'};
4631 char config_file[MAX_BUF_SIZE] = {0};
4632 wifi_band band = wifi_index_to_band(radioIndex);
4633
4634 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4635 if(NULL == TransmitRates)
4636 return RETURN_ERR;
4637 strcpy(sub_set,TransmitRates);
4638
4639 //Allow only supported Data transmit rate to be set
4640 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
4641 token = strtok(sub_set,",");
4642 while( token != NULL ) /* split the basic rate to be set, by comma */
4643 {
4644 sub_set[subset_count]=atoi(token);
4645 subset_count++;
4646 token=strtok(NULL,",");
4647 }
4648 token=strtok(set,",");
4649 while(token!=NULL) /* split the supported rate by comma */
4650 {
4651 set[set_count]=atoi(token);
4652 set_count++;
4653 token=strtok(NULL,",");
4654 }
4655 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
4656 {
4657 for(set_index=0;set_index < set_count;set_index++)
4658 {
4659 flag=0;
4660 if(sub_set[subset_index]==set[set_index])
4661 break;
4662 else
4663 flag=1; /* No match found */
4664 }
4665 if(flag==1)
4666 return RETURN_ERR; //If value not found return Error
4667 }
4668 strcpy(temp_TransmitRates,TransmitRates);
4669
4670 for(i=0;i<strlen(temp_TransmitRates);i++)
4671 {
4672 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
4673 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
4674 {
4675 continue;
4676 }
4677 else
4678 {
4679 return RETURN_ERR;
4680 }
4681 }
4682 strcpy(temp_output,"");
4683 temp = strtok(temp_TransmitRates,",");
4684 while(temp!=NULL)
4685 {
4686 strcpy(temp1,temp);
4687 if(band == band_5)
4688 {
4689 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
4690 {
4691 return RETURN_ERR;
4692 }
4693 }
4694
4695 if(strcmp(temp,"5.5")==0)
4696 {
4697 strcpy(temp1,"55");
4698 }
4699 else
4700 {
4701 strcat(temp1,"0");
4702 }
4703 strcat(temp_output,temp1);
4704 temp = strtok(NULL,",");
4705 if(temp!=NULL)
4706 {
4707 strcat(temp_output," ");
4708 }
4709 }
4710 strcpy(TransmitRates,temp_output);
4711
4712 params.name= "basic_rates";
4713 params.value =TransmitRates;
4714
4715 wifi_dbg_printf("\n%s:",__func__);
4716 wifi_dbg_printf("\nparams.value=%s\n",params.value);
4717 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
4718 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4719 wifi_hostapdWrite(config_file,&params,1);
4720 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4721 return RETURN_OK;
4722}
4723
4724//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
4725INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
4726{
4727 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4728 FILE *fp = NULL;
4729 char path[256] = {0}, output_string[256] = {0};
4730 int count = 0;
4731 char *interface = NULL;
4732
4733 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
4734 if (fp == NULL)
4735 {
4736 printf("Failed to run command in Function %s\n", __FUNCTION__);
4737 return RETURN_ERR;
4738 }
4739 if (fgets(path, sizeof(path) - 1, fp) != NULL)
4740 {
4741 interface = strchr(path, '=');
4742
4743 if (interface != NULL)
4744 {
4745 strcpy(output_string, interface + 1);
4746 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
4747 interface_name[count] = output_string[count];
4748
4749 interface_name[count] = '\0';
4750 }
4751 }
4752 pclose(fp);
4753 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4754 return RETURN_OK;
4755}
4756
4757INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
4758{
4759 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4760 output_struct->radio_BytesSent = 0;
4761 output_struct->radio_BytesReceived = 0;
4762 output_struct->radio_PacketsSent = 0;
4763 output_struct->radio_PacketsReceived = 0;
4764 output_struct->radio_ErrorsSent = 0;
4765 output_struct->radio_ErrorsReceived = 0;
4766 output_struct->radio_DiscardPacketsSent = 0;
4767 output_struct->radio_DiscardPacketsReceived = 0;
4768 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4769 return RETURN_OK;
4770}
4771
4772
4773INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
4774{
4775 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4776 CHAR buf[MAX_CMD_SIZE] = {0};
4777 CHAR Value[MAX_BUF_SIZE] = {0};
4778 FILE *fp = NULL;
4779
4780 if (ifname == NULL || strlen(ifname) <= 1)
4781 return RETURN_OK;
4782
4783 snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
4784 system(buf);
4785
4786 fp = fopen("/tmp/Radio_Stats.txt", "r");
4787 if(fp == NULL)
4788 {
4789 printf("/tmp/Radio_Stats.txt not exists \n");
4790 return RETURN_ERR;
4791 }
4792 fclose(fp);
4793
4794 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4795 File_Reading(buf, Value);
4796 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
4797
4798 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4799 File_Reading(buf, Value);
4800 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
4801
4802 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
4803 File_Reading(buf, Value);
4804 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
4805
4806 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4807 File_Reading(buf, Value);
4808 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
4809
4810 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4811 File_Reading(buf, Value);
4812 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
4813
4814 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
4815 File_Reading(buf, Value);
4816 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
4817
4818 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4819 File_Reading(buf, Value);
4820 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
4821
4822 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
4823 File_Reading(buf, Value);
4824 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
4825
4826 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4827 return RETURN_OK;
4828}
4829
4830INT GetIfacestatus(CHAR *interface_name, CHAR *status)
4831{
developer7e4a2a62023-04-06 19:56:03 +08004832 CHAR buf[MAX_CMD_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004833
developer7e4a2a62023-04-06 19:56:03 +08004834 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4835
4836 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
4837 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
4838 File_Reading(buf, status);
4839 }
4840
4841 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4842 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004843}
4844
4845//Get detail radio traffic static info
4846INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
4847{
4848
developer69b61b02023-03-07 17:17:44 +08004849#if 0
4850 //ifconfig radio_x
developer72fb0bb2023-01-11 09:46:29 +08004851 output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters.
4852 output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters.
4853 output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface.
4854 output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface.
4855
4856 output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors.
4857 output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
4858 output_struct->radio_DiscardPacketsSent=0; //The total number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space.
4859 output_struct->radio_DiscardPacketsReceived=0; //The total number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being delivered. One possible reason for discarding such a packet could be to free up buffer space.
4860
developer69b61b02023-03-07 17:17:44 +08004861 output_struct->radio_PLCPErrorCount=0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
developer72fb0bb2023-01-11 09:46:29 +08004862 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].
4863 output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error.
4864 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.
4865 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
4866 output_struct->radio_ChannelUtilization=35; //Percentage of time the channel was occupied by the radios 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
4867 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
4868 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
4869 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
4870
4871 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
4872 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
4873 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
4874 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.
4875
4876 return RETURN_OK;
4877#endif
4878
4879 CHAR interface_name[64] = {0};
4880 BOOL iface_status = FALSE;
4881 wifi_radioTrafficStats2_t radioTrafficStats = {0};
4882
4883 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
4884 if (NULL == output_struct)
4885 return RETURN_ERR;
4886
4887 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4888 return RETURN_ERR;
4889
4890 wifi_getApEnable(radioIndex, &iface_status);
4891
4892 if (iface_status == TRUE)
4893 wifi_halGetIfStats(interface_name, &radioTrafficStats);
4894 else
4895 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
4896
4897 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
4898 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
4899 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
4900 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
4901 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
4902 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
4903 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
4904 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
4905
4906 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
4907 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].
4908 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
4909 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.
4910 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
4911 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
4912 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
4913 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
4914 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
4915
4916 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
4917 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
4918 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
4919 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.
4920
4921 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
4922
4923 return RETURN_OK;
4924}
4925
4926//Set radio traffic static Measureing rules
4927INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
4928{
4929 //zqiu: If the RadioTrafficStats process running, and the new value is different from old value, the process needs to be reset. The Statistics date, such as MaximumNoiseFloorOnChannel, MinimumNoiseFloorOnChannel and MedianNoiseFloorOnChannel need to be reset. And the "StatisticsStartTime" must be reset to the current time. Units in Seconds
4930 // Else, save the MeasuringRate and MeasuringInterval for future usage
4931
4932 return RETURN_OK;
4933}
4934
4935//To start or stop RadioTrafficStats
4936INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
4937{
4938 //zqiu: If the RadioTrafficStats process running
4939 // if(enable)
4940 // return RETURN_OK.
4941 // else
4942 // Stop RadioTrafficStats process
developer69b61b02023-03-07 17:17:44 +08004943 // Else
developer72fb0bb2023-01-11 09:46:29 +08004944 // if(enable)
4945 // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds
4946 // else
4947 // return RETURN_OK.
4948
4949 return RETURN_OK;
4950}
4951
4952//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
4953INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
4954{
4955 //zqiu: Please ignor signalIndex.
developer69b61b02023-03-07 17:17:44 +08004956 if (NULL == SignalLevel)
developer72fb0bb2023-01-11 09:46:29 +08004957 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08004958
developer72fb0bb2023-01-11 09:46:29 +08004959 *SignalLevel=(radioIndex==0)?-19:-19;
4960
4961 return RETURN_OK;
4962}
4963
4964//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
4965INT wifi_applyRadioSettings(INT radioIndex)
4966{
4967 return RETURN_OK;
4968}
4969
4970//Get the radio index assocated with this SSID entry
4971INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
4972{
4973 if(NULL == radioIndex)
4974 return RETURN_ERR;
4975 int max_radio_num = 0;
4976 wifi_getMaxRadioNumber(&max_radio_num);
4977 *radioIndex = ssidIndex%max_radio_num;
4978 return RETURN_OK;
4979}
4980
4981//Device.WiFi.SSID.{i}.Enable
4982//Get SSID enable configuration parameters (not the SSID enable status)
4983INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
4984{
developer69b61b02023-03-07 17:17:44 +08004985 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08004986 return RETURN_ERR;
4987
4988 return wifi_getApEnable(ssidIndex, output_bool);
4989}
4990
4991//Device.WiFi.SSID.{i}.Enable
4992//Set SSID enable configuration parameters
4993INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
4994{
4995 return wifi_setApEnable(ssidIndex, enable);
4996}
4997
4998//Device.WiFi.SSID.{i}.Status
4999//Get the SSID enable status
5000INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
5001{
developer72fb0bb2023-01-11 09:46:29 +08005002 BOOL output_bool;
5003
5004 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5005 if (NULL == output_string)
5006 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08005007
developer72fb0bb2023-01-11 09:46:29 +08005008 wifi_getApEnable(ssidIndex,&output_bool);
5009 snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
5010
5011 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5012 return RETURN_OK;
5013}
5014
5015// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
5016INT wifi_getSSIDName(INT apIndex, CHAR *output)
5017{
5018 char config_file[MAX_BUF_SIZE] = {0};
5019
developer69b61b02023-03-07 17:17:44 +08005020 if (NULL == output)
developer72fb0bb2023-01-11 09:46:29 +08005021 return RETURN_ERR;
5022
5023 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5024 wifi_hostapdRead(config_file,"ssid",output,32);
5025
5026 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
5027 return RETURN_OK;
5028}
5029
developer69b61b02023-03-07 17:17:44 +08005030// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08005031INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
5032{
developer72fb0bb2023-01-11 09:46:29 +08005033 struct params params;
5034 char config_file[MAX_BUF_SIZE] = {0};
5035
5036 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5037 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
5038 return RETURN_ERR;
5039
5040 params.name = "ssid";
5041 params.value = ssid_string;
5042 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5043 wifi_hostapdWrite(config_file, &params, 1);
5044 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5045 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5046
5047 return RETURN_OK;
5048}
5049
5050//Get the BSSID
5051INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
5052{
developer7e4a2a62023-04-06 19:56:03 +08005053 char cmd[MAX_CMD_SIZE] = {0};
5054 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005055
developer7e4a2a62023-04-06 19:56:03 +08005056 if (!output_string)
developerdaf24792023-06-06 11:40:04 +08005057 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08005058
developer47cc27a2023-05-17 23:09:58 +08005059 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
5060 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08005061
developer5b2f10c2023-05-25 17:02:21 +08005062 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
5063 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
5064 strncpy(output_string, "\0", 1);
5065 return RETURN_ERR;
5066 }
5067 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
5068 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08005069
developer5b2f10c2023-05-25 17:02:21 +08005070 /* if hostapd does not control interface even if this interface has been brought up,
5071 * try to get its mac address by iw command.
5072 */
5073 if(strlen(output_string) == 0) {
5074 memset(cmd, 0, sizeof(cmd));
5075 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
5076 _syscmd(cmd, output_string, 64);
5077 }
developer72fb0bb2023-01-11 09:46:29 +08005078
developer5b2f10c2023-05-25 17:02:21 +08005079 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005080}
5081
5082//Get the MAC address associated with this Wifi SSID
5083INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
5084{
5085 wifi_getBaseBSSID(ssidIndex,output_string);
5086 return RETURN_OK;
5087}
5088
5089//Get the basic SSID traffic static info
5090//Apply SSID and AP (in the case of Acess Point devices) to the hardware
5091//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5092INT wifi_applySSIDSettings(INT ssidIndex)
5093{
5094 char interface_name[16] = {0};
5095 BOOL status = false;
5096 char cmd[MAX_CMD_SIZE] = {0};
5097 char buf[MAX_CMD_SIZE] = {0};
5098 int apIndex, ret;
5099 int max_radio_num = 0;
5100 int radioIndex = 0;
5101
5102 wifi_getMaxRadioNumber(&max_radio_num);
5103
5104 radioIndex = ssidIndex % max_radio_num;
5105
5106 wifi_getApEnable(ssidIndex,&status);
5107 // Do not apply when ssid index is disabled
5108 if (status == false)
5109 return RETURN_OK;
5110
5111 /* Doing full remove and add for ssid Index
5112 * Not all hostapd options are supported with reload
5113 * for example macaddr_acl
5114 */
5115 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
5116 return RETURN_ERR;
5117
5118 ret = wifi_setApEnable(ssidIndex,true);
5119
5120 /* Workaround for hostapd issue with multiple bss definitions
5121 * when first created interface will be removed
5122 * then all vaps other vaps on same phy are removed
5123 * after calling setApEnable to false readd all enabled vaps */
5124 for(int i=0; i < MAX_APS/max_radio_num; i++) {
5125 apIndex = max_radio_num*i+radioIndex;
5126 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5127 return RETURN_ERR;
5128 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
5129 _syscmd(cmd, buf, sizeof(buf));
5130 if(*buf == '1')
5131 wifi_setApEnable(apIndex, true);
5132 }
5133
5134 return ret;
5135}
5136
5137struct channels_noise {
5138 int channel;
5139 int noise;
5140};
5141
5142// Return noise array for each channel
5143int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
5144{
5145 char interface_name[16] = {0};
5146 FILE *f = NULL;
5147 char cmd[128] = {0};
5148 char line[256] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005149 int tmp = 0, arr_index = -1;
5150
5151 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5152 return RETURN_ERR;
5153 sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
5154
5155 if ((f = popen(cmd, "r")) == NULL) {
5156 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5157 return RETURN_ERR;
5158 }
developer69b61b02023-03-07 17:17:44 +08005159
developer72fb0bb2023-01-11 09:46:29 +08005160 while(fgets(line, sizeof(line), f) != NULL) {
5161 if(arr_index < channels_num){
5162 sscanf(line, "%d", &tmp);
5163 if (tmp > 0) { // channel frequency, the first line must be frequency
5164 arr_index++;
5165 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
5166 } else { // noise
5167 channels_noise_arr[arr_index].noise = tmp;
5168 }
5169 }else{
5170 break;
5171 }
5172 }
5173 pclose(f);
5174 return RETURN_OK;
5175}
5176
5177//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
5178//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08005179INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08005180{
5181 int index = -1;
5182 wifi_neighbor_ap2_t *scan_array = NULL;
5183 char cmd[256]={0};
5184 char buf[128]={0};
5185 char file_name[32] = {0};
5186 char filter_SSID[32] = {0};
5187 char line[256] = {0};
5188 char interface_name[16] = {0};
5189 char *ret = NULL;
5190 int freq=0;
5191 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +08005192 int channels_num = 0;
5193 int vht_channel_width = 0;
5194 int get_noise_ret = RETURN_ERR;
5195 bool filter_enable = false;
5196 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
5197 int phyId = 0;
5198
5199 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
5200
5201 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5202 return RETURN_ERR;
5203
5204 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
5205 f = fopen(file_name, "r");
5206 if (f != NULL) {
developer47a56bf2023-05-30 13:38:57 +08005207 fgets(buf, sizeof(file_name), f);
5208 if ((strncmp(buf, "0", 1)) != 0) {
5209 fgets(filter_SSID, sizeof(file_name), f);
5210 if (strlen(filter_SSID) != 0)
5211 filter_enable = true;
5212 }
developer72fb0bb2023-01-11 09:46:29 +08005213 fclose(f);
5214 }
5215
5216 phyId = radio_index_to_phy(radioIndex);
5217 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
5218 _syscmd(cmd, buf, sizeof(buf));
5219 channels_num = strtol(buf, NULL, 10);
5220
5221
5222
5223 sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
5224 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
5225 fprintf(stderr, "cmd: %s\n", cmd);
5226 if ((f = popen(cmd, "r")) == NULL) {
5227 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5228 return RETURN_ERR;
5229 }
developer69b61b02023-03-07 17:17:44 +08005230
developer72fb0bb2023-01-11 09:46:29 +08005231 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
5232 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08005233
developer72fb0bb2023-01-11 09:46:29 +08005234 ret = fgets(line, sizeof(line), f);
5235 while (ret != NULL) {
5236 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +08005237 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
developer72fb0bb2023-01-11 09:46:29 +08005238 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
5239 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
5240
5241 if (!filter_BSS) {
5242 index++;
5243 wifi_neighbor_ap2_t *tmp;
5244 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
5245 if (tmp == NULL) { // no more memory to use
5246 index--;
5247 wifi_dbg_printf("%s: realloc failed\n", __func__);
5248 break;
5249 }
5250 scan_array = tmp;
5251 }
5252 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5253
5254 filter_BSS = false;
5255 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
developerc79e9172023-06-06 19:48:03 +08005256 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
5257 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
5258 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
5259 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
5260 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
5261 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
developer72fb0bb2023-01-11 09:46:29 +08005262 } else if (strstr(line, "freq") != NULL) {
5263 sscanf(line," freq: %d", &freq);
5264 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
5265
5266 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +08005267 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
5268 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
5269 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
5270 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
5271 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
5272 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
developer72fb0bb2023-01-11 09:46:29 +08005273 }
5274 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +08005275 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
5276 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
5277 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
5278 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
5279 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
5280 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
developer72fb0bb2023-01-11 09:46:29 +08005281 }
5282
5283 scan_array[index].ap_Noise = 0;
5284 if (get_noise_ret == RETURN_OK) {
5285 for (int i = 0; i < channels_num; i++) {
5286 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
5287 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
5288 break;
5289 }
5290 }
5291 }
5292 } else if (strstr(line, "beacon interval") != NULL) {
5293 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
5294 } else if (strstr(line, "signal") != NULL) {
5295 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
5296 } else if (strstr(line,"SSID") != NULL) {
5297 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
5298 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
5299 filter_BSS = true;
5300 }
5301 } else if (strstr(line, "Supported rates") != NULL) {
5302 char SRate[80] = {0}, *tmp = NULL;
5303 memset(buf, 0, sizeof(buf));
5304 strcpy(SRate, line);
5305 tmp = strtok(SRate, ":");
5306 tmp = strtok(NULL, ":");
5307 strcpy(buf, tmp);
5308 memset(SRate, 0, sizeof(SRate));
5309
5310 tmp = strtok(buf, " \n");
5311 while (tmp != NULL) {
5312 strcat(SRate, tmp);
5313 if (SRate[strlen(SRate) - 1] == '*') {
5314 SRate[strlen(SRate) - 1] = '\0';
5315 }
5316 strcat(SRate, ",");
5317
5318 tmp = strtok(NULL, " \n");
5319 }
5320 SRate[strlen(SRate) - 1] = '\0';
5321 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
5322 } else if (strstr(line, "DTIM") != NULL) {
developer49c83812023-06-06 14:23:53 +08005323 sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod));
developer72fb0bb2023-01-11 09:46:29 +08005324 } else if (strstr(line, "VHT capabilities") != NULL) {
5325 strcat(scan_array[index].ap_SupportedStandards, ",ac");
5326 strcpy(scan_array[index].ap_OperatingStandards, "ac");
5327 } else if (strstr(line, "HT capabilities") != NULL) {
5328 strcat(scan_array[index].ap_SupportedStandards, ",n");
5329 strcpy(scan_array[index].ap_OperatingStandards, "n");
5330 } else if (strstr(line, "VHT operation") != NULL) {
5331 ret = fgets(line, sizeof(line), f);
5332 sscanf(line," * channel width: %d", &vht_channel_width);
5333 if(vht_channel_width == 1) {
5334 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
5335 } else {
5336 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
5337 }
5338 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5339 continue;
5340 } else if (strstr(line, "HT operation") != NULL) {
5341 ret = fgets(line, sizeof(line), f);
developerdaf24792023-06-06 11:40:04 +08005342 sscanf(line," * secondary channel offset: %s", buf);
developer72fb0bb2023-01-11 09:46:29 +08005343 if (!strcmp(buf, "above")) {
5344 //40Mhz +
5345 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
5346 }
5347 else if (!strcmp(buf, "below")) {
5348 //40Mhz -
5349 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
5350 } else {
5351 //20Mhz
5352 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
5353 }
5354 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5355 continue;
5356 } else if (strstr(line, "HE capabilities") != NULL) {
5357 strcat(scan_array[index].ap_SupportedStandards, ",ax");
5358 strcpy(scan_array[index].ap_OperatingStandards, "ax");
5359 ret = fgets(line, sizeof(line), f);
5360 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
5361 if (strstr(line, "HE40/2.4GHz") != NULL)
5362 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
5363 else
5364 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
5365 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
5366 if (strstr(line, "HE80/5GHz") != NULL) {
5367 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
5368 ret = fgets(line, sizeof(line), f);
5369 } else
5370 continue;
5371 if (strstr(line, "HE160/5GHz") != NULL)
5372 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
5373 }
5374 continue;
5375 } else if (strstr(line, "WPA") != NULL) {
5376 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
5377 } else if (strstr(line, "RSN") != NULL) {
5378 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
5379 } else if (strstr(line, "Group cipher") != NULL) {
5380 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
5381 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
5382 strcpy(scan_array[index].ap_EncryptionMode, "AES");
5383 }
5384 }
5385 ret = fgets(line, sizeof(line), f);
5386 }
5387
5388 if (!filter_BSS) {
5389 *output_array_size = index + 1;
5390 } else {
5391 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5392 *output_array_size = index;
5393 }
5394 *neighbor_ap_array = scan_array;
5395 pclose(f);
5396 free(channels_noise_arr);
5397 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5398 return RETURN_OK;
5399}
5400
5401//>> Deprecated: used for old RDKB code.
5402INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
5403{
5404 INT status = RETURN_ERR;
5405
5406 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5407 output_struct->wifi_PLCPErrorCount = 0;
5408 output_struct->wifi_FCSErrorCount = 0;
5409 output_struct->wifi_InvalidMACCount = 0;
5410 output_struct->wifi_PacketsOtherReceived = 0;
5411 output_struct->wifi_Noise = 0;
5412 status = RETURN_OK;
5413 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5414 return status;
5415}
5416
5417INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
5418{
5419 char interface_name[16] = {0};
5420 char cmd[128] = {0};
5421 char buf[1280] = {0};
5422 char *pos = NULL;
5423
5424 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5425 if (NULL == output_struct)
5426 return RETURN_ERR;
5427
5428 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5429 return RETURN_ERR;
5430
5431 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5432
5433 snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
5434 _syscmd(cmd, buf, sizeof(buf));
5435
5436 pos = buf;
5437 if ((pos = strstr(pos, "RX packets:")) == NULL)
5438 return RETURN_ERR;
5439 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
5440
5441 if ((pos = strstr(pos, "TX packets:")) == NULL)
5442 return RETURN_ERR;
5443 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
5444
5445 if ((pos = strstr(pos, "RX bytes:")) == NULL)
5446 return RETURN_ERR;
5447 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
5448
5449 if ((pos = strstr(pos, "TX bytes:")) == NULL)
5450 return RETURN_ERR;
5451 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
5452
5453 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
5454 _syscmd(cmd, buf, sizeof(buf));
5455 sscanf(buf, "%lu", &output_struct->wifi_Associations);
5456
5457#if 0
5458 //TODO: need to revisit below implementation
5459 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5460 char interface_name[MAX_BUF_SIZE] = {0};
5461 char interface_status[MAX_BUF_SIZE] = {0};
5462 char Value[MAX_BUF_SIZE] = {0};
5463 char buf[MAX_CMD_SIZE] = {0};
5464 char cmd[MAX_CMD_SIZE] = {0};
5465 FILE *fp = NULL;
5466
5467 if (NULL == output_struct) {
5468 return RETURN_ERR;
5469 }
5470
5471 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5472
5473 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
5474 {
5475 if(apIndex == 0) //private_wifi for 2.4G
5476 {
5477 wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
5478 }
5479 else if(apIndex == 1) //private_wifi for 5G
5480 {
5481 wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
5482 }
5483 else if(apIndex == 4) //public_wifi for 2.4G
5484 {
5485 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
5486 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
5487 {
5488 return RETURN_ERR;
5489 }
5490 if(buf[0] == '#')//tp-link
5491 wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
5492 else//tenda
5493 wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name);
5494 }
5495 else if(apIndex == 5) //public_wifi for 5G
5496 {
5497 wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
5498 }
5499
5500 GetIfacestatus(interface_name, interface_status);
5501
5502 if(0 != strcmp(interface_status, "1"))
5503 return RETURN_ERR;
5504
5505 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5506 system(cmd);
5507
5508 fp = fopen("/tmp/SSID_Stats.txt", "r");
5509 if(fp == NULL)
5510 {
5511 printf("/tmp/SSID_Stats.txt not exists \n");
5512 return RETURN_ERR;
5513 }
5514 fclose(fp);
5515
5516 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5517 File_Reading(buf, Value);
5518 output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10);
5519
5520 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5521 File_Reading(buf, Value);
5522 output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10);
5523
5524 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5525 File_Reading(buf, Value);
5526 output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10);
5527
5528 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5529 File_Reading(buf, Value);
5530 output_struct->wifi_BytesSent = strtoul(Value, NULL, 10);
5531
5532 /* There is no specific parameter from caller to associate the value wifi_Associations */
5533 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);
5534 //_syscmd(cmd, buf, sizeof(buf));
5535 //sscanf(buf,"%lu", &output_struct->wifi_Associations);
5536 }
5537#endif
5538 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5539 return RETURN_OK;
5540}
5541
5542INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
5543{
developerb149d9d2023-06-06 16:14:22 +08005544 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005545 char interface_status[MAX_BUF_SIZE] = {0};
5546 char Value[MAX_BUF_SIZE] = {0};
5547 char buf[MAX_CMD_SIZE] = {0};
5548 char cmd[MAX_CMD_SIZE] = {0};
5549 FILE *fp = NULL;
5550
5551 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5552 if (NULL == output_struct)
5553 return RETURN_ERR;
5554
5555 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
5556
5557 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
5558 return RETURN_ERR;
5559 GetIfacestatus(interface_name, interface_status);
5560
5561 if(0 != strcmp(interface_status, "1"))
5562 return RETURN_ERR;
5563
5564 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5565 system(cmd);
5566
5567 fp = fopen("/tmp/SSID_Stats.txt", "r");
5568 if(fp == NULL)
5569 {
5570 printf("/tmp/SSID_Stats.txt not exists \n");
5571 return RETURN_ERR;
5572 }
5573 fclose(fp);
5574
5575 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5576 File_Reading(buf, Value);
5577 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
5578
5579 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5580 File_Reading(buf, Value);
5581 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
5582
5583 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5584 File_Reading(buf, Value);
5585 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
5586
5587 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5588 File_Reading(buf, Value);
5589 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
5590
5591 output_struct->wifi_UnicastPacketsSent = 0;
5592 output_struct->wifi_UnicastPacketsReceived = 0;
5593 output_struct->wifi_MulticastPacketsSent = 0;
5594 output_struct->wifi_MulticastPacketsReceived = 0;
5595 output_struct->wifi_BroadcastPacketsSent = 0;
5596 output_struct->wifi_BroadcastPacketsRecevied = 0;
5597 output_struct->wifi_UnknownPacketsReceived = 0;
5598
5599 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5600 return RETURN_OK;
5601}
5602
5603INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
5604{
5605 INT status = RETURN_ERR;
5606
5607 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5608 //Below values should get updated from hal
5609 output_struct->wifi_RetransCount=0;
5610 output_struct->wifi_FailedRetransCount=0;
5611 output_struct->wifi_RetryCount=0;
5612 output_struct->wifi_MultipleRetryCount=0;
5613 output_struct->wifi_ACKFailureCount=0;
5614 output_struct->wifi_AggregatedPacketCount=0;
5615
5616 status = RETURN_OK;
5617 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5618
5619 return status;
5620}
5621
5622INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
5623{
5624 INT status = RETURN_ERR;
5625 UINT index;
5626 wifi_neighbor_ap_t *pt=NULL;
5627
5628 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5629 *output_array_size=2;
5630 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
5631 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
5632 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
5633 strcpy(pt->ap_Radio,"");
5634 strcpy(pt->ap_SSID,"");
5635 strcpy(pt->ap_BSSID,"");
5636 strcpy(pt->ap_Mode,"");
5637 pt->ap_Channel=1;
5638 pt->ap_SignalStrength=0;
5639 strcpy(pt->ap_SecurityModeEnabled,"");
5640 strcpy(pt->ap_EncryptionMode,"");
5641 strcpy(pt->ap_OperatingFrequencyBand,"");
5642 strcpy(pt->ap_SupportedStandards,"");
5643 strcpy(pt->ap_OperatingStandards,"");
5644 strcpy(pt->ap_OperatingChannelBandwidth,"");
5645 pt->ap_BeaconPeriod=1;
5646 pt->ap_Noise=0;
5647 strcpy(pt->ap_BasicDataTransferRates,"");
5648 strcpy(pt->ap_SupportedDataTransferRates,"");
5649 pt->ap_DTIMPeriod=1;
5650 pt->ap_ChannelUtilization = 1;
5651 }
5652
5653 status = RETURN_OK;
5654 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5655
5656 return status;
5657}
5658
5659//----------------- AP HAL -------------------------------
5660
5661//>> Deprecated: used for old RDKB code.
5662INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
5663{
5664 if (NULL == output_ulong || NULL == output_struct)
5665 return RETURN_ERR;
5666 *output_ulong = 0;
5667 *output_struct = NULL;
5668 return RETURN_OK;
5669}
5670
5671#ifdef HAL_NETLINK_IMPL
5672static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
5673 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5674 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5675 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
5676 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
5677 char mac_addr[20];
5678 static int count=0;
5679 int rate=0;
5680
5681 wifi_device_info_t *out = (wifi_device_info_t*)arg;
5682
5683 nla_parse(tb,
5684 NL80211_ATTR_MAX,
5685 genlmsg_attrdata(gnlh, 0),
5686 genlmsg_attrlen(gnlh, 0),
5687 NULL);
5688
5689 if(!tb[NL80211_ATTR_STA_INFO]) {
5690 fprintf(stderr, "sta stats missing!\n");
5691 return NL_SKIP;
5692 }
5693
5694
5695 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
5696 fprintf(stderr, "failed to parse nested attributes!\n");
5697 return NL_SKIP;
5698 }
5699
5700 //devIndex starts from 1
5701 if( ++count == out->wifi_devIndex )
5702 {
5703 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
5704 //Getting the mac addrress
5705 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
5706
5707 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
5708 fprintf(stderr, "failed to parse nested rate attributes!");
5709 return NL_SKIP;
5710 }
5711
5712 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
developerdaf24792023-06-06 11:40:04 +08005713 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
developer72fb0bb2023-01-11 09:46:29 +08005714 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5715 out->wifi_devTxRate = rate/10;
developerdaf24792023-06-06 11:40:04 +08005716 }
developer72fb0bb2023-01-11 09:46:29 +08005717 }
5718
5719 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
5720 fprintf(stderr, "failed to parse nested rate attributes!");
5721 return NL_SKIP;
5722 }
5723
5724 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
developerdaf24792023-06-06 11:40:04 +08005725 if(rinfo[NL80211_RATE_INFO_BITRATE]) {
developer72fb0bb2023-01-11 09:46:29 +08005726 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5727 out->wifi_devRxRate = rate/10;
developerdaf24792023-06-06 11:40:04 +08005728 }
developer72fb0bb2023-01-11 09:46:29 +08005729 }
5730 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
5731 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
5732
5733 out->wifi_devAssociatedDeviceAuthentiationState = 1;
5734 count = 0; //starts the count for next cycle
5735 return NL_STOP;
5736 }
5737
5738 return NL_SKIP;
5739
5740}
5741#endif
5742
5743INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
5744{
5745#ifdef HAL_NETLINK_IMPL
5746 Netlink nl = {0};
developerb149d9d2023-06-06 16:14:22 +08005747 char if_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005748 char interface_name[16] = {0};
5749
5750 wifi_device_info_t info = {0};
5751 info.wifi_devIndex = devIndex;
5752
5753 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5754 return RETURN_ERR;
5755
5756 snprintf(if_name,sizeof(if_name),"%s", interface_name);
5757
5758 nl.id = initSock80211(&nl);
5759
5760 if (nl.id < 0) {
5761 fprintf(stderr, "Error initializing netlink \n");
5762 return -1;
5763 }
5764
5765 struct nl_msg* msg = nlmsg_alloc();
5766
5767 if (!msg) {
5768 fprintf(stderr, "Failed to allocate netlink message.\n");
5769 nlfree(&nl);
5770 return -2;
5771 }
5772
5773 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +08005774 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +08005775 NL_AUTO_SEQ,
5776 nl.id,
5777 0,
5778 NLM_F_DUMP,
5779 NL80211_CMD_GET_STATION,
5780 0);
5781
5782 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +08005783 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +08005784 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
5785 nl_recvmsgs(nl.socket, nl.cb);
5786 nlmsg_free(msg);
5787 nlfree(&nl);
5788
5789 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
5790 output_struct->wifi_devRxRate = info.wifi_devRxRate;
5791 output_struct->wifi_devTxRate = info.wifi_devTxRate;
5792 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
5793 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
5794 return RETURN_OK;
5795#else
5796 //iw utility to retrieve station information
5797#define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt"
5798#define SIGNALFILE "/tmp/wifi_signalstrength.txt"
5799#define MACFILE "/tmp/wifi_AssoMac.txt"
5800#define TXRATEFILE "/tmp/wifi_txrate.txt"
5801#define RXRATEFILE "/tmp/wifi_rxrate.txt"
5802 FILE *file = NULL;
5803 char if_name[10] = {'\0'};
5804 char pipeCmd[256] = {'\0'};
5805 char line[256] = {0};
5806 char interface_name[16] = {0};
5807 int count = 0, device = 0;
5808
5809 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5810 return RETURN_ERR;
5811
5812 snprintf(if_name,sizeof(if_name),"%s", interface_name);
5813
5814 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name);
5815 file = popen(pipeCmd, "r");
5816
5817 if(file == NULL)
5818 return RETURN_ERR; //popen failed
5819
5820 fgets(line, sizeof line, file);
5821 device = atoi(line);
5822 pclose(file);
5823
5824 if(device == 0)
5825 return RETURN_ERR; //No devices are connected
5826
5827 sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name);
5828 system(pipeCmd);
5829
5830 system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE);
5831
5832 system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE);
5833
5834 system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE);
5835
5836 system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE);
5837
5838 //devIndex starts from 1, ++count
5839 if((file = fopen(SIGNALFILE, "r")) != NULL )
5840 {
5841 for(count =0;fgets(line, sizeof line, file) != NULL;)
5842 {
5843 if (++count == devIndex)
5844 {
5845 output_struct->wifi_devSignalStrength = atoi(line);
5846 break;
5847 }
5848 }
5849 fclose(file);
5850 }
5851 else
5852 fprintf(stderr,"fopen wifi_signalstrength.txt failed");
5853
5854 if((file = fopen(MACFILE, "r")) != NULL )
5855 {
5856 for(count =0;fgets(line, sizeof line, file) != NULL;)
5857 {
5858 if (++count == devIndex)
5859 {
5860 sscanf(line, "%02x:%02x:%02x:%02x:%02x:%02x",&output_struct->wifi_devMacAddress[0],&output_struct->wifi_devMacAddress[1],&output_struct->wifi_devMacAddress[2],&output_struct->wifi_devMacAddress[3],&output_struct->wifi_devMacAddress[4],&output_struct->wifi_devMacAddress[5]);
5861 break;
5862 }
5863 }
5864 fclose(file);
5865 }
5866 else
5867 fprintf(stderr,"fopen wifi_AssoMac.txt failed");
5868
5869 if((file = fopen(TXRATEFILE, "r")) != NULL )
5870 {
5871 for(count =0;fgets(line, sizeof line, file) != NULL;)
5872 {
5873 if (++count == devIndex)
5874 {
5875 output_struct->wifi_devTxRate = atoi(line);
5876 break;
5877 }
5878 }
5879 fclose(file);
5880 }
5881 else
5882 fprintf(stderr,"fopen wifi_txrate.txt failed");
5883
5884 if((file = fopen(RXRATEFILE, "r")) != NULL)
5885 {
5886 for(count =0;fgets(line, sizeof line, file) != NULL;)
5887 {
5888 if (++count == devIndex)
5889 {
5890 output_struct->wifi_devRxRate = atoi(line);
5891 break;
5892 }
5893 }
5894 fclose(file);
5895 }
5896 else
5897 fprintf(stderr,"fopen wifi_rxrate.txt failed");
5898
5899 output_struct->wifi_devAssociatedDeviceAuthentiationState = 1;
5900
5901 return RETURN_OK;
5902#endif
5903}
5904
5905INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
5906{
5907 if (NULL == device)
5908 return RETURN_ERR;
5909 return RETURN_OK;
5910}
5911//<<
5912
5913
5914//--------------wifi_ap_hal-----------------------------
5915//enables CTS protection for the radio used by this AP
5916INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
5917{
5918 //save config and Apply instantly
5919 return RETURN_ERR;
5920}
5921
5922// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
5923INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
5924{
5925 char config_file[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08005926 char config_dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08005927 char buf[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08005928 struct params list = {0};
5929 struct params dat = {0};
5930 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08005931
5932 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5933 list.name = "ht_coex";
5934 snprintf(buf, sizeof(buf), "%d", enable);
5935 list.value = buf;
5936
developerd1824452023-05-18 12:30:04 +08005937 dat.name = "HT_BSSCoexistence";
5938 dat.value = buf;
5939
5940 band = wifi_index_to_band(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08005941 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd1824452023-05-18 12:30:04 +08005942 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08005943 wifi_hostapdWrite(config_file, &list, 1);
developer262f4cb2023-05-24 12:22:04 +08005944 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08005945 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5946
5947 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5948
5949 return RETURN_OK;
5950}
5951
5952//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
5953INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
5954{
5955 char config_file[MAX_BUF_SIZE] = {'\0'};
5956 char buf[MAX_BUF_SIZE] = {'\0'};
5957 struct params list;
5958
5959 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5960 if (threshold < 256 || threshold > 2346 )
5961 return RETURN_ERR;
5962 list.name = "fragm_threshold";
5963 snprintf(buf, sizeof(buf), "%d", threshold);
5964 list.value = buf;
5965
5966 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5967 wifi_hostapdWrite(config_file, &list, 1);
5968 wifi_hostapdProcessUpdate(apIndex, &list, 1);
5969
5970 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5971
5972 return RETURN_OK;
5973}
5974
5975// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
5976INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
5977{
5978 char config_file[64] = {'\0'};
5979 char cmd[512] = {'\0'};
5980 char buf[512] = {'\0'};
5981 char stbc_config[16] = {'\0'};
5982 wifi_band band;
5983 int iterator = 0;
5984 BOOL current_stbc = FALSE;
5985 int ant_count = 0;
5986 int ant_bitmap = 0;
5987 struct params list;
developera1255e42023-05-13 17:45:02 +08005988 char dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08005989
5990 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5991
5992 band = wifi_index_to_band(radioIndex);
5993 if (band == band_invalid)
5994 return RETURN_ERR;
5995
5996 if (band == band_2_4)
5997 iterator = 1;
developera1255e42023-05-13 17:45:02 +08005998 else if ((band == band_5) || (band == band_6))
developer72fb0bb2023-01-11 09:46:29 +08005999 iterator = 2;
6000 else
6001 return RETURN_OK;
6002
6003 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
6004 for (; ant_bitmap > 0; ant_bitmap >>= 1)
6005 ant_count += ant_bitmap & 1;
6006
6007 if (ant_count == 1 && STBC_Enable == TRUE) {
6008 fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__);
6009 return RETURN_OK;
6010 }
6011
6012 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6013
6014 // set ht and vht config
6015 for (int i = 0; i < iterator; i++) {
6016 memset(stbc_config, 0, sizeof(stbc_config));
6017 memset(cmd, 0, sizeof(cmd));
6018 memset(buf, 0, sizeof(buf));
6019 list.name = (i == 0)?"ht_capab":"vht_capab";
6020 snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
6021 snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
6022 _syscmd(cmd, buf, sizeof(buf));
6023 if (strlen(buf) != 0)
6024 current_stbc = TRUE;
6025 if (current_stbc == STBC_Enable)
6026 continue;
6027
6028 if (STBC_Enable == TRUE) {
6029 // Append the STBC flags in capab config
6030 memset(cmd, 0, sizeof(cmd));
6031 if (i == 0)
6032 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
6033 else
6034 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
6035 _syscmd(cmd, buf, sizeof(buf));
6036 } else if (STBC_Enable == FALSE) {
6037 // Remove the STBC flags and remain other flags in capab
6038 memset(cmd, 0, sizeof(cmd));
6039 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6040 _syscmd(cmd, buf, sizeof(buf));
6041 memset(cmd, 0, sizeof(cmd));
6042 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
6043 _syscmd(cmd, buf, sizeof(buf));
6044 }
6045 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
6046 list.value = buf;
6047 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
6048 }
developera1255e42023-05-13 17:45:02 +08006049 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6050 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
6051 _syscmd(cmd, buf, sizeof(buf));
6052 if ((band == band_5) || (band == band_6)) {
6053 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
6054 _syscmd(cmd, buf, sizeof(buf));
6055 }
6056 /*wifi_reloadAp(radioIndex);
6057 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08006058
6059 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6060 return RETURN_OK;
6061}
6062
6063// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
6064INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
6065{
developer2c22d832023-05-18 17:46:26 +08006066 char dat_file[128] = {0};
developer2c22d832023-05-18 17:46:26 +08006067 wifi_band band;
6068 char amdus_buff[8] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006069
developer2c22d832023-05-18 17:46:26 +08006070 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006071
developer2c22d832023-05-18 17:46:26 +08006072 band = wifi_index_to_band(radioIndex);
6073 if (band == band_invalid) {
6074 printf("%s:Band Error\n", __func__);
6075 return RETURN_ERR;
6076 }
6077 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6078 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6079 if (strncmp(amdus_buff, "1", 1) == 0)
developer72fb0bb2023-01-11 09:46:29 +08006080 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08006081 else
6082 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006083
developer2c22d832023-05-18 17:46:26 +08006084 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6085
6086 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006087}
6088
6089// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
6090INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
6091{
developer2c22d832023-05-18 17:46:26 +08006092 char dat_file[128] = {0};
6093 BOOL enable;
6094 wifi_band band;
6095 char amdus_buff[8] = {'\0'};
6096 struct params params = {0};
developer72fb0bb2023-01-11 09:46:29 +08006097
developer2c22d832023-05-18 17:46:26 +08006098 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006099
developer2c22d832023-05-18 17:46:26 +08006100 band = wifi_index_to_band(radioIndex);
6101 if (band == band_invalid) {
6102 printf("%s:Band Error\n", __func__);
6103 return RETURN_ERR;
6104 }
6105 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6106 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6107 if (strncmp(amdus_buff, "1", 1) == 0)
6108 enable = TRUE;
6109 else
6110 enable = FALSE;
6111 if (amsduEnable == enable)
6112 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006113
developer2c22d832023-05-18 17:46:26 +08006114 params.name = "HT_AMSDU";
6115 if (amsduEnable)
6116 params.value = "1";
6117 else
6118 params.value = "0";
6119 wifi_datfileWrite(dat_file, &params, 1);
6120 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006121
developer2c22d832023-05-18 17:46:26 +08006122 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006123
developer72fb0bb2023-01-11 09:46:29 +08006124 return RETURN_OK;
6125}
6126
6127//P2 // outputs the number of Tx streams
6128INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
6129{
6130 char buf[8] = {0};
6131 char cmd[128] = {0};
6132 int phyId = 0;
6133
6134 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6135
6136 phyId = radio_index_to_phy(radioIndex);
6137 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
6138 _syscmd(cmd, buf, sizeof(buf));
6139
6140 *output_int = (INT)strtol(buf, NULL, 16);
6141
6142 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6143
6144 return RETURN_OK;
6145}
6146
6147INT fitChainMask(INT radioIndex, int antcount)
6148{
6149 char buf[128] = {0};
6150 char cmd[128] = {0};
6151 char config_file[64] = {0};
6152 wifi_band band;
6153 struct params list[2] = {0};
6154
6155 band = wifi_index_to_band(radioIndex);
6156 if (band == band_invalid)
6157 return RETURN_ERR;
6158
6159 list[0].name = "he_mu_beamformer";
6160 list[1].name = "he_su_beamformer";
6161
6162 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6163 if (antcount == 1) {
6164 // remove config about multiple antennas
6165 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6166 _syscmd(cmd, buf, sizeof(buf));
6167
6168 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
6169 _syscmd(cmd, buf, sizeof(buf));
6170
6171 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
6172 _syscmd(cmd, buf, sizeof(buf));
6173
6174 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
6175 _syscmd(cmd, buf, sizeof(buf));
6176
6177 list[0].value = "0";
6178 list[1].value = "0";
6179 } else {
6180 // 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.
6181 if (band == band_2_4 || band == band_5) {
6182 snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6183 _syscmd(cmd, buf, sizeof(buf));
6184 if (strlen(buf) > 0) {
6185 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
6186 _syscmd(cmd, buf, sizeof(buf));
6187 }
6188 }
6189 if (band == band_5) {
6190 snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6191 _syscmd(cmd, buf, sizeof(buf));
6192 if (strlen(buf) > 0) {
6193 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
6194 _syscmd(cmd, buf, sizeof(buf));
6195 }
6196 }
6197
6198 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
6199 _syscmd(cmd, buf, sizeof(buf));
6200 if (strlen(buf) == 0) {
6201 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
6202 _syscmd(cmd, buf, sizeof(buf));
6203 }
6204
6205 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
6206 _syscmd(cmd, buf, sizeof(buf));
6207 if (strlen(buf) == 0) {
6208 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
6209 _syscmd(cmd, buf, sizeof(buf));
6210 }
6211
6212 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
6213 _syscmd(cmd, buf, sizeof(buf));
6214 if (strlen(buf) == 0) {
6215 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
6216 } else {
6217 snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
6218 }
6219 _syscmd(cmd, buf, sizeof(buf));
6220
6221 list[0].value = "1";
6222 list[1].value = "1";
6223 }
6224 wifi_hostapdWrite(config_file, list, 2);
developerdaf24792023-06-06 11:40:04 +08006225 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006226}
6227
6228//P2 // sets the number of Tx streams to an enviornment variable
6229INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
6230{
6231 char cmd[128] = {0};
6232 char buf[128] = {0};
6233 int phyId = 0;
6234 int cur_mask = 0;
developera1255e42023-05-13 17:45:02 +08006235 int antcountmsk = 0;
6236 INT cur_nss = 0;
developer863a4a62023-06-06 16:55:59 +08006237 CHAR dat_file[64] = {0};
developera1255e42023-05-13 17:45:02 +08006238 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08006239
6240 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6241
6242 if (numStreams <= 0) {
6243 fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams);
6244 return RETURN_ERR;
6245 }
6246
developera1255e42023-05-13 17:45:02 +08006247 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
6248 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
6249 cur_nss += 1;
6250 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
6251 if (cur_nss == numStreams)
developer72fb0bb2023-01-11 09:46:29 +08006252 return RETURN_OK;
6253
6254 wifi_setRadioEnable(radioIndex, FALSE);
6255
6256 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08006257 //iw need mask value.
6258 for (;numStreams > 0; numStreams--)
6259 antcountmsk |= 0x1 << (numStreams - 1);
6260 snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
developer72fb0bb2023-01-11 09:46:29 +08006261 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006262 if (strlen(buf) > 0) {
6263 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6264 return RETURN_ERR;
6265 }
developera1255e42023-05-13 17:45:02 +08006266 band = wifi_index_to_band(radioIndex);
6267 if (band == band_invalid) {
6268 printf("%s:Band Error\n", __func__);
6269 return RETURN_ERR;
6270 }
6271 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6272 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
6273 _syscmd(cmd, buf, sizeof(buf));
6274 if (strlen(buf) > 0) {
6275 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6276 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006277 }
developera1255e42023-05-13 17:45:02 +08006278 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
6279 _syscmd(cmd, buf, sizeof(buf));
6280 if (strlen(buf) > 0) {
6281 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6282 return RETURN_ERR;
6283 }
6284 fitChainMask(radioIndex, numStreams);
developer72fb0bb2023-01-11 09:46:29 +08006285 wifi_setRadioEnable(radioIndex, TRUE);
6286
6287 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6288 return RETURN_OK;
6289}
6290
6291//P2 // outputs the number of Rx streams
6292INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
6293{
6294 char buf[8] = {0};
6295 char cmd[128] = {0};
6296 int phyId = 0;
6297
6298 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6299
6300 phyId = radio_index_to_phy(radioIndex);
6301 sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
6302 _syscmd(cmd, buf, sizeof(buf));
6303
6304 *output_int = (INT)strtol(buf, NULL, 16);
6305
6306 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6307
6308 return RETURN_OK;
6309}
6310
6311//P2 // sets the number of Rx streams to an enviornment variable
6312INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
6313{
6314 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6315 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
6316 fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__);
6317 return RETURN_ERR;
6318 }
6319 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6320 return RETURN_ERR;
6321}
6322
6323//Get radio RDG enable setting
6324INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
6325{
developer47cc27a2023-05-17 23:09:58 +08006326 if (NULL == output_bool)
6327 return RETURN_ERR;
6328
6329 *output_bool = TRUE;
6330 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006331}
6332
6333//Get radio RDG enable setting
6334INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
6335{
developer47cc27a2023-05-17 23:09:58 +08006336 char rdg_status[2] = {0};
6337 char dat_file[MAX_CMD_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08006338
6339 if (NULL == output_bool)
6340 return RETURN_ERR;
6341
6342 /*prepare dat file path*/
6343 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6344
6345 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
6346 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
6347 *output_bool = TRUE;
6348 else
6349 *output_bool = FALSE;
6350
6351 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006352}
6353
6354//Set radio RDG enable setting
6355INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
6356{
developer47cc27a2023-05-17 23:09:58 +08006357 char dat_file[MAX_CMD_SIZE] = {0};
6358 struct params params = {0};
6359
6360 /*prepare dat file path*/
6361 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6362
6363 params.name = "HT_RDG";
6364
6365 if (enable) {
6366 params.value = "1";
6367 } else {
6368 params.value = "0";
6369 }
6370
6371 wifi_datfileWrite(dat_file, &params, 1);
6372
6373 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006374}
6375
developer5cd4c862023-05-26 09:34:42 +08006376
6377int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006378{
developer5cd4c862023-05-26 09:34:42 +08006379 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6380 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6381 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6382 unsigned char status;
6383 unsigned char *out_status = data;
6384 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08006385
developer5cd4c862023-05-26 09:34:42 +08006386 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6387 genlmsg_attrlen(gnlh, 0), NULL);
6388 if (err < 0){
6389 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6390 return err;
6391 }
developer8e6583c2023-05-23 13:36:06 +08006392
developer5cd4c862023-05-26 09:34:42 +08006393 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6394 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6395 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6396 if (err < 0){
6397 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6398 return err;
6399 }
developer8e6583c2023-05-23 13:36:06 +08006400
developer5cd4c862023-05-26 09:34:42 +08006401 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
6402 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
6403 if (status == 0) {
6404 wifi_debug(DEBUG_NOTICE, "disabled\n");
6405 } else {
6406 wifi_debug(DEBUG_NOTICE, "enabled\n");
6407 }
6408 *out_status = status;
6409 }
6410 }
developer8e6583c2023-05-23 13:36:06 +08006411
developer5cd4c862023-05-26 09:34:42 +08006412 return 0;
6413}
developer8e6583c2023-05-23 13:36:06 +08006414
developer5cd4c862023-05-26 09:34:42 +08006415int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
6416{
6417 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6418 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6419 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6420 unsigned char status;
6421 unsigned char *out_status = data;
6422 int err = 0;
6423
6424 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6425 genlmsg_attrlen(gnlh, 0), NULL);
6426 if (err < 0) {
6427 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6428 return err;
6429 }
6430
6431 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6432 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6433 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6434 if (err < 0) {
6435 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6436 return err;
6437 }
6438
6439 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
6440 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
6441 if (status == 0) {
6442 wifi_debug(DEBUG_NOTICE, "disabled\n");
6443 } else {
6444 wifi_debug(DEBUG_NOTICE, "enabled\n");
6445 }
6446 *out_status = status;
6447 }
6448 }
6449
6450 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08006451}
6452
developer5cd4c862023-05-26 09:34:42 +08006453INT mtk_wifi_get_ba_decl_auto_status(
6454 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
6455{
6456 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08006457 unsigned int if_idx = 0;
6458 int ret = -1;
6459 struct unl unl_ins;
6460 struct nl_msg *msg = NULL;
6461 struct nlattr * msg_data = NULL;
6462 struct mtk_nl80211_param param;
6463
6464 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6465 return RETURN_ERR;
6466 if_idx = if_nametoindex(inf_name);
6467 if (!if_idx) {
6468 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6469 return RETURN_ERR;
6470 }
6471 /*init mtk nl80211 vendor cmd*/
6472 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
6473 param.if_type = NL80211_ATTR_IFINDEX;
6474 param.if_idx = if_idx;
6475
6476 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6477 if (ret) {
6478 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6479 return RETURN_ERR;
6480 }
6481 /*add mtk vendor cmd data*/
6482 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
6483 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6484 nlmsg_free(msg);
6485 goto err;
6486 }
6487
6488 /*send mtk nl80211 vendor msg*/
6489 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6490 if (ret) {
6491 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6492 goto err;
6493 }
6494 /*deinit mtk nl80211 vendor msg*/
6495 mtk_nl80211_deint(&unl_ins);
6496 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
6497 return RETURN_OK;
6498err:
6499 mtk_nl80211_deint(&unl_ins);
6500 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6501 return RETURN_ERR;
6502}
developere0ff7232023-06-08 16:33:14 +08006503
6504INT mtk_wifi_set_auto_ba_en(
6505 INT apIndex, INT vendor_data_attr, BOOL enable)
6506{
6507 char inf_name[IF_NAME_SIZE] = {0};
6508 unsigned int if_idx = 0;
6509 int ret = -1;
6510 struct unl unl_ins;
6511 struct nl_msg *msg = NULL;
6512 struct nlattr * msg_data = NULL;
6513 struct mtk_nl80211_param param;
6514
6515 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6516 return RETURN_ERR;
6517 if_idx = if_nametoindex(inf_name);
6518 if (!if_idx) {
6519 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6520 return RETURN_ERR;
6521 }
6522 /*init mtk nl80211 vendor cmd*/
6523 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
6524 param.if_type = NL80211_ATTR_IFINDEX;
6525 param.if_idx = if_idx;
6526
6527 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6528 if (ret) {
6529 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6530 return RETURN_ERR;
6531 }
6532 /*add mtk vendor cmd data*/
6533 if (nla_put_u8(msg, vendor_data_attr, enable)) {
6534 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6535 nlmsg_free(msg);
6536 goto err;
6537 }
6538
6539 /*send mtk nl80211 vendor msg*/
6540 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
6541 if (ret) {
6542 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6543 goto err;
6544 }
6545 /*deinit mtk nl80211 vendor msg*/
6546 mtk_nl80211_deint(&unl_ins);
6547 return RETURN_OK;
6548err:
6549 mtk_nl80211_deint(&unl_ins);
6550 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6551 return RETURN_ERR;
6552}
6553
developer5cd4c862023-05-26 09:34:42 +08006554//Get radio ADDBA enable setting
6555INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
6556{
6557 if (output_bool == NULL) {
6558 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6559 return RETURN_ERR;
6560 }
6561 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6562 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
6563 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
6564 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
6565 return RETURN_ERR;
6566 }
6567 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6568 return RETURN_OK;
6569}
6570
developer72fb0bb2023-01-11 09:46:29 +08006571//Set radio ADDBA enable setting
6572INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
6573{
6574 return RETURN_ERR;
6575}
6576
6577//Get radio auto block ack enable setting
6578INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
6579{
developer5cd4c862023-05-26 09:34:42 +08006580 if (output_bool == NULL) {
6581 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6582 return RETURN_ERR;
6583 }
developer8e6583c2023-05-23 13:36:06 +08006584
developer5cd4c862023-05-26 09:34:42 +08006585 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6586 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
6587 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
6588 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
6589 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
6590 return RETURN_ERR;
6591 }
6592 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6593 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006594}
6595
6596//Set radio auto block ack enable setting
6597INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
6598{
developere0ff7232023-06-08 16:33:14 +08006599 if (mtk_wifi_set_auto_ba_en
6600 (radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
6601 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
6602 return RETURN_ERR;
6603 }
6604 wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
6605 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006606}
6607
6608//Get radio 11n pure mode enable support
6609INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
6610{
6611 if (NULL == output_bool)
6612 return RETURN_ERR;
6613 *output_bool = TRUE;
6614 return RETURN_OK;
6615}
6616
6617//Get radio 11n pure mode enable setting
6618INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
6619{
6620 if (NULL == output_bool)
6621 return RETURN_ERR;
6622 *output_bool = TRUE;
6623 return RETURN_OK;
6624}
6625
6626//Set radio 11n pure mode enable setting
6627INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
6628{
6629 return RETURN_ERR;
6630}
6631
developer5cd4c862023-05-26 09:34:42 +08006632
6633int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006634{
developer5cd4c862023-05-26 09:34:42 +08006635 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6636 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
6637 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6638 unsigned char status = 0, *out_status = data;
6639 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08006640
developer5cd4c862023-05-26 09:34:42 +08006641 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6642 genlmsg_attrlen(gnlh, 0), NULL);
6643 if (err < 0) {
6644 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6645 return err;
6646 }
developer72fb0bb2023-01-11 09:46:29 +08006647
developer5cd4c862023-05-26 09:34:42 +08006648 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6649 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
6650 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6651 if (err < 0){
6652 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
6653 return err;
6654 }
developer72fb0bb2023-01-11 09:46:29 +08006655
developer5cd4c862023-05-26 09:34:42 +08006656 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
6657 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
6658 if (status == 0) {
6659 wifi_debug(DEBUG_NOTICE, "disabled\n");
6660 } else {
6661 wifi_debug(DEBUG_NOTICE, "enabled\n");
6662 }
6663 *out_status = status;
6664 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
6665 }
6666 }
6667
6668 return 0;
6669}
6670
6671INT mtk_wifi_set_igmp_en_status(
6672 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
6673 unsigned char in_en_stat, BOOL *output_bool)
6674{
6675 char inf_name[IF_NAME_SIZE] = {0};
developer5cd4c862023-05-26 09:34:42 +08006676 unsigned int if_idx = 0;
6677 int ret = -1;
6678 struct unl unl_ins;
6679 struct nl_msg *msg = NULL;
6680 struct nlattr * msg_data = NULL;
6681 struct mtk_nl80211_param param;
6682
6683 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6684 return RETURN_ERR;
6685 if_idx = if_nametoindex(inf_name);
6686 if (!if_idx) {
6687 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6688 return RETURN_ERR;
6689 }
6690 /*init mtk nl80211 vendor cmd*/
6691 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
6692 param.if_type = NL80211_ATTR_IFINDEX;
6693 param.if_idx = if_idx;
6694
6695 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6696 if (ret) {
6697 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6698 return RETURN_ERR;
6699 }
6700 /*add mtk vendor cmd data*/
6701 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
6702 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6703 nlmsg_free(msg);
6704 goto err;
6705 }
6706
6707 /*send mtk nl80211 vendor msg*/
6708 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6709 if (ret) {
6710 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6711 goto err;
6712 }
6713 /*deinit mtk nl80211 vendor msg*/
6714 mtk_nl80211_deint(&unl_ins);
6715 if (output_bool) {
6716 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
6717 } else {
6718 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
6719 }
6720 return RETURN_OK;
6721err:
6722 mtk_nl80211_deint(&unl_ins);
6723 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6724 return RETURN_ERR;
6725}
6726
6727
6728//Get radio IGMP snooping enable setting
6729INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
6730{
6731 if (output_bool == NULL) {
6732 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6733 return RETURN_ERR;
6734 }
6735 if (mtk_wifi_set_igmp_en_status
6736 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
6737 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
6738 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
6739 return RETURN_ERR;
6740 }
6741 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006742 return RETURN_OK;
6743}
6744
6745//Set radio IGMP snooping enable setting
6746INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
6747{
developer5cd4c862023-05-26 09:34:42 +08006748 if (mtk_wifi_set_igmp_en_status
6749 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
6750 NULL, enable, NULL) != RETURN_OK) {
6751 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
6752 return RETURN_ERR;
6753 }
6754 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developer72fb0bb2023-01-11 09:46:29 +08006755 return RETURN_OK;
6756}
6757
6758//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08006759INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08006760{
developer69b61b02023-03-07 17:17:44 +08006761 if (NULL == output_int)
developer72fb0bb2023-01-11 09:46:29 +08006762 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08006763 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006764
6765 return RETURN_OK;
6766}
6767
6768
6769//---------------------------------------------------------------------------------------------------
6770//
6771// Additional Wifi AP level APIs used for Access Point devices
6772//
6773//---------------------------------------------------------------------------------------------------
6774
6775// creates a new ap and pushes these parameters to the hardware
6776INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
6777{
6778 // Deprecated when use hal version 3, use wifi_createVap() instead.
6779 return RETURN_OK;
6780}
6781
6782// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
6783INT wifi_deleteAp(INT apIndex)
6784{
developer7e4a2a62023-04-06 19:56:03 +08006785 char interface_name[16] = {0};
6786 char buf[MAX_BUF_SIZE];
6787 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08006788
developer7e4a2a62023-04-06 19:56:03 +08006789 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6790 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08006791
developer7e4a2a62023-04-06 19:56:03 +08006792 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
6793 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006794
developer7e4a2a62023-04-06 19:56:03 +08006795 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006796
developer7e4a2a62023-04-06 19:56:03 +08006797 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006798}
6799
6800// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
6801INT wifi_getApName(INT apIndex, CHAR *output_string)
6802{
developer7e4a2a62023-04-06 19:56:03 +08006803 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08006804 int radio_idx = 0;
6805 int bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08006806
developer7e4a2a62023-04-06 19:56:03 +08006807 if(!output_string)
6808 return RETURN_ERR;
6809
6810 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
6811 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
6812
6813 snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model.
6814 } else
6815 snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
6816
6817 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006818}
6819
6820// Outputs the index number in that corresponds to the SSID string
6821INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
6822{
developer7e4a2a62023-04-06 19:56:03 +08006823 char cmd [128] = {0};
6824 char buf[32] = {0};
6825 char ap_idx = 0;
6826 char *apIndex_str = NULL;
6827 char radio_idx = 0;
6828 char bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08006829
developer7e4a2a62023-04-06 19:56:03 +08006830 snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
6831 inputSsidString);
6832 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006833
developer7e4a2a62023-04-06 19:56:03 +08006834 if (strlen(buf)) {
6835 apIndex_str = strtok(buf, "\n");
6836 *output_int = strtoul(apIndex_str, NULL, 10);
6837 return RETURN_OK;
6838 }
developer72fb0bb2023-01-11 09:46:29 +08006839
developer7e4a2a62023-04-06 19:56:03 +08006840 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
6841 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
6842 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
6843 radio_idx = 2;
6844 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
6845 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
6846 radio_idx = 1;
6847 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
6848 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
6849 radio_idx = 0;
6850 } else {
6851 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
6852 __func__, inputSsidString, ap_idx);
6853 *output_int = -1;
6854 return RETURN_ERR;
6855 }
6856
6857 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
6858
6859 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
6860 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
6861 __func__, inputSsidString, ap_idx);
6862 *output_int = ap_idx;
6863 return RETURN_OK;
6864 }
6865
6866 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006867}
6868
6869INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
6870{
6871 return wifi_getIndexFromName(inputSsidString, output_int);
6872}
6873
6874// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
6875INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
6876{
6877 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08006878 char config_file[MAX_BUF_SIZE] = {0};
6879
6880 if(NULL == output_string)
6881 return RETURN_ERR;
6882
6883 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6884 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
6885 if((strcmp(buf,"3")==0))
6886 snprintf(output_string, 32, "WPAand11i");
6887 else if((strcmp(buf,"2")==0))
6888 snprintf(output_string, 32, "11i");
6889 else if((strcmp(buf,"1")==0))
6890 snprintf(output_string, 32, "WPA");
6891 else
6892 snprintf(output_string, 32, "None");
6893
6894 return RETURN_OK;
6895}
6896
6897// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
6898INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
6899{
6900 char config_file[MAX_BUF_SIZE] = {0};
6901 struct params list;
6902
6903 if (NULL == beaconTypeString)
6904 return RETURN_ERR;
6905 list.name = "wpa";
6906 list.value = "0";
6907
6908 if((strcmp(beaconTypeString,"WPAand11i")==0))
6909 list.value="3";
6910 else if((strcmp(beaconTypeString,"11i")==0))
6911 list.value="2";
6912 else if((strcmp(beaconTypeString,"WPA")==0))
6913 list.value="1";
6914
6915 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
6916 wifi_hostapdWrite(config_file, &list, 1);
6917 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6918 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
6919 return RETURN_OK;
6920}
6921
6922// sets the beacon interval on the hardware for this AP
6923INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
6924{
6925 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6926 struct params params={'\0'};
6927 char buf[MAX_BUF_SIZE] = {'\0'};
6928 char config_file[MAX_BUF_SIZE] = {'\0'};
6929
6930 params.name = "beacon_int";
6931 snprintf(buf, sizeof(buf), "%u", beaconInterval);
6932 params.value = buf;
6933
6934 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6935 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08006936
developer72fb0bb2023-01-11 09:46:29 +08006937 wifi_hostapdProcessUpdate(apIndex, &params, 1);
6938 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6939 return RETURN_OK;
6940}
6941
6942INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
6943{
6944 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
6945 return RETURN_ERR;
6946 return RETURN_OK;
6947}
6948
6949// Get the packet size threshold supported.
6950INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
6951{
6952 //save config and apply instantly
6953 if (NULL == output_bool)
6954 return RETURN_ERR;
6955 *output_bool = TRUE;
6956 return RETURN_OK;
6957}
6958
6959// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
6960INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
6961{
developer72fb0bb2023-01-11 09:46:29 +08006962 char buf[16] = {0};
6963 char config_file[128] = {0};
6964 struct params param = {0};
6965
6966 if (threshold > 65535) {
6967 fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold);
6968 return RETURN_ERR;
6969 }
6970
developer23e71282023-01-18 10:25:19 +08006971 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006972 snprintf(buf, sizeof(buf), "%u", threshold);
6973 param.name = "rts_threshold";
6974 param.value = buf;
6975 wifi_hostapdWrite(config_file, &param, 1);
6976 wifi_hostapdProcessUpdate(apIndex, &param, 1);
6977 wifi_reloadAp(apIndex);
6978
6979 return RETURN_OK;
6980}
6981
6982// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
6983INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
6984{
6985 if (NULL == output_string)
6986 return RETURN_ERR;
6987 snprintf(output_string, 32, "TKIPandAESEncryption");
6988 return RETURN_OK;
6989
6990}
6991
6992// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
6993INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
6994{
6995 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6996 char *param_name = NULL;
6997 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
developerc79e9172023-06-06 19:48:03 +08006998 unsigned int len;
developer72fb0bb2023-01-11 09:46:29 +08006999
7000 if(NULL == output_string)
7001 return RETURN_ERR;
7002
7003 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7004 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
7005
7006 if(strcmp(buf,"0")==0)
7007 {
7008 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
7009 snprintf(output_string, 32, "None");
7010 return RETURN_OK;
7011 }
7012 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
7013 param_name = "rsn_pairwise";
7014 else if((strcmp(buf,"1")==0))
7015 param_name = "wpa_pairwise";
7016 else
7017 return RETURN_ERR;
7018 memset(output_string,'\0',32);
7019 wifi_hostapdRead(config_file,param_name,output_string,32);
7020 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
7021 param_name = "wpa_pairwise";
7022 memset(output_string, '\0', 32);
7023 wifi_hostapdRead(config_file, param_name, output_string, 32);
7024 }
7025 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
7026
developerc79e9172023-06-06 19:48:03 +08007027 if(strcmp(output_string,"TKIP CCMP") == 0) {
7028 len = strlen("TKIPandAESEncryption");
7029 memcpy(output_string,"TKIPandAESEncryption", len);
7030 output_string[len] = '\0';
7031 } else if(strcmp(output_string,"TKIP") == 0) {
7032 len = strlen("TKIPEncryption");
7033 memcpy(output_string,"TKIPEncryption", len);
7034 output_string[len] = '\0';
7035 } else if(strcmp(output_string,"CCMP") == 0) {
7036 len = strlen("AESEncryption");
7037 memcpy(output_string,"AESEncryption", len);
7038 output_string[len] = '\0';
7039 }
developer72fb0bb2023-01-11 09:46:29 +08007040
7041 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7042 return RETURN_OK;
7043}
7044
7045// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7046INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
7047{
7048 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7049 struct params params={'\0'};
7050 char output_string[32];
7051 char config_file[MAX_BUF_SIZE] = {0};
7052
7053 memset(output_string,'\0',32);
developere5750452023-05-15 16:46:42 +08007054 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08007055
7056 if(strcmp(encMode, "TKIPEncryption") == 0)
7057 params.value = "TKIP";
7058 else if(strcmp(encMode,"AESEncryption") == 0)
7059 params.value = "CCMP";
7060 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
7061 params.value = "TKIP CCMP";
7062
7063 if((strcmp(output_string,"WPAand11i")==0))
7064 {
7065 params.name = "wpa_pairwise";
7066 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7067 wifi_hostapdWrite(config_file, &params, 1);
7068 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7069
7070 params.name = "rsn_pairwise";
7071 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7072 wifi_hostapdWrite(config_file, &params, 1);
7073 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7074
7075 return RETURN_OK;
7076 }
7077 else if((strcmp(output_string,"11i")==0))
7078 {
7079 params.name = "rsn_pairwise";
7080 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7081 wifi_hostapdWrite(config_file, &params, 1);
7082 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7083 return RETURN_OK;
7084 }
7085 else if((strcmp(output_string,"WPA")==0))
7086 {
7087 params.name = "wpa_pairwise";
7088 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7089 wifi_hostapdWrite(config_file, &params, 1);
7090 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7091 return RETURN_OK;
7092 }
7093
7094 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7095 return RETURN_OK;
7096}
7097
7098// deletes internal security varable settings for this ap
7099INT wifi_removeApSecVaribles(INT apIndex)
7100{
7101 //TODO: remove the entry in hostapd config file
7102 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name);
7103 //_syscmd(cmd, buf, sizeof(buf));
7104
7105 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name);
7106 //_syscmd(cmd, buf, sizeof(buf));
7107 return RETURN_ERR;
7108}
7109
7110// changes the hardware settings to disable encryption on this ap
7111INT wifi_disableApEncryption(INT apIndex)
7112{
7113 //Apply instantly
7114 return RETURN_ERR;
7115}
7116
7117// set the authorization mode on this ap
7118// mode mapping as: 1: open, 2: shared, 4:auto
7119INT wifi_setApAuthMode(INT apIndex, INT mode)
7120{
7121 struct params params={0};
7122 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007123
7124 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
7125
7126 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
7127 params.name = "auth_algs";
7128
developere5750452023-05-15 16:46:42 +08007129 if ((mode & 1 && mode & 2) || mode & 4)
developer72fb0bb2023-01-11 09:46:29 +08007130 params.value = "3";
7131 else if (mode & 2)
7132 params.value = "2";
7133 else if (mode & 1)
7134 params.value = "1";
7135 else
7136 params.value = "0";
7137
7138 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7139 wifi_hostapdWrite(config_file, &params, 1);
7140 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08007141 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007142 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
7143
7144 return RETURN_OK;
7145}
7146
7147// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7148INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7149{
7150 //save to wifi config, and wait for wifi restart to apply
7151 struct params params={'\0'};
7152 char config_file[MAX_BUF_SIZE] = {0};
7153 int ret;
7154
7155 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7156 if(authMode == NULL)
7157 return RETURN_ERR;
7158
7159 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
7160 params.name = "wpa_key_mgmt";
7161
7162 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
7163 params.value = "WPA-PSK";
7164 else if(strcmp(authMode,"EAPAuthentication") == 0)
7165 params.value = "WPA-EAP";
7166 else if (strcmp(authMode, "SAEAuthentication") == 0)
7167 params.value = "SAE";
7168 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
7169 params.value = "WPA-EAP-SUITE-B-192";
7170 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
7171 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
developer3086e2f2023-01-17 09:40:01 +08007172 else if (strcmp(authMode, "Enhanced_Open") == 0)
7173 params.value = "OWE";
developer72fb0bb2023-01-11 09:46:29 +08007174 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
7175 return RETURN_OK; //This is taken careof in beaconType
7176
7177 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7178 ret=wifi_hostapdWrite(config_file,&params,1);
7179 if(!ret)
7180 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
7181 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7182
7183 return ret;
7184}
7185
7186// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7187INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7188{
7189 //save to wifi config, and wait for wifi restart to apply
7190 char BeaconType[50] = {0};
7191 char config_file[MAX_BUF_SIZE] = {0};
7192
7193 *authMode = 0;
7194 wifi_getApBeaconType(apIndex,BeaconType);
7195 printf("%s____%s \n",__FUNCTION__,BeaconType);
7196
7197 if(strcmp(BeaconType,"None") == 0)
7198 strcpy(authMode,"None");
7199 else
7200 {
7201 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7202 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
7203 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
7204 if(strcmp(authMode,"WPA-PSK") == 0)
7205 strcpy(authMode,"SharedAuthentication");
7206 else if(strcmp(authMode,"WPA-EAP") == 0)
7207 strcpy(authMode,"EAPAuthentication");
7208 }
7209
7210 return RETURN_OK;
7211}
7212
7213// Outputs the number of stations associated per AP
7214INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
7215{
7216 char interface_name[16] = {0};
7217 char cmd[128]={0};
7218 char buf[128]={0};
7219 BOOL status = false;
7220
7221 if(apIndex > MAX_APS)
7222 return RETURN_ERR;
7223
7224 wifi_getApEnable(apIndex,&status);
7225 if (!status)
7226 return RETURN_OK;
7227
7228 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
7229 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7230 return RETURN_ERR;
7231 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name);
7232 _syscmd(cmd, buf, sizeof(buf));
7233 sscanf(buf,"%lu", output_ulong);
7234
7235 return RETURN_OK;
7236}
7237
7238// manually removes any active wi-fi association with the device specified on this ap
7239INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
7240{
developer7e4a2a62023-04-06 19:56:03 +08007241 char inf_name[16] = {0};
7242 char cmd[MAX_CMD_SIZE] = {0};
7243 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007244
developer7e4a2a62023-04-06 19:56:03 +08007245 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08007246 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007247
7248 snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
7249 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007250
7251 return RETURN_OK;
7252}
7253
7254// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
7255INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
7256{
developer7e4a2a62023-04-06 19:56:03 +08007257 int max_radio_num = 0;
7258
7259 if(NULL == output_int)
7260 return RETURN_ERR;
7261
7262 wifi_getMaxRadioNumber(&max_radio_num);
7263 *output_int = apIndex % max_radio_num;
7264
7265 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007266}
7267
7268// sets the radio index for the specific ap
7269INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
7270{
7271 //set to config only and wait for wifi reset to apply settings
7272 return RETURN_ERR;
7273}
7274
developer121a8e72023-05-22 09:19:39 +08007275
7276#define MAX_ACL_DUMP_LEN 4096
7277int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
7278{
7279 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7280 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
7281 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7282 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08007283 int err = 0;
developer121a8e72023-05-22 09:19:39 +08007284 unsigned short acl_result_len = 0;
7285 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08007286 if (!msg || !cb_data) {
developerdaf24792023-06-06 11:40:04 +08007287 wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08007288 return NL_SKIP;
7289 }
developer121a8e72023-05-22 09:19:39 +08007290 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7291 genlmsg_attrlen(gnlh, 0), NULL);
7292 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08007293 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08007294 return NL_SKIP;
7295 }
developer121a8e72023-05-22 09:19:39 +08007296 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7297 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
7298 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7299 if (err < 0)
7300 return NL_SKIP;
7301 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
7302 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7303 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7304 if (acl_result_len > MAX_ACL_DUMP_LEN) {
7305 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
7306 return NL_SKIP;
7307 } else if (*(show_str + acl_result_len - 1) != '\0') {
7308 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
7309 *(show_str + acl_result_len - 1) = '\0';
7310 }
7311 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08007312
7313 if (cb_data->out_len >= acl_result_len) {
7314 memset(cb_data->out_buf, 0, cb_data->out_len);
7315 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
7316 memmove(cb_data->out_buf, show_str, acl_result_len);
7317 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
7318 } else {
7319 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08007320 }
developer121a8e72023-05-22 09:19:39 +08007321 } else
7322 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
7323 } else
7324 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
7325 return NL_OK;
7326}
developer72fb0bb2023-01-11 09:46:29 +08007327// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08007328INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08007329{
developer7e4a2a62023-04-06 19:56:03 +08007330 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08007331 unsigned int if_idx = 0;
7332 int ret = -1;
7333 struct unl unl_ins;
7334 struct nl_msg *msg = NULL;
7335 struct nlattr * msg_data = NULL;
7336 struct mtk_nl80211_param param;
7337 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08007338 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7339 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08007340 if_idx = if_nametoindex(inf_name);
7341 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08007342 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08007343 return RETURN_ERR;
7344 }
7345 /*init mtk nl80211 vendor cmd*/
7346 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7347 param.if_type = NL80211_ATTR_IFINDEX;
7348 param.if_idx = if_idx;
7349
7350 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7351 if (ret) {
7352 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7353 return RETURN_ERR;
7354 }
developer121a8e72023-05-22 09:19:39 +08007355 /*add mtk vendor cmd data*/
7356 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08007357 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08007358 nlmsg_free(msg);
7359 goto err;
7360 }
developer72fb0bb2023-01-11 09:46:29 +08007361
developer121a8e72023-05-22 09:19:39 +08007362 /*send mtk nl80211 vendor msg*/
7363 cb_data.out_buf = macArray;
7364 cb_data.out_len = buf_size;
7365
7366 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
7367 if (ret) {
7368 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7369 goto err;
7370 }
7371 /*deinit mtk nl80211 vendor msg*/
7372 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007373 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developer72fb0bb2023-01-11 09:46:29 +08007374 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08007375err:
7376 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007377 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08007378 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007379}
7380
developer2edaf012023-05-24 14:24:53 +08007381INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7382{
7383 char *mac_arry_buf = NULL;
7384
7385 mac_arry_buf = malloc(buf_size);
7386 if (!mac_arry_buf) {
7387 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
7388 return RETURN_ERR;
7389 }
7390 memset(mac_arry_buf, 0, buf_size);
7391 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
7392 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
7393 free(mac_arry_buf);
7394 mac_arry_buf = NULL;
7395 return RETURN_ERR;
7396 }
7397 /*
7398 mtk format to wifi hal format:
7399 "policy=1
7400 00:11:22:33:44:55
7401 00:11:22:33:44:66
7402 "
7403 -->
7404 "00:11:22:33:44:55
7405 00:11:22:33:44:66
7406 "
7407 */
7408 memset(macArray, 0, buf_size);
7409 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
7410 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
7411 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
7412 }
7413 free(mac_arry_buf);
7414 mac_arry_buf = NULL;
7415 return RETURN_OK;
7416}
7417
developer72fb0bb2023-01-11 09:46:29 +08007418INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7419{
developer72fb0bb2023-01-11 09:46:29 +08007420
developer7e4a2a62023-04-06 19:56:03 +08007421 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08007422
7423 return RETURN_OK;
7424}
7425
7426
7427// Get the list of stations associated per AP
7428INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
7429{
developer7e4a2a62023-04-06 19:56:03 +08007430 char interface_name[IF_NAME_SIZE] = {0};
7431 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08007432
developer7e4a2a62023-04-06 19:56:03 +08007433 if(apIndex > 3) //Currently supporting apIndex upto 3
7434 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007435
developer7e4a2a62023-04-06 19:56:03 +08007436 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7437 return RETURN_ERR;
7438
7439 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
7440 _syscmd(cmd, macArray, buf_size);
7441 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007442}
7443
developer8dd72532023-05-17 19:58:35 +08007444int hex2num(char c)
7445{
7446 if (c >= '0' && c <= '9')
7447 return c - '0';
7448 if (c >= 'a' && c <= 'f')
7449 return c - 'a' + 10;
7450 if (c >= 'A' && c <= 'F')
7451 return c - 'A' + 10;
7452 return -1;
7453}
7454
7455/**
7456 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
7457 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
7458 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
7459 * Returns: Characters used (> 0) on success, -1 on failure
7460 */
7461int hwaddr_aton2(const char *txt, unsigned char *addr)
7462{
7463 int i;
7464 const char *pos = txt;
7465
7466 for (i = 0; i < 6; i++) {
7467 int a, b;
7468
7469 while (*pos == ':' || *pos == '.' || *pos == '-')
7470 pos++;
7471
7472 a = hex2num(*pos++);
7473 if (a < 0)
7474 return -1;
7475 b = hex2num(*pos++);
7476 if (b < 0)
7477 return -1;
7478 *addr++ = (a << 4) | b;
7479 }
7480
7481 return pos - txt;
7482}
7483
developer72fb0bb2023-01-11 09:46:29 +08007484// adds the mac address to the filter list
7485//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7486INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7487{
developer7e4a2a62023-04-06 19:56:03 +08007488 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08007489 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08007490 struct nl_msg *msg = NULL;
7491 struct nlattr * msg_data = NULL;
7492 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08007493 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
7494 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08007495 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7496 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007497 if (!DeviceMacAddress)
7498 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08007499 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08007500 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08007501 return RETURN_ERR;
7502 }
developer8dd72532023-05-17 19:58:35 +08007503 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08007504 if (!if_idx) {
7505 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7506 return RETURN_ERR;
7507 }
developer49b17232023-05-19 16:35:19 +08007508 /*init mtk nl80211 vendor cmd*/
7509 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7510 param.if_type = NL80211_ATTR_IFINDEX;
7511 param.if_idx = if_idx;
7512 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7513 if (ret) {
7514 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007515 return RETURN_ERR;
7516 }
developer49b17232023-05-19 16:35:19 +08007517 /*add mtk vendor cmd data*/
7518 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08007519 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08007520 nlmsg_free(msg);
7521 goto err;
7522 }
developer49b17232023-05-19 16:35:19 +08007523 /*send mtk nl80211 vendor msg*/
7524 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7525 if (ret) {
7526 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007527 goto err;
7528 }
developer49b17232023-05-19 16:35:19 +08007529 /*deinit mtk nl80211 vendor msg*/
7530 mtk_nl80211_deint(&unl_ins);
7531 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08007532 return RETURN_OK;
7533err:
developer49b17232023-05-19 16:35:19 +08007534 mtk_nl80211_deint(&unl_ins);
7535 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08007536 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007537}
7538
7539// deletes the mac address from the filter list
7540//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7541INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7542{
developer2edaf012023-05-24 14:24:53 +08007543 struct unl unl_ins;
7544 int if_idx = 0, ret = 0;
7545 struct nl_msg *msg = NULL;
7546 struct nlattr * msg_data = NULL;
7547 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08007548 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007549 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007550
developer7e4a2a62023-04-06 19:56:03 +08007551 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7552 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007553
developer7e4a2a62023-04-06 19:56:03 +08007554 if (!DeviceMacAddress)
7555 return RETURN_ERR;
7556
developer2edaf012023-05-24 14:24:53 +08007557 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
7558 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
7559 return RETURN_ERR;
7560 }
developer72fb0bb2023-01-11 09:46:29 +08007561
developer2edaf012023-05-24 14:24:53 +08007562 if_idx = if_nametoindex(inf_name);
7563 if (!if_idx) {
7564 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7565 return RETURN_ERR;
7566 }
7567 /*init mtk nl80211 vendor cmd*/
7568 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7569 param.if_type = NL80211_ATTR_IFINDEX;
7570 param.if_idx = if_idx;
7571 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7572 if (ret) {
7573 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7574 return RETURN_ERR;
7575 }
7576 /*add mtk vendor cmd data*/
7577 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
7578 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7579 nlmsg_free(msg);
7580 goto err;
7581 }
7582 /*send mtk nl80211 vendor msg*/
7583 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7584 if (ret) {
7585 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7586 goto err;
7587 }
7588 /*deinit mtk nl80211 vendor msg*/
7589 mtk_nl80211_deint(&unl_ins);
7590 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
7591 return RETURN_OK;
7592err:
7593 mtk_nl80211_deint(&unl_ins);
7594 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7595 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007596}
7597
7598// outputs the number of devices in the filter list
7599INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
7600{
developer2edaf012023-05-24 14:24:53 +08007601 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
7602 UINT buf_size = 1024;
7603 UINT sta_num = 0;
7604 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007605 if(output_uint == NULL)
developerdaf24792023-06-06 11:40:04 +08007606 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007607
developer2edaf012023-05-24 14:24:53 +08007608 mac_arry = (char *)malloc(buf_size);
7609 if (mac_arry == NULL) {
7610 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08007611 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007612 }
developerdaf24792023-06-06 11:40:04 +08007613 memset(mac_arry, 0, buf_size);
developer2edaf012023-05-24 14:24:53 +08007614 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
7615 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
7616 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
7617 return RETURN_ERR;
7618 }
7619 /*count the acl str nums:*/
7620 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08007621
developer2edaf012023-05-24 14:24:53 +08007622 /*mac addr string format:
7623 exp1: 00:11:22:33:44:55\0
7624 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
7625 */
7626 ptr = mac_arry;
7627 while (sscanf(ptr, "%17s", mac_str) == 1) {
7628 if (hwaddr_aton2(mac_str, mac) >= 0)
7629 sta_num++;
7630 ptr = strstr(ptr, mac_str) + strlen(mac_str);
7631 }
7632 *output_uint = sta_num;
7633 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
7634 free(mac_arry);
7635 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08007636 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007637}
7638
7639INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
7640{
developer72fb0bb2023-01-11 09:46:29 +08007641 char buf[128]={'\0'};
7642
7643 if(strcmp(action,"DENY")==0)
7644 {
7645 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
7646 system(buf);
7647 return RETURN_OK;
7648 }
7649
7650 if(strcmp(action,"ALLOW")==0)
7651 {
7652 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
7653 system(buf);
7654 return RETURN_OK;
7655 }
7656
7657 return RETURN_ERR;
7658
7659}
7660
7661// enable kick for devices on acl black list
7662INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
7663{
developer47cc27a2023-05-17 23:09:58 +08007664 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
developer2f79c922023-06-02 17:33:42 +08007665 char assocArray[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007666
7667 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
7668 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
7669
developer7e4a2a62023-04-06 19:56:03 +08007670 /* if there are no devices connected there is nothing to do */
developer72fb0bb2023-01-11 09:46:29 +08007671 if (strlen(assocArray) < 17)
7672 return RETURN_OK;
7673
developer7e4a2a62023-04-06 19:56:03 +08007674 if (enable == TRUE) {
7675 /* kick off the MAC which is in ACL array (deny list) */
7676 acl = strtok(aclArray, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007677 while (acl != NULL) {
7678 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
7679 wifi_kickApAssociatedDevice(apIndex, acl);
7680
developer7e4a2a62023-04-06 19:56:03 +08007681 acl = strtok(NULL, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007682 }
7683 wifi_setApMacAddressControlMode(apIndex, 2);
developer7e4a2a62023-04-06 19:56:03 +08007684 } else
developer72fb0bb2023-01-11 09:46:29 +08007685 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08007686
developer72fb0bb2023-01-11 09:46:29 +08007687 return RETURN_OK;
7688}
7689
7690INT wifi_setPreferPrivateConnection(BOOL enable)
7691{
7692 return RETURN_OK;
7693}
7694
7695// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
7696INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
7697{
developer2edaf012023-05-24 14:24:53 +08007698 int if_idx = 0, ret = 0;
7699 struct unl unl_ins;
7700 struct nl_msg *msg = NULL;
7701 struct nlattr * msg_data = NULL;
7702 struct mtk_nl80211_param param;
7703 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08007704 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007705
developer7e4a2a62023-04-06 19:56:03 +08007706 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7707 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007708 if_idx = if_nametoindex(inf_name);
7709 if (!if_idx) {
7710 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7711 return RETURN_ERR;
7712 }
7713 /*init mtk nl80211 vendor cmd*/
7714 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7715 param.if_type = NL80211_ATTR_IFINDEX;
7716 param.if_idx = if_idx;
7717 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7718 if (ret) {
7719 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7720 return RETURN_ERR;
7721 }
7722 /*add mtk vendor cmd data*/
7723 if (filterMode == 0) {
7724 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
7725 } else if (filterMode == 1) {
7726 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
7727 } else if (filterMode == 2) {
7728 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
7729 } else {
7730 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
7731 nlmsg_free(msg);
7732 goto err;
7733 }
7734 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
7735 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7736 nlmsg_free(msg);
7737 goto err;
7738 }
7739 /*send mtk nl80211 vendor msg*/
7740 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7741 if (ret) {
7742 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7743 goto err;
7744 }
7745 /*deinit mtk nl80211 vendor msg*/
7746 mtk_nl80211_deint(&unl_ins);
7747 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08007748 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007749err:
7750 mtk_nl80211_deint(&unl_ins);
7751 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7752 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007753}
7754
7755// 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.
7756INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
7757{
7758 return RETURN_ERR;
7759}
7760
7761// gets the vlan ID for this ap from an internal enviornment variable
7762INT wifi_getApVlanID(INT apIndex, INT *output_int)
7763{
7764 if(apIndex==0)
7765 {
7766 *output_int=100;
7767 return RETURN_OK;
7768 }
7769
7770 return RETURN_ERR;
7771}
7772
7773// sets the vlan ID for this ap to an internal enviornment variable
7774INT wifi_setApVlanID(INT apIndex, INT vlanId)
7775{
7776 //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)
7777 return RETURN_ERR;
7778}
7779
7780// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
7781INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
7782{
7783 snprintf(bridgeName, 32, "brlan0");
7784 snprintf(IP, 32, "10.0.0.1");
7785 snprintf(subnet, 32, "255.255.255.0");
7786
7787 return RETURN_OK;
7788}
7789
7790//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
7791INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
7792{
7793 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
7794 return RETURN_ERR;
7795}
7796
7797// reset the vlan configuration for this ap
7798INT wifi_resetApVlanCfg(INT apIndex)
7799{
developera1255e42023-05-13 17:45:02 +08007800 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08007801 int if_idx, ret = 0;
7802 struct nl_msg *msg = NULL;
7803 struct nlattr * msg_data = NULL;
7804 struct mtk_nl80211_param param;
7805 struct unl unl_ins;
7806 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08007807
developer2202b332023-05-24 16:23:22 +08007808 if (apIndex > MAX_APS) {
7809 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
7810 return RETURN_ERR;
7811 }
developer72fb0bb2023-01-11 09:46:29 +08007812
developer2202b332023-05-24 16:23:22 +08007813 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7814 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7815 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007816
developer2202b332023-05-24 16:23:22 +08007817 /*step 1. mwctl dev %s set vlan_tag 0*/
7818 if_idx = if_nametoindex(interface_name);
7819 /*init mtk nl80211 vendor cmd*/
7820 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
7821 param.if_type = NL80211_ATTR_IFINDEX;
7822 param.if_idx = if_idx;
7823 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08007824
developer2202b332023-05-24 16:23:22 +08007825 if (ret) {
7826 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7827 return RETURN_ERR;
7828 }
developer72fb0bb2023-01-11 09:46:29 +08007829
developer2202b332023-05-24 16:23:22 +08007830 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
7831 printf("Nla put attribute error\n");
7832 nlmsg_free(msg);
7833 goto err;
7834 }
developer72fb0bb2023-01-11 09:46:29 +08007835
developer2202b332023-05-24 16:23:22 +08007836 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7837 if (ret) {
7838 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7839 goto err;
7840 }
7841 mtk_nl80211_deint(&unl_ins);
7842 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08007843
developer2202b332023-05-24 16:23:22 +08007844 /*step 2. mwctl dev %s set vlan_priority 0*/
7845 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7846 if (ret) {
7847 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7848 return RETURN_ERR;
7849 }
developer72fb0bb2023-01-11 09:46:29 +08007850
developer2202b332023-05-24 16:23:22 +08007851 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
7852 printf("Nla put attribute error\n");
7853 nlmsg_free(msg);
7854 goto err;
7855 }
developer72fb0bb2023-01-11 09:46:29 +08007856
developer2202b332023-05-24 16:23:22 +08007857 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7858 if (ret) {
7859 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7860 goto err;
7861 }
7862 mtk_nl80211_deint(&unl_ins);
7863 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
7864
7865 /*step 3. mwctl dev %s set vlan_id 0*/
7866 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7867 if (ret) {
7868 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08007869 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08007870 }
developer72fb0bb2023-01-11 09:46:29 +08007871
developer2202b332023-05-24 16:23:22 +08007872 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
7873 printf("Nla put attribute error\n");
7874 nlmsg_free(msg);
7875 goto err;
7876 }
7877
7878 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7879 if (ret) {
7880 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7881 goto err;
7882 }
7883 mtk_nl80211_deint(&unl_ins);
7884 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
7885
7886 /*step 4. mwctl dev %s set vlan_en 0*/
7887 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7888 if (ret) {
7889 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7890 return RETURN_ERR;
7891 }
7892
7893 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
7894 printf("Nla put attribute error\n");
7895 nlmsg_free(msg);
7896 goto err;
7897 }
7898
7899 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7900 if (ret) {
7901 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7902 goto err;
7903 }
7904 mtk_nl80211_deint(&unl_ins);
7905 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
7906
7907 /*step 5. mwctl dev %s set vlan_policy 0:4*/
7908 vlan_param.direction = 0;
7909 vlan_param.policy = 4;
7910 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7911 if (ret) {
7912 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7913 return RETURN_ERR;
7914 }
7915 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
7916 printf("Nla put attribute error\n");
7917 nlmsg_free(msg);
7918 goto err;
7919 }
7920
7921 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7922 if (ret) {
7923 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7924 goto err;
7925 }
7926 mtk_nl80211_deint(&unl_ins);
7927 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
7928
7929 /*step 6. mwctl dev %s set vlan_policy 1:0*/
7930 vlan_param.direction = 1;
7931 vlan_param.policy = 0;
7932 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7933 if (ret) {
7934 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7935 return RETURN_ERR;
7936 }
7937
7938 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
7939 printf("Nla put attribute error\n");
7940 nlmsg_free(msg);
7941 goto err;
7942 }
7943
7944 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7945 if (ret) {
7946 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
7947 goto err;
7948 }
7949 /*deinit mtk nl80211 vendor msg*/
7950 mtk_nl80211_deint(&unl_ins);
7951 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
7952
7953 /*TODO need to modify VLAN config in dat file*/
7954 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7955
7956 return RETURN_OK;
7957err:
7958 mtk_nl80211_deint(&unl_ins);
7959 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7960 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007961}
7962
7963// 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.
7964INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
7965{
7966 return RETURN_ERR;
7967}
7968
7969// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
7970INT wifi_startHostApd()
7971{
7972 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7973 system("systemctl start hostapd.service");
7974 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7975 return RETURN_OK;
7976 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
7977}
7978
7979// stops hostapd
developer69b61b02023-03-07 17:17:44 +08007980INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08007981{
7982 char cmd[128] = {0};
7983 char buf[128] = {0};
7984
7985 sprintf(cmd,"systemctl stop hostapd");
7986 _syscmd(cmd, buf, sizeof(buf));
7987
7988 return RETURN_OK;
7989}
7990
7991// restart hostapd dummy function
7992INT wifi_restartHostApd()
7993{
7994 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7995 system("systemctl restart hostapd-global");
7996 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7997
developer72fb0bb2023-01-11 09:46:29 +08007998 return RETURN_OK;
7999}
8000
8001// sets the AP enable status variable for the specified ap.
8002INT wifi_setApEnable(INT apIndex, BOOL enable)
8003{
developer7e4a2a62023-04-06 19:56:03 +08008004 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +08008005 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer7e4a2a62023-04-06 19:56:03 +08008006 char cmd[MAX_CMD_SIZE] = {0};
8007 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008008 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08008009 int max_radio_num = 0;
8010 int phyId = 0;
developer72fb0bb2023-01-11 09:46:29 +08008011
developer7e4a2a62023-04-06 19:56:03 +08008012 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08008013
developer7e4a2a62023-04-06 19:56:03 +08008014 wifi_getMaxRadioNumber(&max_radio_num);
8015 if (enable == status)
8016 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008017
developer7e4a2a62023-04-06 19:56:03 +08008018 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8019 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008020
developer7e4a2a62023-04-06 19:56:03 +08008021 if (enable == TRUE) {
8022 int radioIndex = apIndex % max_radio_num;
8023 phyId = radio_index_to_phy(radioIndex);
developerf3c7d292023-05-29 17:57:16 +08008024 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
8025 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08008026
developer7e4a2a62023-04-06 19:56:03 +08008027 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
8028 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
8029 _syscmd(cmd, buf, sizeof(buf));
8030 } else {
8031 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8032 _syscmd(cmd, buf, sizeof(buf));
developerf3c7d292023-05-29 17:57:16 +08008033 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
8034 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +08008035 }
8036 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
8037 interface_name, interface_name, enable, VAP_STATUS_FILE);
8038 _syscmd(cmd, buf, sizeof(buf));
8039 //Wait for wifi up/down to apply
8040 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008041}
8042
8043// Outputs the setting of the internal variable that is set by wifi_setApEnable().
8044INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
8045{
developer7e4a2a62023-04-06 19:56:03 +08008046 char interface_name[IF_NAME_SIZE] = {0};
8047 char cmd[MAX_CMD_SIZE] = {0};
developere740c2a2023-05-23 18:34:32 +08008048 int ret;
developer72fb0bb2023-01-11 09:46:29 +08008049
developer7e4a2a62023-04-06 19:56:03 +08008050 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
8051 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008052
developer7e4a2a62023-04-06 19:56:03 +08008053 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08008054
developer7e4a2a62023-04-06 19:56:03 +08008055 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
8056 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8057 *output_bool = FALSE;
8058 return RETURN_OK;
8059 }
developere740c2a2023-05-23 18:34:32 +08008060 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status", interface_name);
8061 ret = system(cmd);
8062 if (ret == 0)
8063 *output_bool = 1;
developer7e4a2a62023-04-06 19:56:03 +08008064 }
developer72fb0bb2023-01-11 09:46:29 +08008065
developer7e4a2a62023-04-06 19:56:03 +08008066 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008067}
8068
developer69b61b02023-03-07 17:17:44 +08008069// Outputs the AP "Enabled" "Disabled" status from driver
8070INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08008071{
developer7e4a2a62023-04-06 19:56:03 +08008072 BOOL output_bool;
developer72fb0bb2023-01-11 09:46:29 +08008073
developer7e4a2a62023-04-06 19:56:03 +08008074 if (!output_string) {
8075 printf("%s: null pointer!", __func__);
8076 return RETURN_ERR;
8077 }
developer72fb0bb2023-01-11 09:46:29 +08008078
developer7e4a2a62023-04-06 19:56:03 +08008079 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08008080
developer7e4a2a62023-04-06 19:56:03 +08008081 if(output_bool == 1)
8082 snprintf(output_string, 32, "Up");
8083 else
8084 snprintf(output_string, 32, "Disable");
8085
8086 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008087}
8088
8089//Indicates whether or not beacons include the SSID name.
8090// outputs a 1 if SSID on the AP is enabled, else outputs 0
8091INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
8092{
8093 //get the running status
8094 char config_file[MAX_BUF_SIZE] = {0};
8095 char buf[16] = {0};
8096
8097 if (!output)
8098 return RETURN_ERR;
8099
8100 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8101 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
8102 // default is enable
8103 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
8104 *output = TRUE;
8105
8106 return RETURN_OK;
8107}
8108
8109// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
8110INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
8111{
8112 //store the config, apply instantly
8113 char config_file[MAX_BUF_SIZE] = {0};
8114 struct params list;
8115
8116 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8117 list.name = "ignore_broadcast_ssid";
8118 list.value = enable?"0":"1";
8119
8120 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8121 wifi_hostapdWrite(config_file, &list, 1);
8122 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8123 //TODO: call hostapd_cli for dynamic_config_control
8124 wifi_reloadAp(apIndex);
8125 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8126
8127 return RETURN_OK;
8128}
8129
8130//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
8131INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
8132{
developer47cc27a2023-05-17 23:09:58 +08008133 /* get the running status */
8134 if(!output_uint)
8135 return RETURN_ERR;
8136
8137 *output_uint = 15;
8138 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008139}
8140
developer47cc27a2023-05-17 23:09:58 +08008141/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +08008142INT wifi_setApRetryLimit(INT apIndex, UINT number)
8143{
developer47cc27a2023-05-17 23:09:58 +08008144 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008145}
8146
developer95c045d2023-05-24 19:26:28 +08008147int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
8148{
8149 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8150 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
8151 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
developer2f79c922023-06-02 17:33:42 +08008152 unsigned char *status = (unsigned char *)data;
developer95c045d2023-05-24 19:26:28 +08008153 int err = 0;
developer95c045d2023-05-24 19:26:28 +08008154
8155 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8156 genlmsg_attrlen(gnlh, 0), NULL);
8157 if (err < 0)
8158 return err;
8159
8160 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8161 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
8162 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8163 if (err < 0)
8164 return err;
8165
8166 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
developer95c045d2023-05-24 19:26:28 +08008167 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
8168 }
8169 }
8170
8171 return 0;
8172}
8173
developer72fb0bb2023-01-11 09:46:29 +08008174//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
8175INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
8176{
developer95c045d2023-05-24 19:26:28 +08008177 int if_idx, ret = 0;
developer8e6583c2023-05-23 13:36:06 +08008178 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08008179 unsigned char status = 0;
8180 struct nl_msg *msg = NULL;
8181 struct nlattr * msg_data = NULL;
8182 struct mtk_nl80211_param param;
8183 struct unl unl_ins;
developer8e6583c2023-05-23 13:36:06 +08008184
8185 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008186 if(!output)
developerdaf24792023-06-06 11:40:04 +08008187 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008188
developer95c045d2023-05-24 19:26:28 +08008189 if (apIndex > MAX_APS) {
8190 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8191 return RETURN_ERR;
8192 }
8193
developer8e6583c2023-05-23 13:36:06 +08008194 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developerdaf24792023-06-06 11:40:04 +08008195 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +08008196
8197 if_idx = if_nametoindex(interface_name);
8198 /*init mtk nl80211 vendor cmd*/
8199 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8200 param.if_type = NL80211_ATTR_IFINDEX;
8201 param.if_idx = if_idx;
8202 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8203
8204 if (ret) {
8205 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8206 return RETURN_ERR;
8207 }
8208
8209 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
8210 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8211 nlmsg_free(msg);
8212 goto err;
8213 }
8214
8215 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
8216 (void *)&status);
8217 if (ret) {
8218 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8219 goto err;
8220 }
8221 mtk_nl80211_deint(&unl_ins);
8222
8223 *output = status == 0 ? FALSE : TRUE;
8224 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +08008225
8226 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008227 return RETURN_OK;
developer95c045d2023-05-24 19:26:28 +08008228err:
8229 mtk_nl80211_deint(&unl_ins);
8230 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8231 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008232}
8233
8234//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
8235INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
8236{
8237 //get the running status from driver
8238 char cmd[128] = {0};
8239 char buf[128] = {0};
8240 int max_radio_num = 0, radioIndex = 0;
8241 int phyId = 0;
8242
8243 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8244
8245 wifi_getMaxRadioNumber(&max_radio_num);
8246 radioIndex = apIndex % max_radio_num;
8247 phyId = radio_index_to_phy(radioIndex);
8248 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
8249 _syscmd(cmd,buf, sizeof(buf));
8250
8251 if (strlen(buf) > 0)
8252 *output = true;
8253
8254 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8255
8256 return RETURN_OK;
8257}
8258
8259//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
8260INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
8261{
developer95c045d2023-05-24 19:26:28 +08008262 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +08008263}
8264
8265// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
8266INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
8267{
developer95c045d2023-05-24 19:26:28 +08008268 int if_idx, ret = 0;
8269 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08008270 struct nl_msg *msg = NULL;
8271 struct nlattr * msg_data = NULL;
8272 struct mtk_nl80211_param param;
8273 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +08008274
developer95c045d2023-05-24 19:26:28 +08008275 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008276
developer95c045d2023-05-24 19:26:28 +08008277 if (apIndex > MAX_APS) {
8278 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8279 return RETURN_ERR;
8280 }
developer72fb0bb2023-01-11 09:46:29 +08008281
developer95c045d2023-05-24 19:26:28 +08008282 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8283 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008284
developer95c045d2023-05-24 19:26:28 +08008285 if_idx = if_nametoindex(interface_name);
8286 /*init mtk nl80211 vendor cmd*/
8287 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8288 param.if_type = NL80211_ATTR_IFINDEX;
8289 param.if_idx = if_idx;
8290 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8291
8292 if (ret) {
8293 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8294 return RETURN_ERR;
8295 }
8296
8297 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
8298 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8299 nlmsg_free(msg);
8300 goto err;
8301 }
8302
8303 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8304 if (ret) {
8305 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8306 goto err;
8307 }
8308 mtk_nl80211_deint(&unl_ins);
8309
8310 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8311 return RETURN_OK;
8312err:
8313 mtk_nl80211_deint(&unl_ins);
8314 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8315 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008316}
8317
developer95c045d2023-05-24 19:26:28 +08008318
developer72fb0bb2023-01-11 09:46:29 +08008319//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.
8320INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
8321{
8322 //get the running status from driver
8323 if(!output)
8324 return RETURN_ERR;
8325
8326 char config_file[128] = {0};
8327 char buf[16] = {0};
8328
8329 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8330 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
8331 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
8332 *output = TRUE;
8333 else
8334 *output = FALSE;
8335
8336 return RETURN_OK;
8337}
8338
8339// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
8340INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
8341{
8342 //save config and apply instantly.
8343 char config_file[MAX_BUF_SIZE] = {0};
8344 struct params list;
8345
8346 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8347 list.name = "uapsd_advertisement_enabled";
8348 list.value = enable?"1":"0";
8349
8350 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8351 wifi_hostapdWrite(config_file, &list, 1);
8352 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developere82c0ca2023-05-10 16:25:35 +08008353 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008354 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8355
8356 return RETURN_OK;
8357}
8358
8359// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
8360INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
8361{
8362 char interface_name[16] = {0};
8363 // assume class 0->BE, 1->BK, 2->VI, 3->VO
developerb149d9d2023-06-06 16:14:22 +08008364 char cmd[MAX_CMD_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008365 char buf[128] = {0};
8366 char ack_filepath[128] = {0};
8367 uint16_t bitmap = 0;
8368 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
8369 FILE *f = NULL;
8370
8371 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
8372
8373 // Get current setting
8374 snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
8375 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
8376 _syscmd(cmd, buf, sizeof(buf));
8377 if (strlen(buf) > 0)
8378 bitmap = strtoul(buf, NULL, 10);
8379
8380 bitmap = strtoul(buf, NULL, 10);
8381
8382 if (ackPolicy == TRUE) { // True, unset this class
8383 bitmap &= ~class_map[class];
8384 } else { // False, set this class
8385 bitmap |= class_map[class];
8386 }
8387
8388 f = fopen(ack_filepath, "w");
8389 if (f == NULL) {
8390 fprintf(stderr, "%s: fopen failed\n", __func__);
8391 return RETURN_ERR;
8392 }
8393 fprintf(f, "%hu", bitmap);
8394 fclose(f);
8395
8396 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8397 return RETURN_ERR;
8398 snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
8399 _syscmd(cmd, buf, sizeof(buf));
8400
8401 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
8402 return RETURN_OK;
8403}
8404
8405//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.
8406INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
8407{
8408 //get the running status from driver
8409 if(!output_uint)
8410 return RETURN_ERR;
8411
8412 char output[16]={'\0'};
8413 char config_file[MAX_BUF_SIZE] = {0};
8414
8415 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8416 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
8417 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
8418 else {
8419 int device_num = atoi(output);
8420 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
8421 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
8422 return RETURN_ERR;
8423 }
8424 else {
8425 *output_uint = device_num;
8426 }
8427 }
8428
8429 return RETURN_OK;
8430}
8431
8432INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
8433{
8434 //store to wifi config, apply instantly
8435 char str[MAX_BUF_SIZE]={'\0'};
developer72fb0bb2023-01-11 09:46:29 +08008436 struct params params;
8437 char config_file[MAX_BUF_SIZE] = {0};
8438
8439 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8440 if (number > MAX_ASSOCIATED_STA_NUM) {
8441 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
8442 return RETURN_ERR;
8443 }
8444 sprintf(str, "%d", number);
8445 params.name = "max_num_sta";
8446 params.value = str;
8447
8448 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
8449 int ret = wifi_hostapdWrite(config_file, &params, 1);
8450 if (ret) {
8451 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
8452 ,__func__, ret);
8453 }
8454
8455 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
8456 if (ret) {
8457 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
8458 ,__func__, ret);
8459 }
8460 wifi_reloadAp(apIndex);
8461 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8462
8463 return RETURN_OK;
8464}
8465
8466//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.
8467INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
8468{
8469 //get the current threshold
8470 if(!output_uint)
8471 return RETURN_ERR;
8472 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
8473 if (*output_uint == 0)
8474 *output_uint = 50;
8475 return RETURN_OK;
8476}
8477
8478INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
8479{
8480 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
8481 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
8482 return RETURN_OK;
8483 return RETURN_ERR;
8484}
8485
8486//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.
8487INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
8488{
8489 if(!output_uint)
8490 return RETURN_ERR;
8491 *output_uint = 3;
8492 return RETURN_OK;
8493}
8494
8495//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
8496INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
8497{
8498 if(!output_uint)
8499 return RETURN_ERR;
8500 *output_uint = 3;
8501 return RETURN_OK;
8502}
8503
8504//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.
8505INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
8506{
8507 if(!output_in_seconds)
8508 return RETURN_ERR;
8509 *output_in_seconds = 0;
8510 return RETURN_OK;
8511}
8512
8513//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
8514INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
8515{
8516 if(!output || apIndex>=MAX_APS)
8517 return RETURN_ERR;
8518 //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
8519 snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
8520 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008521}
developer72fb0bb2023-01-11 09:46:29 +08008522
8523//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
8524INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
8525{
8526 char config_file[128] = {0};
8527 char wpa[16] = {0};
8528 char key_mgmt[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08008529 if (!output)
8530 return RETURN_ERR;
8531
8532 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8533 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
8534
8535 strcpy(output, "None");//Copying "None" to output string for default case
8536 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
8537 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
8538 if (!strcmp(wpa, "1"))
8539 snprintf(output, 32, "WPA-Personal");
8540 else if (!strcmp(wpa, "2"))
8541 snprintf(output, 32, "WPA2-Personal");
8542 else if (!strcmp(wpa, "3"))
8543 snprintf(output, 32, "WPA-WPA2-Personal");
8544
developere5750452023-05-15 16:46:42 +08008545 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
8546 snprintf(output, 32, "WPA3-Enterprise");
developer72fb0bb2023-01-11 09:46:29 +08008547 } else if (strstr(key_mgmt, "WPA-EAP")) {
8548 if (!strcmp(wpa, "1"))
8549 snprintf(output, 32, "WPA-Enterprise");
8550 else if (!strcmp(wpa, "2"))
8551 snprintf(output, 32, "WPA2-Enterprise");
8552 else if (!strcmp(wpa, "3"))
8553 snprintf(output, 32, "WPA-WPA2-Enterprise");
8554 } else if (strstr(key_mgmt, "SAE")) {
8555 if (strstr(key_mgmt, "WPA-PSK") == NULL)
8556 snprintf(output, 32, "WPA3-Personal");
8557 else
8558 snprintf(output, 32, "WPA3-Personal-Transition");
developer72fb0bb2023-01-11 09:46:29 +08008559 }
8560
8561 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8562 return RETURN_OK;
8563#if 0
8564 //TODO: need to revisit below implementation
8565 char securityType[32], authMode[32];
8566 int enterpriseMode=0;
8567
8568 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8569 if(!output)
8570 return RETURN_ERR;
8571
8572 wifi_getApBeaconType(apIndex, securityType);
8573 strcpy(output,"None");//By default, copying "None" to output string
8574 if (strncmp(securityType,"None", strlen("None")) == 0)
8575 return RETURN_OK;
8576
8577 wifi_getApBasicAuthenticationMode(apIndex, authMode);
8578 enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0;
8579
8580 if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0)
8581 snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal");
8582 else if (strncmp(securityType, "WPA", strlen("WPA")) == 0)
8583 snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal");
8584 else if (strncmp(securityType, "11i", strlen("11i")) == 0)
8585 snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal");
8586 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8587
8588 return RETURN_OK;
8589#endif
8590}
developer69b61b02023-03-07 17:17:44 +08008591
developer72fb0bb2023-01-11 09:46:29 +08008592INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
8593{
8594 char securityType[32];
8595 char authMode[32];
8596
8597 //store settings and wait for wifi up to apply
8598 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8599 if(!encMode)
8600 return RETURN_ERR;
8601
8602 if (strcmp(encMode, "None")==0)
8603 {
8604 strcpy(securityType,"None");
8605 strcpy(authMode,"None");
8606 }
8607 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
8608 {
8609 strcpy(securityType,"WPAand11i");
8610 strcpy(authMode,"PSKAuthentication");
8611 }
8612 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
8613 {
8614 strcpy(securityType,"WPAand11i");
8615 strcpy(authMode,"EAPAuthentication");
8616 }
8617 else if (strcmp(encMode, "WPA-Personal")==0)
8618 {
8619 strcpy(securityType,"WPA");
8620 strcpy(authMode,"PSKAuthentication");
8621 }
8622 else if (strcmp(encMode, "WPA-Enterprise")==0)
8623 {
8624 strcpy(securityType,"WPA");
8625 strcpy(authMode,"EAPAuthentication");
8626 }
8627 else if (strcmp(encMode, "WPA2-Personal")==0)
8628 {
8629 strcpy(securityType,"11i");
8630 strcpy(authMode,"PSKAuthentication");
8631 }
8632 else if (strcmp(encMode, "WPA2-Enterprise")==0)
8633 {
8634 strcpy(securityType,"11i");
8635 strcpy(authMode,"EAPAuthentication");
8636 }
8637 else if (strcmp(encMode, "WPA3-Personal") == 0)
8638 {
8639 strcpy(securityType,"11i");
8640 strcpy(authMode,"SAEAuthentication");
8641 }
8642 else if (strcmp(encMode, "WPA3-Personal-Transition") == 0)
8643 {
8644 strcpy(securityType, "11i");
8645 strcpy(authMode, "PSK-SAEAuthentication");
8646 }
8647 else if (strcmp(encMode, "WPA3-Enterprise") == 0)
8648 {
8649 strcpy(securityType,"11i");
8650 strcpy(authMode,"EAP_192-bit_Authentication");
8651 }
developer3086e2f2023-01-17 09:40:01 +08008652 else if (strcmp(encMode, "OWE") == 0)
8653 {
8654 strcpy(securityType,"11i");
8655 strcpy(authMode,"Enhanced_Open");
8656 }
developer72fb0bb2023-01-11 09:46:29 +08008657 else
8658 {
8659 strcpy(securityType,"None");
8660 strcpy(authMode,"None");
8661 }
8662 wifi_setApBeaconType(apIndex, securityType);
8663 wifi_setApBasicAuthenticationMode(apIndex, authMode);
8664 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8665
8666 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008667}
developer72fb0bb2023-01-11 09:46:29 +08008668
8669
8670//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
8671// output_string must be pre-allocated as 64 character string by caller
8672// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8673INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
8674{
8675 char buf[16] = {0};
8676 char config_file[MAX_BUF_SIZE] = {0};
8677
8678 if(output_string==NULL)
8679 return RETURN_ERR;
8680
8681 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8682 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8683
8684 if(strcmp(buf,"0")==0)
8685 {
8686 printf("wpa_mode is %s ......... \n",buf);
8687 return RETURN_ERR;
8688 }
8689
8690 wifi_dbg_printf("\nFunc=%s\n",__func__);
8691 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
developere5750452023-05-15 16:46:42 +08008692 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developer72fb0bb2023-01-11 09:46:29 +08008693 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8694
8695 return RETURN_OK;
8696}
8697
8698// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
8699// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8700INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
8701{
8702 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8703 struct params params={'\0'};
8704 int ret;
8705 char config_file[MAX_BUF_SIZE] = {0};
8706
8707 if(NULL == preSharedKey)
8708 return RETURN_ERR;
8709
developere5750452023-05-15 16:46:42 +08008710 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +08008711
developere5750452023-05-15 16:46:42 +08008712 if(strlen(preSharedKey) != 64)
developer72fb0bb2023-01-11 09:46:29 +08008713 {
developere5750452023-05-15 16:46:42 +08008714 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
developer72fb0bb2023-01-11 09:46:29 +08008715 return RETURN_ERR;
8716 }
8717 params.value = preSharedKey;
8718 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8719 ret = wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +08008720 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08008721 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008722 wifi_reloadAp(apIndex);
8723 }
developer72fb0bb2023-01-11 09:46:29 +08008724 return ret;
8725 //TODO: call hostapd_cli for dynamic_config_control
8726}
8727
8728//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
8729// outputs the passphrase, maximum 63 characters
8730INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
8731{
8732 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
8733
8734 wifi_dbg_printf("\nFunc=%s\n",__func__);
8735 if (NULL == output_string)
8736 return RETURN_ERR;
8737
8738 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8739 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8740 if(strcmp(buf,"0")==0)
8741 {
8742 printf("wpa_mode is %s ......... \n",buf);
8743 return RETURN_ERR;
8744 }
8745
8746 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
8747 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8748
8749 return RETURN_OK;
8750}
8751
8752// sets the passphrase enviornment variable, max 63 characters
8753INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
8754{
8755 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8756 struct params params={'\0'};
8757 char config_file[MAX_BUF_SIZE] = {0};
8758 int ret;
8759
8760 if(NULL == passPhrase)
8761 return RETURN_ERR;
8762
8763 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
8764 {
8765 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
8766 return RETURN_ERR;
8767 }
8768 params.name = "wpa_passphrase";
8769 params.value = passPhrase;
8770 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8771 ret=wifi_hostapdWrite(config_file,&params,1);
developere5750452023-05-15 16:46:42 +08008772 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08008773 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008774 wifi_reloadAp(apIndex);
8775 }
developer72fb0bb2023-01-11 09:46:29 +08008776
8777 return ret;
8778}
8779
8780//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.
8781INT wifi_setApSecurityReset(INT apIndex)
8782{
8783 char original_config_file[64] = {0};
8784 char current_config_file[64] = {0};
8785 char buf[64] = {0};
8786 char cmd[64] = {0};
8787 char wpa[4] = {0};
8788 char wpa_psk[64] = {0};
8789 char wpa_passphrase[64] = {0};
8790 char wpa_psk_file[128] = {0};
8791 char wpa_key_mgmt[64] = {0};
8792 char wpa_pairwise[32] = {0};
8793 wifi_band band;
8794 struct params list[6];
8795
8796 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8797
8798 band = wifi_index_to_band(apIndex);
8799 if (band == band_2_4)
8800 sprintf(original_config_file, "/etc/hostapd-2G.conf");
8801 else if (band == band_5)
8802 sprintf(original_config_file, "/etc/hostapd-5G.conf");
8803 else if (band == band_6)
8804 sprintf(original_config_file, "/etc/hostapd-6G.conf");
8805 else
8806 return RETURN_ERR;
8807
8808 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
8809 list[0].name = "wpa";
8810 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +08008811
developer72fb0bb2023-01-11 09:46:29 +08008812 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
8813 list[1].name = "wpa_psk";
8814 list[1].value = wpa_psk;
8815
8816 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
8817 list[2].name = "wpa_passphrase";
8818 list[2].value = wpa_passphrase;
8819
8820 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
8821
8822 if (strlen(wpa_psk_file) == 0)
8823 strcpy(wpa_psk_file, PSK_FILE);
8824
8825 if (access(wpa_psk_file, F_OK) != 0) {
developerdaf24792023-06-06 11:40:04 +08008826 snprintf(cmd, MAX_CMD_SIZE, "touch %s", wpa_psk_file);
developer72fb0bb2023-01-11 09:46:29 +08008827 _syscmd(cmd, buf, sizeof(buf));
8828 }
8829 list[3].name = "wpa_psk_file";
8830 list[3].value = wpa_psk_file;
8831
8832 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
8833 list[4].name = "wpa_key_mgmt";
8834 list[4].value = wpa_key_mgmt;
8835
8836 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
8837 list[5].name = "wpa_pairwise";
8838 list[5].value = wpa_pairwise;
8839
8840 sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8841 wifi_hostapdWrite(current_config_file, list, 6);
8842
8843 wifi_setApEnable(apIndex, FALSE);
8844 wifi_setApEnable(apIndex, TRUE);
8845
8846 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8847 return RETURN_OK;
8848}
8849
8850//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).
8851INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
8852{
8853 char config_file[64] = {0};
8854 char buf[64] = {0};
8855 char cmd[256] = {0};
8856
8857 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8858
8859 if(!IP_output || !Port_output || !RadiusSecret_output)
8860 return RETURN_ERR;
8861
8862 // Read the first matched config
8863 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8864 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
8865 _syscmd(cmd, buf, sizeof(buf));
8866 strncpy(IP_output, buf, 64);
8867
8868 memset(buf, 0, sizeof(buf));
8869 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
8870 _syscmd(cmd, buf, sizeof(buf));
8871 *Port_output = atoi(buf);
8872
8873 memset(buf, 0, sizeof(buf));
8874 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
8875 _syscmd(cmd, buf, sizeof(buf));
8876 strncpy(RadiusSecret_output, buf, 64);
8877
8878 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8879 return RETURN_OK;
8880}
8881
8882INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
8883{
8884 char config_file[64] = {0};
8885 char port_str[8] = {0};
8886 char cmd[256] = {0};
8887 char buf[128] = {0};
8888
8889 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8890
developere5750452023-05-15 16:46:42 +08008891 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
8892 return RETURN_ERR;
8893
8894 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
8895 return RETURN_ERR;
8896
developer72fb0bb2023-01-11 09:46:29 +08008897 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8898
8899 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
8900 _syscmd(cmd, buf, sizeof(buf));
8901 memset(cmd, 0, sizeof(cmd));
8902
8903 snprintf(port_str, sizeof(port_str), "%d", port);
8904 if (strlen(buf) == 0)
8905 // Append
8906 snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
8907 "auth_server_addr=%s\\n"
8908 "auth_server_port=%s\\n"
8909 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
8910 else {
8911 // Delete the three lines setting after the "# radius 1" comment
8912 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
8913 _syscmd(cmd, buf, sizeof(buf));
8914 memset(cmd, 0, sizeof(cmd));
8915 // Use "# radius 1" comment to find the location to insert the radius setting
8916 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
8917 "# radius 1\\n"
8918 "auth_server_addr=%s\\n"
8919 "auth_server_port=%s\\n"
8920 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
8921 }
8922 if(_syscmd(cmd, buf, sizeof(buf))) {
8923 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
8924 return RETURN_ERR;
8925 }
8926
8927 wifi_reloadAp(apIndex);
8928 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8929 return RETURN_OK;
8930}
8931
8932INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
8933{
8934 char config_file[64] = {0};
8935 char buf[64] = {0};
8936 char cmd[256] = {0};
8937
8938 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8939
8940 if(!IP_output || !Port_output || !RadiusSecret_output)
8941 return RETURN_ERR;
8942
8943 // Read the second matched config
8944 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8945 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
8946 _syscmd(cmd, buf, sizeof(buf));
8947 strncpy(IP_output, buf, 64);
8948
8949 memset(buf, 0, sizeof(buf));
8950 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
8951 _syscmd(cmd, buf, sizeof(buf));
8952 *Port_output = atoi(buf);
8953
8954 memset(buf, 0, sizeof(buf));
8955 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
8956 _syscmd(cmd, buf, sizeof(buf));
8957 strncpy(RadiusSecret_output, buf, 64);
8958
8959 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8960 return RETURN_OK;
8961}
8962
8963INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
8964{
8965 char config_file[64] = {0};
8966 char port_str[8] = {0};
8967 char cmd[256] = {0};
8968 char buf[128] = {0};
8969
8970 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8971
developere5750452023-05-15 16:46:42 +08008972 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
8973 return RETURN_ERR;
8974
8975 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
8976 return RETURN_ERR;
8977
developer72fb0bb2023-01-11 09:46:29 +08008978 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
8979
8980 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
8981 _syscmd(cmd, buf, sizeof(buf));
8982 memset(cmd, 0, sizeof(cmd));
8983
8984 snprintf(port_str, sizeof(port_str), "%d", port);
8985 if (strlen(buf) == 0)
8986 // Append
8987 snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
8988 "auth_server_addr=%s\\n"
8989 "auth_server_port=%s\\n"
8990 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
8991 else {
8992 // Delete the three lines setting after the "# radius 2" comment
8993 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
8994 _syscmd(cmd, buf, sizeof(buf));
8995 memset(cmd, 0, sizeof(cmd));
8996 // Use "# radius 2" comment to find the location to insert the radius setting
8997 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
8998 "# radius 2\\n"
8999 "auth_server_addr=%s\\n"
9000 "auth_server_port=%s\\n"
9001 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9002 }
9003 if(_syscmd(cmd, buf, sizeof(buf))) {
9004 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9005 return RETURN_ERR;
9006 }
9007
9008 wifi_reloadAp(apIndex);
9009 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9010 return RETURN_OK;
9011}
9012
9013//RadiusSettings
9014INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
9015{
9016 if(!output)
9017 return RETURN_ERR;
9018
9019 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
developer69b61b02023-03-07 17:17:44 +08009020 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
9021 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
9022 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
9023 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
developer72fb0bb2023-01-11 09:46:29 +08009024 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.
developer69b61b02023-03-07 17:17:44 +08009025 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
9026 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
9027 output->QuietPeriodAfterFailedAuthentication = 5; //The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it.
developer72fb0bb2023-01-11 09:46:29 +08009028 //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.
9029
9030 return RETURN_OK;
9031}
9032
9033INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
9034{
9035 //store the paramters, and apply instantly
9036 return RETURN_ERR;
9037}
9038
9039//Device.WiFi.AccessPoint.{i}.WPS.Enable
9040//Enables or disables WPS functionality for this access point.
9041// outputs the WPS enable state of this ap in output_bool
9042INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
9043{
9044 char interface_name[16] = {0};
developer2f79c922023-06-02 17:33:42 +08009045 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009046 if(!output_bool)
9047 return RETURN_ERR;
9048 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9049 return RETURN_ERR;
9050 sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name);
9051 _syscmd(cmd, buf, sizeof(buf));
9052 if(strstr(buf, "configured"))
9053 *output_bool=TRUE;
9054 else
9055 *output_bool=FALSE;
9056
9057 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08009058}
developer72fb0bb2023-01-11 09:46:29 +08009059
9060//Device.WiFi.AccessPoint.{i}.WPS.Enable
9061// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
9062INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
9063{
9064 char config_file[MAX_BUF_SIZE] = {0};
developere5750452023-05-15 16:46:42 +08009065 char buf[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009066 struct params params;
9067
9068 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9069 //store the paramters, and wait for wifi up to apply
9070 params.name = "wps_state";
developere5750452023-05-15 16:46:42 +08009071 if (enable == TRUE) {
9072 wifi_getApBeaconType(apIndex, buf);
9073 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
9074 params.value = "1";
9075 else // If ap set encryption
9076 params.value = "2";
9077 } else {
9078 params.value = "0";
9079 }
developer72fb0bb2023-01-11 09:46:29 +08009080
9081 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9082 wifi_hostapdWrite(config_file, &params, 1);
9083 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9084 wifi_reloadAp(apIndex);
9085
9086 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9087 return RETURN_OK;
9088}
9089
9090//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
9091INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
9092{
9093 if(!output)
9094 return RETURN_ERR;
9095 snprintf(output, 128, "PushButton,PIN");
9096 return RETURN_OK;
9097}
9098
9099//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9100//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.
9101// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
9102INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
9103{
9104 if(!output)
9105 return RETURN_ERR;
9106 snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
9107
9108 return RETURN_OK;
9109}
9110
9111//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9112// 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
9113INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
9114{
9115 //apply instantly. No setting need to be stored.
9116 char methods[MAX_BUF_SIZE], *token, *next_token;
9117 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
9118 struct params params;
9119
9120 if(!methodString)
9121 return RETURN_ERR;
9122 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9123 //store the paramters, and wait for wifi up to apply
9124
9125 snprintf(methods, sizeof(methods), "%s", methodString);
9126 for(token=methods; *token; token=next_token)
9127 {
9128 strtok_r(token, ",", &next_token);
9129 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
9130 snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
9131 else if(*token=='E')
9132 {
9133 if(!strcmp(methods, "Ethernet"))
9134 snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
9135 else if(!strcmp(methods, "ExternalNFCToken"))
9136 snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
9137 else
9138 printf("%s: Unknown WpsConfigMethod\n", __func__);
9139 }
9140 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
9141 snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
9142 else if(*token=='N' && !strcmp(token, "NFCInterface"))
9143 snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
9144 else if(*token=='P' )
9145 {
9146 if(!strcmp(token, "PushButton"))
developere5750452023-05-15 16:46:42 +08009147 snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developer72fb0bb2023-01-11 09:46:29 +08009148 else if(!strcmp(token, "PIN"))
9149 snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
9150 else
9151 printf("%s: Unknown WpsConfigMethod\n", __func__);
9152 }
9153 else
9154 printf("%s: Unknown WpsConfigMethod\n", __func__);
9155 }
9156 params.name = "config_methods";
9157 params.value = config_methods;
9158 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9159 wifi_hostapdWrite(config_file, &params, 1);
9160 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9161 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9162
9163 return RETURN_OK;
9164}
9165
9166// outputs the pin value, ulong_pin must be allocated by the caller
9167INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
9168{
9169 char buf[MAX_BUF_SIZE] = {0};
9170 char cmd[MAX_CMD_SIZE] = {0};
9171
9172 if(!output_ulong)
9173 return RETURN_ERR;
9174 snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
9175 _syscmd(cmd, buf, sizeof(buf));
9176 if(strlen(buf) > 0)
9177 *output_ulong=strtoul(buf, NULL, 10);
9178
9179 return RETURN_OK;
9180}
9181
9182// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
9183INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
9184{
9185 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
9186 char ap_pin[16] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009187 char config_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009188 struct params params;
9189
9190 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9191 snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
9192 params.name = "ap_pin";
9193 params.value = ap_pin;
9194 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9195 wifi_hostapdWrite(config_file, &params, 1);
9196 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9197 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9198
9199 return RETURN_OK;
9200}
9201
9202// Output string is either Not configured or Configured, max 32 characters
9203INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
9204{
9205 char interface_name[16] = {0};
9206 char cmd[MAX_CMD_SIZE];
9207 char buf[MAX_BUF_SIZE]={0};
9208
9209 if(!output_string)
9210 return RETURN_ERR;
9211 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9212 snprintf(output_string, 32, "Not configured");
9213 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9214 return RETURN_ERR;
9215 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
9216 _syscmd(cmd, buf, sizeof(buf));
9217
9218 if(!strncmp(buf, "configured", 10))
9219 snprintf(output_string, 32, "Configured");
9220 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9221
9222 return RETURN_OK;
9223}
9224
9225// sets the WPS pin for this AP
9226INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
9227{
9228 char interface_name[16] = {0};
9229 char cmd[MAX_CMD_SIZE];
9230 char buf[MAX_BUF_SIZE]={0};
9231 BOOL enable;
9232
9233 wifi_getApEnable(apIndex, &enable);
9234 if (!enable)
9235 return RETURN_ERR;
9236 wifi_getApWpsEnable(apIndex, &enable);
9237 if (!enable)
9238 return RETURN_ERR;
9239
9240 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9241 return RETURN_ERR;
9242 snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
9243 _syscmd(cmd, buf, sizeof(buf));
9244 if((strstr(buf, "OK"))!=NULL)
9245 return RETURN_OK;
9246
9247 return RETURN_ERR;
9248}
9249
9250// This function is called when the WPS push button has been pressed for this AP
9251INT wifi_setApWpsButtonPush(INT apIndex)
9252{
9253 char cmd[MAX_CMD_SIZE];
9254 char buf[MAX_BUF_SIZE]={0};
9255 char interface_name[16] = {0};
9256 BOOL enable=FALSE;
9257
9258 wifi_getApEnable(apIndex, &enable);
9259 if (!enable)
9260 return RETURN_ERR;
9261
9262 wifi_getApWpsEnable(apIndex, &enable);
9263 if (!enable)
9264 return RETURN_ERR;
9265
9266 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9267 return RETURN_ERR;
9268
9269 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
9270 _syscmd(cmd, buf, sizeof(buf));
9271
9272 if((strstr(buf, "OK"))!=NULL)
9273 return RETURN_OK;
9274 return RETURN_ERR;
9275}
9276
9277// cancels WPS mode for this AP
9278INT wifi_cancelApWPS(INT apIndex)
9279{
9280 char interface_name[16] = {0};
9281 char cmd[MAX_CMD_SIZE];
9282 char buf[MAX_BUF_SIZE]={0};
9283
9284 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9285 return RETURN_ERR;
9286 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
9287 _syscmd(cmd,buf, sizeof(buf));
9288
9289 if((strstr(buf, "OK"))!=NULL)
9290 return RETURN_OK;
9291 return RETURN_ERR;
9292}
9293
9294//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
9295//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
9296INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
9297{
9298 char interface_name[16] = {0};
9299 FILE *f = NULL;
developer2f79c922023-06-02 17:33:42 +08009300 int read_flag=0, auth_temp=0, mac_temp=0;
developer72fb0bb2023-01-11 09:46:29 +08009301 char cmd[256] = {0}, buf[2048] = {0};
9302 char *param = NULL, *value = NULL, *line=NULL;
9303 size_t len = 0;
developer72fb0bb2023-01-11 09:46:29 +08009304 wifi_associated_dev_t *dev=NULL;
9305
9306 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9307 *associated_dev_array = NULL;
9308 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9309 return RETURN_ERR;
9310 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9311 _syscmd(cmd,buf,sizeof(buf));
9312 *output_array_size = atoi(buf);
9313
9314 if (*output_array_size <= 0)
9315 return RETURN_OK;
9316
9317 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
9318 *associated_dev_array = dev;
9319 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
9320 _syscmd(cmd,buf,sizeof(buf));
9321 f = fopen("/tmp/connected_devices.txt", "r");
9322 if (f==NULL)
9323 {
9324 *output_array_size=0;
9325 return RETURN_ERR;
9326 }
9327 while ((getline(&line, &len, f)) != -1)
9328 {
9329 param = strtok(line,"=");
9330 value = strtok(NULL,"=");
9331
9332 if( strcmp("flags",param) == 0 )
9333 {
9334 value[strlen(value)-1]='\0';
9335 if(strstr (value,"AUTHORIZED") != NULL )
9336 {
9337 dev[auth_temp].cli_AuthenticationState = 1;
9338 dev[auth_temp].cli_Active = 1;
9339 auth_temp++;
9340 read_flag=1;
9341 }
9342 }
9343 if(read_flag==1)
9344 {
9345 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
9346 {
9347 value[strlen(value)-1]='\0';
9348 sscanf(value, "%x:%x:%x:%x:%x:%x",
9349 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
9350 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
9351 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
9352 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
9353 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
9354 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
9355 mac_temp++;
9356 read_flag=0;
9357 }
9358 }
9359 }
9360 *output_array_size = auth_temp;
9361 auth_temp=0;
9362 mac_temp=0;
9363 free(line);
9364 fclose(f);
9365 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9366 return RETURN_OK;
9367}
9368
9369#define MACADDRESS_SIZE 6
9370
9371INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9372{
9373 FILE *fp = NULL;
9374 char str[MAX_BUF_SIZE] = {0};
9375 int wificlientindex = 0 ;
9376 int count = 0;
9377 int signalstrength = 0;
9378 int arr[MACADDRESS_SIZE] = {0};
9379 unsigned char mac[MACADDRESS_SIZE] = {0};
9380 UINT wifi_count = 0;
developer72fb0bb2023-01-11 09:46:29 +08009381 char pipeCmd[MAX_CMD_SIZE] = {0};
9382
9383 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9384 *output_array_size = 0;
9385 *associated_dev_array = NULL;
9386
9387 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
9388 fp = popen(pipeCmd, "r");
developer69b61b02023-03-07 17:17:44 +08009389 if (fp == NULL)
developer72fb0bb2023-01-11 09:46:29 +08009390 {
9391 printf("Failed to run command inside function %s\n",__FUNCTION__ );
9392 return RETURN_ERR;
9393 }
9394
9395 /* Read the output a line at a time - output it. */
9396 fgets(str, sizeof(str)-1, fp);
9397 wifi_count = (unsigned int) atoi ( str );
9398 *output_array_size = wifi_count;
9399 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
9400 pclose(fp);
9401
9402 if(wifi_count == 0)
9403 {
9404 return RETURN_OK;
9405 }
9406 else
9407 {
9408 wifi_associated_dev3_t* temp = NULL;
9409 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
9410 if(temp == NULL)
9411 {
9412 printf("Error Statement. Insufficient memory \n");
9413 return RETURN_ERR;
9414 }
9415
9416 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
9417 system(pipeCmd);
9418 memset(pipeCmd,0,sizeof(pipeCmd));
9419 if(apIndex == 0)
9420 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
9421 else if(apIndex == 1)
9422 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
9423 system(pipeCmd);
9424
9425 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
9426 if(fp == NULL)
9427 {
9428 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
9429 free(temp);
9430 return RETURN_ERR;
9431 }
9432 fclose(fp);
9433
9434 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
9435 fp = popen(pipeCmd, "r");
9436 if(fp)
9437 {
9438 for(count =0 ; count < wifi_count; count++)
9439 {
9440 fgets(str, MAX_BUF_SIZE, fp);
9441 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9442 {
9443 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9444 {
9445 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9446
9447 }
9448 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9449 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]);
9450 }
9451 temp[count].cli_AuthenticationState = 1; //TODO
9452 temp[count].cli_Active = 1; //TODO
9453 }
9454 pclose(fp);
9455 }
9456
9457 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
9458 fp = popen(pipeCmd, "r");
9459 if(fp)
developer69b61b02023-03-07 17:17:44 +08009460 {
developer72fb0bb2023-01-11 09:46:29 +08009461 pclose(fp);
9462 }
9463 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
9464 if(fp)
9465 {
9466 for(count =0 ; count < wifi_count ;count++)
9467 {
9468 fgets(str, MAX_BUF_SIZE, fp);
9469 signalstrength = atoi(str);
9470 temp[count].cli_SignalStrength = signalstrength;
9471 temp[count].cli_RSSI = signalstrength;
9472 temp[count].cli_SNR = signalstrength + 95;
9473 }
9474 pclose(fp);
9475 }
9476
9477
9478 if((apIndex == 0) || (apIndex == 4))
9479 {
9480 for(count =0 ; count < wifi_count ;count++)
developer69b61b02023-03-07 17:17:44 +08009481 {
developer72fb0bb2023-01-11 09:46:29 +08009482 strcpy(temp[count].cli_OperatingStandard,"g");
9483 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
9484 }
9485
9486 //BytesSent
9487 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
9488 fp = popen(pipeCmd, "r");
9489 if(fp)
developer69b61b02023-03-07 17:17:44 +08009490 {
developer72fb0bb2023-01-11 09:46:29 +08009491 pclose(fp);
9492 }
9493 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
9494 if(fp)
9495 {
9496 for (count = 0; count < wifi_count; count++)
9497 {
9498 fgets(str, MAX_BUF_SIZE, fp);
9499 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
9500 }
9501 pclose(fp);
9502 }
9503
9504 //BytesReceived
9505 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
9506 fp = popen(pipeCmd, "r");
9507 if (fp)
9508 {
9509 pclose(fp);
9510 }
9511 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
9512 if (fp)
9513 {
9514 for (count = 0; count < wifi_count; count++)
9515 {
9516 fgets(str, MAX_BUF_SIZE, fp);
9517 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
9518 }
9519 pclose(fp);
9520 }
9521
9522 //PacketsSent
9523 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
9524 fp = popen(pipeCmd, "r");
9525 if (fp)
9526 {
9527 pclose(fp);
9528 }
9529
9530 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
9531 if (fp)
9532 {
9533 for (count = 0; count < wifi_count; count++)
9534 {
9535 fgets(str, MAX_BUF_SIZE, fp);
9536 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
9537 }
9538 pclose(fp);
9539 }
9540
9541 //PacketsReceived
9542 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
9543 fp = popen(pipeCmd, "r");
9544 if (fp)
9545 {
9546 pclose(fp);
9547 }
9548 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
9549 if (fp)
9550 {
9551 for (count = 0; count < wifi_count; count++)
9552 {
9553 fgets(str, MAX_BUF_SIZE, fp);
9554 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
9555 }
9556 pclose(fp);
9557 }
9558
9559 //ErrorsSent
9560 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9561 fp = popen(pipeCmd, "r");
9562 if (fp)
9563 {
9564 pclose(fp);
9565 }
9566 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9567 if (fp)
9568 {
9569 for (count = 0; count < wifi_count; count++)
9570 {
9571 fgets(str, MAX_BUF_SIZE, fp);
9572 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9573 }
9574 pclose(fp);
9575 }
9576
9577 //ErrorsSent
9578 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9579 fp = popen(pipeCmd, "r");
9580 if (fp)
9581 {
9582 pclose(fp);
9583 }
9584 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9585 if (fp)
9586 {
9587 for (count = 0; count < wifi_count; count++)
9588 {
9589 fgets(str, MAX_BUF_SIZE, fp);
9590 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9591 }
9592 pclose(fp);
9593 }
9594
9595 //LastDataDownlinkRate
9596 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
9597 fp = popen(pipeCmd, "r");
9598 if (fp)
9599 {
9600 pclose(fp);
9601 }
9602 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
9603 if (fp)
9604 {
9605 for (count = 0; count < wifi_count; count++)
9606 {
9607 fgets(str, MAX_BUF_SIZE, fp);
9608 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
9609 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
9610 }
9611 pclose(fp);
9612 }
9613
9614 //LastDataUplinkRate
9615 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
9616 fp = popen(pipeCmd, "r");
9617 if (fp)
9618 {
9619 pclose(fp);
9620 }
9621 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
9622 if (fp)
9623 {
9624 for (count = 0; count < wifi_count; count++)
9625 {
9626 fgets(str, MAX_BUF_SIZE, fp);
9627 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
9628 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
9629 }
9630 pclose(fp);
9631 }
9632
9633 }
9634 else if ((apIndex == 1) || (apIndex == 5))
9635 {
9636 for (count = 0; count < wifi_count; count++)
9637 {
9638 strcpy(temp[count].cli_OperatingStandard, "a");
9639 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
9640 temp[count].cli_BytesSent = 0;
9641 temp[count].cli_BytesReceived = 0;
9642 temp[count].cli_LastDataUplinkRate = 0;
9643 temp[count].cli_LastDataDownlinkRate = 0;
9644 temp[count].cli_PacketsSent = 0;
9645 temp[count].cli_PacketsReceived = 0;
9646 temp[count].cli_ErrorsSent = 0;
9647 }
9648 }
9649
9650 for (count = 0; count < wifi_count; count++)
9651 {
9652 temp[count].cli_Retransmissions = 0;
9653 temp[count].cli_DataFramesSentAck = 0;
9654 temp[count].cli_DataFramesSentNoAck = 0;
9655 temp[count].cli_MinRSSI = 0;
9656 temp[count].cli_MaxRSSI = 0;
9657 strncpy(temp[count].cli_InterferenceSources, "", 64);
9658 memset(temp[count].cli_IPAddress, 0, 64);
9659 temp[count].cli_RetransCount = 0;
9660 temp[count].cli_FailedRetransCount = 0;
9661 temp[count].cli_RetryCount = 0;
9662 temp[count].cli_MultipleRetryCount = 0;
9663 }
9664 *associated_dev_array = temp;
9665 }
9666 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9667 return RETURN_OK;
9668}
9669
developer7e4a2a62023-04-06 19:56:03 +08009670int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +08009671{
developer7e4a2a62023-04-06 19:56:03 +08009672 char cmd[MAX_CMD_SIZE] = {0};
9673 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009674
developer7e4a2a62023-04-06 19:56:03 +08009675 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
9676
9677 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
9678 interface_name);
9679 _syscmd(cmd, buf, MAX_BUF_SIZE);
9680
9681 strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */
9682
9683 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009684 return RETURN_OK;
9685}
9686
9687/* #define HOSTAPD_STA_PARAM_ENTRIES 29
9688struct hostapd_sta_param {
9689 char key[50];
9690 char value[100];
9691}
9692
9693static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){
9694 int i = 0;
9695
9696 while(i<HOSTAPD_STA_PARAM_ENTRIES) {
9697 if (strncmp(params[i].key,key,50) == 0){
9698 return &params[i].value;
9699 }
9700 i++;
9701 }
9702 return NULL;
9703
9704} */
9705
developer72fb0bb2023-01-11 09:46:29 +08009706static const char *get_line_from_str_buf(const char *buf, char *line)
9707{
9708 int i;
9709 int n = strlen(buf);
9710
9711 for (i = 0; i < n; i++) {
9712 line[i] = buf[i];
9713 if (buf[i] == '\n') {
9714 line[i] = '\0';
9715 return &buf[i + 1];
9716 }
9717 }
9718
9719 return NULL;
9720}
9721
9722INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9723{
developer0d26f2c2023-05-25 19:46:36 +08009724 char interface_name[16] = {0};
9725 FILE *f = NULL;
9726 int auth_temp= -1;
9727 char cmd[256] = {0}, buf[2048] = {0};
9728 char *param = NULL, *value = NULL, *line=NULL;
9729 size_t len = 0;
9730 wifi_associated_dev3_t *dev=NULL;
developer72fb0bb2023-01-11 09:46:29 +08009731
9732 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer0d26f2c2023-05-25 19:46:36 +08009733 *associated_dev_array = NULL;
9734 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08009735 return RETURN_ERR;
developer0d26f2c2023-05-25 19:46:36 +08009736 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9737 _syscmd(cmd, buf, sizeof(buf));
9738 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08009739
developer0d26f2c2023-05-25 19:46:36 +08009740 if (*output_array_size <= 0)
9741 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08009742
developer0d26f2c2023-05-25 19:46:36 +08009743 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
9744 *associated_dev_array = dev;
9745 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
9746 _syscmd(cmd,buf,sizeof(buf));
9747 f = fopen("/tmp/diagnostic3_devices.txt", "r");
9748 if (f == NULL)
9749 {
9750 *output_array_size=0;
developer72fb0bb2023-01-11 09:46:29 +08009751 return RETURN_ERR;
9752 }
developer0d26f2c2023-05-25 19:46:36 +08009753 while ((getline(&line, &len, f)) != -1)
9754 {
9755 param = strtok(line, "=");
9756 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +08009757
developer0d26f2c2023-05-25 19:46:36 +08009758 if( strcmp("flags",param) == 0 )
9759 {
9760 value[strlen(value)-1]='\0';
9761 if(strstr (value,"AUTHORIZED") != NULL )
9762 {
9763 auth_temp++;
9764 dev[auth_temp].cli_AuthenticationState = 1;
9765 dev[auth_temp].cli_Active = 1;
developer72fb0bb2023-01-11 09:46:29 +08009766 }
developer0d26f2c2023-05-25 19:46:36 +08009767 } else if (auth_temp < 0) {
9768 continue;
9769 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
9770 {
9771 value[strlen(value)-1]='\0';
9772 sscanf(value, "%x:%x:%x:%x:%x:%x",
9773 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
9774 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
9775 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
9776 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
9777 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
9778 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
9779 } else if (strcmp("signal", param) == 0) {
9780 value[strlen(value)-1]='\0';
9781 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
9782 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
developer72fb0bb2023-01-11 09:46:29 +08009783 }
developer0d26f2c2023-05-25 19:46:36 +08009784 }
9785 if (line)
9786 free(line);
9787 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +08009788 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009789 return RETURN_OK;
9790}
9791
9792#if 0
9793//To-do
9794INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9795{
9796 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9797
9798 //Using different approach to get required WiFi Parameters from system available commands
developer69b61b02023-03-07 17:17:44 +08009799#if 0
developer72fb0bb2023-01-11 09:46:29 +08009800 FILE *f;
9801 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
9802 char cmd[256], buf[2048];
9803 char *param , *value, *line=NULL;
9804 size_t len = 0;
9805 ssize_t nread;
9806 wifi_associated_dev3_t *dev=NULL;
9807 *associated_dev_array = NULL;
9808 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9809 _syscmd(cmd,buf,sizeof(buf));
9810 *output_array_size = atoi(buf);
9811
9812 if (*output_array_size <= 0)
9813 return RETURN_OK;
9814
9815 dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t));
9816 *associated_dev_array = dev;
9817 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name);
9818 _syscmd(cmd,buf,sizeof(buf));
9819 f = fopen("/tmp/connected_devices.txt", "r");
9820 if (f==NULL)
9821 {
9822 *output_array_size=0;
9823 return RETURN_ERR;
9824 }
9825 while ((nread = getline(&line, &len, f)) != -1)
9826 {
9827 param = strtok(line,"=");
9828 value = strtok(NULL,"=");
9829
9830 if( strcmp("flags",param) == 0 )
9831 {
9832 value[strlen(value)-1]='\0';
9833 if(strstr (value,"AUTHORIZED") != NULL )
9834 {
9835 dev[auth_temp].cli_AuthenticationState = 1;
9836 dev[auth_temp].cli_Active = 1;
9837 auth_temp++;
9838 read_flag=1;
9839 }
9840 }
9841 if(read_flag==1)
9842 {
9843 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
9844 {
9845 value[strlen(value)-1]='\0';
9846 sscanf(value, "%x:%x:%x:%x:%x:%x",
9847 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
9848 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
9849 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
9850 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
9851 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
9852 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
9853
9854 }
9855 else if( strcmp("rx_packets",param) == 0 )
9856 {
9857 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived));
9858 }
9859
9860 else if( strcmp("tx_packets",param) == 0 )
9861 {
developer69b61b02023-03-07 17:17:44 +08009862 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent));
developer72fb0bb2023-01-11 09:46:29 +08009863 }
9864
9865 else if( strcmp("rx_bytes",param) == 0 )
9866 {
9867 sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived));
9868 }
9869
9870 else if( strcmp("tx_bytes",param) == 0 )
9871 {
developer69b61b02023-03-07 17:17:44 +08009872 sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent));
developer72fb0bb2023-01-11 09:46:29 +08009873 mac_temp++;
9874 read_flag=0;
developer69b61b02023-03-07 17:17:44 +08009875 }
developer72fb0bb2023-01-11 09:46:29 +08009876 }
9877 }
9878
9879 *output_array_size = auth_temp;
9880 auth_temp=0;
9881 mac_temp=0;
9882 free(line);
9883 fclose(f);
9884#endif
9885 char interface_name[MAX_BUF_SIZE] = {0};
9886 char wifi_status[MAX_BUF_SIZE] = {0};
9887 char hostapdconf[MAX_BUF_SIZE] = {0};
9888
9889 wifi_associated_dev3_t *dev_array = NULL;
9890 ULONG wifi_count = 0;
9891
9892 *associated_dev_array = NULL;
9893 *output_array_size = 0;
9894
9895 printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex);
9896 //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI.
9897 {
9898 sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex);
9899
9900 wifi_GetInterfaceName(interface_name, hostapdconf);
9901
9902 if(strlen(interface_name) > 1)
9903 {
9904 wifihal_interfacestatus(wifi_status,interface_name);
9905 if(strcmp(wifi_status,"RUNNING") == 0)
9906 {
9907 wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count);
9908
9909 *associated_dev_array = dev_array;
developer69b61b02023-03-07 17:17:44 +08009910 *output_array_size = wifi_count;
developer72fb0bb2023-01-11 09:46:29 +08009911 }
9912 else
9913 {
9914 *associated_dev_array = NULL;
9915 }
9916 }
9917 }
9918
9919 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9920 return RETURN_OK;
9921}
9922#endif
9923
9924/* getIPAddress function */
9925/**
9926* @description Returning IpAddress of the Matched String
9927*
developer69b61b02023-03-07 17:17:44 +08009928* @param
developer72fb0bb2023-01-11 09:46:29 +08009929* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +08009930* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +08009931* @return The status of the operation
9932* @retval RETURN_OK if successful
9933* @retval RETURN_ERR if any error is detected
9934*
9935*/
9936
9937INT getIPAddress(char *str,char *ipaddr)
9938{
9939 FILE *fp = NULL;
9940 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
9941 int LeaseTime = 0,ret = 0;
9942 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
9943 {
9944 return RETURN_ERR;
9945 }
9946
9947 while ( fgets(buf, sizeof(buf), fp)!= NULL )
9948 {
9949 /*
9950 Sample:sss
9951 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
9952 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
9953 */
9954 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
9955 &(LeaseTime),
9956 phyAddr,
9957 ipAddr,
9958 hostName
9959 );
9960 if(ret != 4)
9961 continue;
9962 if(strcmp(str,phyAddr) == 0)
9963 strcpy(ipaddr,ipAddr);
9964 }
9965 fclose(fp);
9966 return RETURN_OK;
9967}
9968
9969/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
9970/**
9971* @description Returning Inactive wireless connected clients informations
9972*
developer69b61b02023-03-07 17:17:44 +08009973* @param
developer72fb0bb2023-01-11 09:46:29 +08009974* @filename Holding private_wifi 2g/5g content files
9975* @associated_dev_array Having inactiv wireless clients informations
9976* @output_array_size Returning Inactive wireless counts
9977* @return The status of the operation
9978* @retval RETURN_OK if successful
9979* @retval RETURN_ERR if any error is detected
9980*
9981*/
9982
9983INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9984{
9985 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9986 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
9987 FILE *fp = NULL;
9988 int arr[MACADDRESS_SIZE] = {0};
9989 unsigned char mac[MACADDRESS_SIZE] = {0};
9990 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
9991 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
9992 fp = popen(buf,"r");
9993 if(fp == NULL)
9994 return RETURN_ERR;
9995 else
9996 {
9997 fgets(path,sizeof(path),fp);
9998 maccount = atoi(path);
9999 }
10000 pclose(fp);
10001 *output_array_size = maccount;
10002 wifi_associated_dev3_t* temp = NULL;
10003 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10004 *associated_dev_array = temp;
10005 if(temp == NULL)
10006 {
10007 printf("Error Statement. Insufficient memory \n");
10008 return RETURN_ERR;
10009 }
10010 memset(buf,0,sizeof(buf));
10011 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
10012 fp = popen(buf,"r");
10013 if (fp == NULL) {
10014 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
10015 return RETURN_ERR;
10016 }
10017 for(count = 0; count < maccount ; count++)
10018 {
10019 fgets(path,sizeof(path),fp);
10020 for(i = 0; path[i]!='\n';i++)
10021 str[i]=path[i];
10022 str[i]='\0';
10023 getIPAddress(str,ipaddr);
10024 memset(buf,0,sizeof(buf));
10025 if(strlen(ipaddr) > 0)
10026 {
10027 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
10028 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
10029 {
10030 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10031 {
10032 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10033 {
10034 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
10035
10036 }
10037 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10038 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]);
10039 }
10040 temp[count].cli_AuthenticationState = 0; //TODO
developer69b61b02023-03-07 17:17:44 +080010041 temp[count].cli_Active = 0; //TODO
developer72fb0bb2023-01-11 09:46:29 +080010042 temp[count].cli_SignalStrength = 0;
10043 }
10044 else //Active wireless clients info
10045 {
10046 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10047 {
10048 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10049 {
10050 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
10051
10052 }
10053 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10054 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]);
10055 }
10056 temp[count].cli_Active = 1;
10057 }
10058 }
10059 memset(ipaddr,0,sizeof(ipaddr));
10060 }
10061 pclose(fp);
10062 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10063 return RETURN_OK;
10064}
10065//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
10066//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
10067//To get Band Steering Capability
10068INT wifi_getBandSteeringCapability(BOOL *support)
10069{
10070 *support = FALSE;
10071 return RETURN_OK;
10072}
10073
10074
10075//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
10076//To get Band Steering enable status
10077INT wifi_getBandSteeringEnable(BOOL *enable)
10078{
10079 *enable = FALSE;
10080 return RETURN_OK;
10081}
10082
10083//To turn on/off Band steering
10084INT wifi_setBandSteeringEnable(BOOL enable)
10085{
10086 return RETURN_OK;
10087}
10088
10089//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
10090//To get Band Steering AP group
10091INT wifi_getBandSteeringApGroup(char *output_ApGroup)
10092{
10093 if (NULL == output_ApGroup)
10094 return RETURN_ERR;
10095
10096 strcpy(output_ApGroup, "1,2");
10097 return RETURN_OK;
10098}
10099
10100//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
10101//to set and read the band steering BandUtilizationThreshold parameters
10102INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
10103{
10104 return RETURN_ERR;
10105}
10106
10107INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
10108{
10109 return RETURN_ERR;
10110}
10111
10112//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
10113//to set and read the band steering RSSIThreshold parameters
10114INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
10115{
10116 return RETURN_ERR;
10117}
10118
10119INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
10120{
10121 return RETURN_ERR;
10122}
10123
10124
10125//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
10126//to set and read the band steering physical modulation rate threshold parameters
10127INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
10128{
10129 //If chip is not support, return -1
10130 return RETURN_ERR;
10131}
10132
10133INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
10134{
10135 //If chip is not support, return -1
10136 return RETURN_ERR;
10137}
10138
10139//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
10140//to set and read the inactivity time (in seconds) for steering under overload condition
10141INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
10142{
10143 return RETURN_ERR;
10144}
10145
10146INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
10147{
10148 return RETURN_ERR;
10149}
10150
10151//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
10152//to set and read the inactivity time (in seconds) for steering under Idle condition
10153INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
10154{
10155 return RETURN_ERR;
10156}
10157
10158INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
10159{
10160 return RETURN_ERR;
10161}
10162
10163//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
10164//pClientMAC[64]
10165//pSourceSSIDIndex[64]
10166//pDestSSIDIndex[64]
10167//pSteeringReason[256]
10168INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
10169{
10170 //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
10171 *pSteeringTime=time(NULL);
10172 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
10173 return RETURN_OK;
10174}
10175
10176INT wifi_ifConfigDown(INT apIndex)
10177{
10178 INT status = RETURN_OK;
10179 char cmd[64];
10180
10181 snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
10182 printf("%s: %s\n", __func__, cmd);
10183 system(cmd);
10184
10185 return status;
10186}
10187
10188INT wifi_ifConfigUp(INT apIndex)
10189{
10190 char interface_name[16] = {0};
10191 char cmd[128];
10192 char buf[1024];
10193
10194 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10195 return RETURN_ERR;
10196 snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
10197 _syscmd(cmd, buf, sizeof(buf));
10198 return 0;
10199}
10200
10201//>> Deprecated. Replace with wifi_applyRadioSettings
10202INT wifi_pushBridgeInfo(INT apIndex)
10203{
developerb2977562023-05-24 17:54:12 +080010204 char ip[32] = {0};
10205 char subnet[32] = {0};
10206 char bridge[32] = {0};
10207 char cmd[128] = {0};
10208 char buf[1024] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010209
developerb2977562023-05-24 17:54:12 +080010210 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080010211
developerb2977562023-05-24 17:54:12 +080010212 snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
10213 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010214
developerb2977562023-05-24 17:54:12 +080010215 return 0;
developer72fb0bb2023-01-11 09:46:29 +080010216}
10217
10218INT wifi_pushChannel(INT radioIndex, UINT channel)
10219{
10220 char interface_name[16] = {0};
10221 char cmd[128];
10222 char buf[1024];
developer72fb0bb2023-01-11 09:46:29 +080010223
developer72fb0bb2023-01-11 09:46:29 +080010224 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10225 return RETURN_ERR;
10226 snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
10227 _syscmd(cmd,buf, sizeof(buf));
10228
10229 return 0;
10230}
10231
10232INT wifi_pushChannelMode(INT radioIndex)
10233{
10234 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
10235 return RETURN_ERR;
10236}
10237
10238INT wifi_pushDefaultValues(INT radioIndex)
10239{
10240 //Apply Comcast specified default radio settings instantly
10241 //AMPDU=1
10242 //AMPDUFrames=32
10243 //AMPDULim=50000
10244 //txqueuelen=1000
10245
10246 return RETURN_ERR;
10247}
10248
10249INT wifi_pushTxChainMask(INT radioIndex)
10250{
10251 //Apply default TxChainMask instantly
10252 return RETURN_ERR;
10253}
10254
10255INT wifi_pushRxChainMask(INT radioIndex)
10256{
10257 //Apply default RxChainMask instantly
10258 return RETURN_ERR;
10259}
10260
10261INT wifi_pushSSID(INT apIndex, CHAR *ssid)
10262{
developer7e4a2a62023-04-06 19:56:03 +080010263 INT status;
developer72fb0bb2023-01-11 09:46:29 +080010264
developer7e4a2a62023-04-06 19:56:03 +080010265 status = wifi_setSSIDName(apIndex, ssid);
10266 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010267
developer7e4a2a62023-04-06 19:56:03 +080010268 return status;
developer72fb0bb2023-01-11 09:46:29 +080010269}
10270
10271INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
10272{
10273 //Apply default Ssid Advertisement instantly
10274 return RETURN_ERR;
10275}
10276
10277INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
10278{
developere82c0ca2023-05-10 16:25:35 +080010279 time_t now;
10280
10281 time(&now);
10282 if (now > radio_up_time[radioIndex])
10283 *output = now - radio_up_time[radioIndex];
10284 else {
10285 *output = 0;
10286 return RETURN_ERR;
10287 }
10288
10289 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010290}
10291
10292INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
10293{
10294 return RETURN_OK;
10295}
10296
10297INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
10298{
10299 return RETURN_OK;
10300}
10301
10302//To-do
10303INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
10304{
10305 char output[16]={'\0'};
10306 char config_file[MAX_BUF_SIZE] = {0};
10307
10308 if (!output_string)
10309 return RETURN_ERR;
10310
10311 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10312 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
10313
10314 if (strlen(output) == 0)
10315 snprintf(output_string, 64, "Disabled");
10316 else if (strncmp(output, "0", 1) == 0)
10317 snprintf(output_string, 64, "Disabled");
10318 else if (strncmp(output, "1", 1) == 0)
10319 snprintf(output_string, 64, "Optional");
10320 else if (strncmp(output, "2", 1) == 0)
10321 snprintf(output_string, 64, "Required");
10322 else {
10323 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
10324 return RETURN_ERR;
10325 }
10326
10327 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
10328 return RETURN_OK;
10329}
10330INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
10331{
developer72fb0bb2023-01-11 09:46:29 +080010332 struct params params;
10333 char config_file[MAX_BUF_SIZE] = {0};
10334
10335 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10336 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
10337 return RETURN_ERR;
10338
10339 params.name = "ieee80211w";
10340 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
10341 params.value = "0";
10342 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
10343 params.value = "1";
10344 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
10345 params.value = "2";
10346 else{
10347 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
10348 return RETURN_ERR;
10349 }
10350 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10351 wifi_hostapdWrite(config_file, &params, 1);
10352 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10353 return RETURN_OK;
10354}
10355INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
10356{
10357 char output[16]={'\0'};
10358 char config_file[MAX_BUF_SIZE] = {0};
developer84c3d782023-05-31 16:08:21 +080010359 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080010360
10361 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer84c3d782023-05-31 16:08:21 +080010362 band = wifi_index_to_band(radioIndex);
10363 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer262f4cb2023-05-24 12:22:04 +080010364 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080010365
developer84c3d782023-05-31 16:08:21 +080010366 if (strncmp(output, "0", 1) == 0)
developer47a56bf2023-05-30 13:38:57 +080010367 *output_bool = FALSE;
developer262f4cb2023-05-24 12:22:04 +080010368 else if (strncmp(output, "1", 1) == 0)
10369 *output_bool = TRUE;
10370 else if (strncmp(output, "2", 1) == 0)
10371 *output_bool = TRUE;
10372 else if (strncmp(output, "3", 1) == 0)
10373 *output_bool = TRUE;
10374 else
10375 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010376 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
10377
10378 return RETURN_OK;
10379}
10380
10381INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
10382{
10383 return RETURN_OK;
10384}
10385
10386INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
10387{
10388 return RETURN_OK;
10389}
10390
10391INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
10392{
10393 return RETURN_OK;
10394}
10395
10396INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10397{
10398 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10399 char config_file[MAX_BUF_SIZE] = {0};
10400
10401 if (NULL == output)
10402 return RETURN_ERR;
10403 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10404 wifi_hostapdRead(config_file,"hw_mode",output,64);
10405
10406 if(strcmp(output,"b")==0)
10407 sprintf(output, "%s", "1,2,5.5,11");
10408 else if (strcmp(output,"a")==0)
10409 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
10410 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
10411 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
10412
10413 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10414 return RETURN_OK;
10415}
10416
10417INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10418{
10419 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10420 char *temp;
10421 char temp_output[128];
10422 char temp_TransmitRates[128];
10423 char config_file[MAX_BUF_SIZE] = {0};
10424
10425 if (NULL == output)
10426 return RETURN_ERR;
10427
10428 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10429 wifi_hostapdRead(config_file,"supported_rates",output,64);
10430
10431 if (strlen(output) == 0) {
10432 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
10433 return RETURN_OK;
10434 }
10435 strcpy(temp_TransmitRates,output);
10436 strcpy(temp_output,"");
10437 temp = strtok(temp_TransmitRates," ");
10438 while(temp!=NULL)
10439 {
10440 temp[strlen(temp)-1]=0;
10441 if((temp[0]=='5') && (temp[1]=='\0'))
10442 {
10443 temp="5.5";
10444 }
10445 strcat(temp_output,temp);
10446 temp = strtok(NULL," ");
10447 if(temp!=NULL)
10448 {
10449 strcat(temp_output,",");
10450 }
10451 }
10452 strcpy(output,temp_output);
10453 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10454
10455 return RETURN_OK;
10456}
10457
10458INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10459{
10460 return RETURN_OK;
10461}
10462
10463
10464INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10465{
10466 int i=0;
10467 char *temp;
10468 char temp1[128] = {0};
10469 char temp_output[128] = {0};
10470 char temp_TransmitRates[128] = {0};
10471 struct params params={'\0'};
10472 char config_file[MAX_BUF_SIZE] = {0};
10473 wifi_band band = wifi_index_to_band(wlanIndex);
10474
10475 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10476 if(NULL == output)
10477 return RETURN_ERR;
10478 strcpy(temp_TransmitRates,output);
10479
10480 for(i=0;i<strlen(temp_TransmitRates);i++)
10481 {
10482 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
10483 {
10484 continue;
10485 }
10486 else
10487 {
10488 return RETURN_ERR;
10489 }
10490 }
10491 strcpy(temp_output,"");
10492 temp = strtok(temp_TransmitRates,",");
10493 while(temp!=NULL)
10494 {
10495 strcpy(temp1,temp);
10496 if(band == band_5)
10497 {
10498 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
10499 {
10500 return RETURN_ERR;
10501 }
10502 }
10503
10504 if(strcmp(temp,"5.5")==0)
10505 {
10506 strcpy(temp1,"55");
10507 }
10508 else
10509 {
10510 strcat(temp1,"0");
10511 }
10512 strcat(temp_output,temp1);
10513 temp = strtok(NULL,",");
10514 if(temp!=NULL)
10515 {
10516 strcat(temp_output," ");
10517 }
10518 }
10519 strcpy(output,temp_output);
10520
10521 params.name = "supported_rates";
10522 params.value = output;
10523
10524 wifi_dbg_printf("\n%s:",__func__);
10525 wifi_dbg_printf("params.value=%s\n",params.value);
10526 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10527 wifi_hostapdWrite(config_file,&params,1);
10528 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10529
10530 return RETURN_OK;
10531}
10532
10533
10534static char *sncopy(char *dst, int dst_sz, const char *src)
10535{
10536 if (src && dst && dst_sz > 0) {
10537 strncpy(dst, src, dst_sz);
10538 dst[dst_sz - 1] = '\0';
10539 }
10540 return dst;
10541}
10542
10543static int util_get_sec_chan_offset(int channel, const char* ht_mode)
10544{
10545 if (0 == strcmp(ht_mode, "HT40") ||
10546 0 == strcmp(ht_mode, "HT80") ||
10547 0 == strcmp(ht_mode, "HT160")) {
10548 switch (channel) {
10549 case 1 ... 7:
10550 case 36:
10551 case 44:
10552 case 52:
10553 case 60:
10554 case 100:
10555 case 108:
10556 case 116:
10557 case 124:
10558 case 132:
10559 case 140:
10560 case 149:
10561 case 157:
10562 return 1;
10563 case 8 ... 13:
10564 case 40:
10565 case 48:
10566 case 56:
10567 case 64:
10568 case 104:
10569 case 112:
10570 case 120:
10571 case 128:
10572 case 136:
10573 case 144:
10574 case 153:
10575 case 161:
10576 return -1;
10577 default:
10578 return -EINVAL;
10579 }
10580 }
10581
10582 return -EINVAL;
10583}
10584
10585static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
10586{
10587 int idx = channel%8;
10588 if (0 == strcmp(ht_mode, "HT40") ||
10589 0 == strcmp(ht_mode, "HT80") ||
10590 0 == strcmp(ht_mode, "HT160")) {
10591 switch (idx) {
10592 case 1:
10593 return 1;
10594 case 5:
10595 return -1;
10596 default:
10597 return -EINVAL;
10598 }
10599 }
10600
10601 return -EINVAL;
10602}
10603static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
10604{
10605 if (NULL == hw_mode) return;
10606
10607 if (0 == strcmp(hw_mode, "ac"))
10608 sncopy(bw_mode, bw_mode_len, "ht vht");
10609
10610 if (0 == strcmp(hw_mode, "n"))
10611 sncopy(bw_mode, bw_mode_len, "ht");
10612
10613 return;
10614}
10615
10616static int util_chan_to_freq(int chan)
10617{
10618 if (chan == 14)
10619 return 2484;
10620 else if (chan < 14)
10621 return 2407 + chan * 5;
10622 else if (chan >= 182 && chan <= 196)
10623 return 4000 + chan * 5;
10624 else
10625 return 5000 + chan * 5;
10626 return 0;
10627}
10628
10629static int util_6G_chan_to_freq(int chan)
10630{
10631 if (chan)
10632 return 5950 + chan * 5;
10633 else
10634 return 0;
developer69b61b02023-03-07 17:17:44 +080010635
developer72fb0bb2023-01-11 09:46:29 +080010636}
10637const int *util_unii_5g_chan2list(int chan, int width)
10638{
10639 static const int lists[] = {
10640 // <width>, <chan1>, <chan2>..., 0,
10641 20, 36, 0,
10642 20, 40, 0,
10643 20, 44, 0,
10644 20, 48, 0,
10645 20, 52, 0,
10646 20, 56, 0,
10647 20, 60, 0,
10648 20, 64, 0,
10649 20, 100, 0,
10650 20, 104, 0,
10651 20, 108, 0,
10652 20, 112, 0,
10653 20, 116, 0,
10654 20, 120, 0,
10655 20, 124, 0,
10656 20, 128, 0,
10657 20, 132, 0,
10658 20, 136, 0,
10659 20, 140, 0,
10660 20, 144, 0,
10661 20, 149, 0,
10662 20, 153, 0,
10663 20, 157, 0,
10664 20, 161, 0,
10665 20, 165, 0,
10666 40, 36, 40, 0,
10667 40, 44, 48, 0,
10668 40, 52, 56, 0,
10669 40, 60, 64, 0,
10670 40, 100, 104, 0,
10671 40, 108, 112, 0,
10672 40, 116, 120, 0,
10673 40, 124, 128, 0,
10674 40, 132, 136, 0,
10675 40, 140, 144, 0,
10676 40, 149, 153, 0,
10677 40, 157, 161, 0,
10678 80, 36, 40, 44, 48, 0,
10679 80, 52, 56, 60, 64, 0,
10680 80, 100, 104, 108, 112, 0,
10681 80, 116, 120, 124, 128, 0,
10682 80, 132, 136, 140, 144, 0,
10683 80, 149, 153, 157, 161, 0,
10684 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
10685 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
10686 -1 // final delimiter
10687 };
10688 const int *start;
10689 const int *p;
10690
10691 for (p = lists; *p != -1; p++) {
10692 if (*p == width) {
10693 for (start = ++p; *p != 0; p++) {
10694 if (*p == chan)
10695 return start;
10696 }
10697 }
10698 // move to the end of channel list of given width
10699 while (*p != 0) {
10700 p++;
10701 }
10702 }
10703
10704 return NULL;
10705}
10706
10707static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
10708{
10709 if (NULL == ht_mode)
10710 return 0;
10711
10712 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
10713 const int *chans = util_unii_5g_chan2list(channel, width);
10714 int sum = 0;
10715 int cnt = 0;
10716
10717 if (NULL == chans)
10718 return 0;
10719
10720 while (*chans) {
10721 sum += *chans;
10722 cnt++;
10723 chans++;
10724 }
10725 if (cnt == 0)
10726 return 0;
10727 return sum / cnt;
10728}
10729
10730static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
10731{
10732 if (NULL == ht_mode)
10733 return 0;
10734
10735 int width = strtol((ht_mode + 2), NULL, 10);
10736
10737 int idx = 0 ;
10738 int centerchan = 0;
10739 int chan_ofs = 1;
10740
10741 if (width == 40){
10742 idx = ((channel/4) + chan_ofs)%2;
10743 switch (idx) {
10744 case 0:
10745 centerchan = (channel - 2);
10746 break;
10747 case 1:
10748 centerchan = (channel + 2);
developer69b61b02023-03-07 17:17:44 +080010749 break;
developer72fb0bb2023-01-11 09:46:29 +080010750 default:
10751 return -EINVAL;
10752 }
10753 }else if (width == 80){
developer69b61b02023-03-07 17:17:44 +080010754 idx = ((channel/4) + chan_ofs)%4;
developer72fb0bb2023-01-11 09:46:29 +080010755 switch (idx) {
10756 case 0:
10757 centerchan = (channel - 6);
10758 break;
10759 case 1:
10760 centerchan = (channel + 6);
10761 break;
10762 case 2:
10763 centerchan = (channel + 2);
10764 break;
10765 case 3:
10766 centerchan = (channel - 2);
10767 break;
10768 default:
10769 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080010770 }
developer72fb0bb2023-01-11 09:46:29 +080010771 }else if (width == 160){
10772 switch (channel) {
10773 case 1 ... 29:
10774 centerchan = 15;
10775 break;
10776 case 33 ... 61:
10777 centerchan = 47;
10778 break;
10779 case 65 ... 93:
10780 centerchan = 79;
10781 break;
10782 case 97 ... 125:
10783 centerchan = 111;
10784 break;
10785 case 129 ... 157:
10786 centerchan = 143;
10787 break;
10788 case 161 ... 189:
10789 centerchan = 175;
10790 break;
10791 case 193 ... 221:
10792 centerchan = 207;
10793 break;
10794 default:
10795 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080010796 }
developer72fb0bb2023-01-11 09:46:29 +080010797 }
10798 return centerchan;
10799}
10800static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
10801{
10802 BOOL onlyG, onlyN, onlyA;
10803 CHAR tmp[64];
10804 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
10805 if (ret == RETURN_OK) {
10806 sncopy(hw_mode, hw_mode_size, tmp);
10807 }
10808 return ret;
10809}
10810
10811INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
10812{
10813 // Sample commands:
10814 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
10815 // hostapd_cli -i wifi0 chan_switch 30 2437
developerc79e9172023-06-06 19:48:03 +080010816 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +080010817 char center_freq1_str[32] = ""; // center_freq1=%d
10818 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
10819 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
10820 char hw_mode[16] = ""; // n|ac
10821 char bw_mode[16] = ""; // ht|ht vht
10822 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
10823 char interface_name[16] = {0};
10824 int sec_chan_offset;
10825 int width;
10826 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010827 char *ext_str = "None";
10828 wifi_band band = band_invalid;
10829 int center_chan = 0;
10830 int center_freq1 = 0;
10831
10832 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
10833
10834 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10835 return RETURN_ERR;
10836
10837 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10838
10839 band = wifi_index_to_band(radioIndex);
10840
10841 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
10842
10843 // Get radio mode HT20|HT40|HT80 etc.
10844 if (channel){
developer72fb0bb2023-01-11 09:46:29 +080010845 snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
10846
10847 // Provide bandwith if specified
10848 if (channel_width_MHz > 20) {
10849 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
10850 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
10851 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
10852
10853 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
10854 }else if (channel_width_MHz == 20){
10855 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
10856 }
10857
10858
10859 if (channel_width_MHz > 20) {
10860 if (band == band_6){
10861 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
10862 if(center_chan){
10863 center_freq1 = util_6G_chan_to_freq(center_chan);
10864 }
10865 }else{
10866 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
10867 if(center_chan){
10868 center_freq1 = util_chan_to_freq(center_chan);
10869 }
10870 }
developer69b61b02023-03-07 17:17:44 +080010871
developer72fb0bb2023-01-11 09:46:29 +080010872 if (center_freq1)
10873 snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080010874
developer72fb0bb2023-01-11 09:46:29 +080010875 }
10876
10877 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
10878 if (band == band_6){
10879 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
10880 }else{
10881 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
10882 }
10883 if (sec_chan_offset != -EINVAL)
10884 snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
10885
10886 // Only the first AP, other are hanging on the same radio
developerfead3972023-05-25 20:15:02 +080010887 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
developerd1824452023-05-18 12:30:04 +080010888 if (ret != RETURN_OK) {
developerfead3972023-05-25 20:15:02 +080010889 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
developerd1824452023-05-18 12:30:04 +080010890 return RETURN_ERR;
10891 }
10892 /* wifi_dbg_printf("execute: '%s'\n", cmd);
developerf6a87542023-05-16 15:47:28 +080010893 ret = _syscmd(cmd, buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +080010894 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080010895
10896 ret = wifi_setRadioChannel(radioIndex, channel);
10897 if (ret != RETURN_OK) {
10898 fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__);
10899 return RETURN_ERR;
10900 }
10901
developer262f4cb2023-05-24 12:22:04 +080010902 if (sec_chan_offset == 1)
10903 ext_str = "Above";
10904 else if (sec_chan_offset == -1)
10905 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080010906
developerd1824452023-05-18 12:30:04 +080010907 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080010908
10909 } else {
10910 if (channel_width_MHz > 20)
10911 ext_str = "Above";
10912 }
10913
10914 wifi_setRadioExtChannel(radioIndex, ext_str);
10915
10916 char mhz_str[16];
10917 snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
10918 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
10919
10920 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10921
10922 return RETURN_OK;
10923}
10924
10925INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
10926{
10927 int index = -1;
10928 wifi_neighbor_ap2_t *scan_array = NULL;
10929 char cmd[256]={0};
10930 char buf[128]={0};
10931 char file_name[32] = {0};
10932 char filter_SSID[32] = {0};
10933 char line[256] = {0};
10934 char interface_name[16] = {0};
10935 char *ret = NULL;
10936 int freq=0;
10937 FILE *f = NULL;
developer72fb0bb2023-01-11 09:46:29 +080010938 int channels_num = 0;
10939 int vht_channel_width = 0;
10940 int get_noise_ret = RETURN_ERR;
10941 bool filter_enable = false;
10942 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
10943 int phyId = 0;
10944
10945 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
10946
10947 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
10948 f = fopen(file_name, "r");
10949 if (f != NULL) {
10950 fgets(filter_SSID, sizeof(file_name), f);
10951 if (strlen(filter_SSID) != 0)
10952 filter_enable = true;
10953 fclose(f);
10954 }
10955
10956 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
10957 return RETURN_ERR;
10958
10959 phyId = radio_index_to_phy(radio_index);
10960
10961 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
10962 _syscmd(cmd, buf, sizeof(buf));
10963 channels_num = strtol(buf, NULL, 10);
10964
10965 sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
10966 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
10967 fprintf(stderr, "cmd: %s\n", cmd);
10968 if ((f = popen(cmd, "r")) == NULL) {
10969 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
10970 return RETURN_ERR;
10971 }
developer69b61b02023-03-07 17:17:44 +080010972
developer72fb0bb2023-01-11 09:46:29 +080010973 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
10974 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +080010975
developer72fb0bb2023-01-11 09:46:29 +080010976 ret = fgets(line, sizeof(line), f);
10977 while (ret != NULL) {
10978 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +080010979 // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
developer72fb0bb2023-01-11 09:46:29 +080010980 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
10981 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
10982
10983 if (!filter_BSS) {
10984 index++;
10985 wifi_neighbor_ap2_t *tmp;
10986 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
10987 if (tmp == NULL) { // no more memory to use
10988 index--;
10989 wifi_dbg_printf("%s: realloc failed\n", __func__);
10990 break;
10991 }
10992 scan_array = tmp;
10993 }
10994 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
10995
10996 filter_BSS = false;
10997 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
developerc79e9172023-06-06 19:48:03 +080010998 memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
10999 memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
11000 memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
11001 memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
11002 memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
11003 memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
developer72fb0bb2023-01-11 09:46:29 +080011004 } else if (strstr(line, "freq") != NULL) {
11005 sscanf(line," freq: %d", &freq);
11006 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
11007
11008 if (freq >= 2412 && freq <= 2484) {
developerc79e9172023-06-06 19:48:03 +080011009 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
11010 memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
11011 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
11012 memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
11013 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
11014 memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
developer72fb0bb2023-01-11 09:46:29 +080011015 }
11016 else if (freq >= 5160 && freq <= 5805) {
developerc79e9172023-06-06 19:48:03 +080011017 memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
11018 memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
11019 memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
11020 memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
11021 memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
11022 memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
developer72fb0bb2023-01-11 09:46:29 +080011023 }
11024
11025 scan_array[index].ap_Noise = 0;
11026 if (get_noise_ret == RETURN_OK) {
11027 for (int i = 0; i < channels_num; i++) {
11028 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
11029 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
11030 break;
11031 }
11032 }
11033 }
11034 } else if (strstr(line, "beacon interval") != NULL) {
11035 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
11036 } else if (strstr(line, "signal") != NULL) {
11037 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
11038 } else if (strstr(line,"SSID") != NULL) {
11039 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
11040 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
11041 filter_BSS = true;
11042 }
11043 } else if (strstr(line, "Supported rates") != NULL) {
11044 char SRate[80] = {0}, *tmp = NULL;
11045 memset(buf, 0, sizeof(buf));
11046 strcpy(SRate, line);
11047 tmp = strtok(SRate, ":");
11048 tmp = strtok(NULL, ":");
11049 strcpy(buf, tmp);
11050 memset(SRate, 0, sizeof(SRate));
11051
11052 tmp = strtok(buf, " \n");
11053 while (tmp != NULL) {
11054 strcat(SRate, tmp);
11055 if (SRate[strlen(SRate) - 1] == '*') {
11056 SRate[strlen(SRate) - 1] = '\0';
11057 }
11058 strcat(SRate, ",");
11059
11060 tmp = strtok(NULL, " \n");
11061 }
11062 SRate[strlen(SRate) - 1] = '\0';
11063 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
11064 } else if (strstr(line, "DTIM") != NULL) {
developer49c83812023-06-06 14:23:53 +080011065 sscanf(line,"DTIM Period %u", &(scan_array[index].ap_DTIMPeriod));
developer72fb0bb2023-01-11 09:46:29 +080011066 } else if (strstr(line, "VHT capabilities") != NULL) {
11067 strcat(scan_array[index].ap_SupportedStandards, ",ac");
11068 strcpy(scan_array[index].ap_OperatingStandards, "ac");
11069 } else if (strstr(line, "HT capabilities") != NULL) {
11070 strcat(scan_array[index].ap_SupportedStandards, ",n");
11071 strcpy(scan_array[index].ap_OperatingStandards, "n");
11072 } else if (strstr(line, "VHT operation") != NULL) {
11073 ret = fgets(line, sizeof(line), f);
11074 sscanf(line," * channel width: %d", &vht_channel_width);
11075 if(vht_channel_width == 1) {
11076 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
11077 } else {
11078 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
11079 }
11080 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11081 continue;
11082 } else if (strstr(line, "HT operation") != NULL) {
11083 ret = fgets(line, sizeof(line), f);
developerdaf24792023-06-06 11:40:04 +080011084 sscanf(line," * secondary channel offset: %s", buf);
developer72fb0bb2023-01-11 09:46:29 +080011085 if (!strcmp(buf, "above")) {
11086 //40Mhz +
11087 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
11088 }
11089 else if (!strcmp(buf, "below")) {
11090 //40Mhz -
11091 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
11092 } else {
11093 //20Mhz
11094 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
11095 }
11096 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11097 continue;
11098 } else if (strstr(line, "HE capabilities") != NULL) {
11099 strcat(scan_array[index].ap_SupportedStandards, ",ax");
11100 strcpy(scan_array[index].ap_OperatingStandards, "ax");
11101 ret = fgets(line, sizeof(line), f);
11102 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
11103 if (strstr(line, "HE40/2.4GHz") != NULL)
11104 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
11105 else
11106 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
11107 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
11108 if (strstr(line, "HE80/5GHz") != NULL) {
11109 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
11110 ret = fgets(line, sizeof(line), f);
11111 } else
11112 continue;
11113 if (strstr(line, "HE160/5GHz") != NULL)
11114 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
11115 }
11116 continue;
11117 } else if (strstr(line, "WPA") != NULL) {
11118 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
11119 } else if (strstr(line, "RSN") != NULL) {
11120 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
11121 } else if (strstr(line, "Group cipher") != NULL) {
11122 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
11123 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
11124 strcpy(scan_array[index].ap_EncryptionMode, "AES");
11125 }
11126 }
11127 ret = fgets(line, sizeof(line), f);
11128 }
11129
11130 if (!filter_BSS) {
11131 *output_array_size = index + 1;
11132 } else {
11133 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
11134 *output_array_size = index;
11135 }
11136 *neighbor_ap_array = scan_array;
11137 pclose(f);
11138 free(channels_noise_arr);
11139 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11140 return RETURN_OK;
11141}
11142
11143INT wifi_getApAssociatedDeviceStats(
11144 INT apIndex,
11145 mac_address_t *clientMacAddress,
11146 wifi_associated_dev_stats_t *associated_dev_stats,
11147 u64 *handle)
11148{
11149 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
11150 char interface_name[50] = {0};
11151 char cmd[1024] = {0};
11152 char mac_str[18] = {0};
11153 char *key = NULL;
11154 char *val = NULL;
11155 FILE *f = NULL;
11156 char *line = NULL;
11157 size_t len = 0;
11158
11159 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11160 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11161 return RETURN_ERR;
11162 }
11163
11164 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
11165 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
11166 if((f = popen(cmd, "r")) == NULL) {
11167 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11168 return RETURN_ERR;
11169 }
11170
11171 while ((getline(&line, &len, f)) != -1) {
11172 key = strtok(line,":");
11173 val = strtok(NULL,":");
11174
11175 if(!strncmp(key,"rx bytes",8))
11176 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
11177 if(!strncmp(key,"tx bytes",8))
11178 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
11179 if(!strncmp(key,"rx packets",10))
11180 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11181 if(!strncmp(key,"tx packets",10))
11182 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11183 if(!strncmp(key,"tx retries",10))
11184 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
11185 if(!strncmp(key,"tx failed",9))
11186 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
11187 if(!strncmp(key,"rx drop misc",13))
11188 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
11189 if(!strncmp(key,"rx bitrate",10)) {
11190 val = strtok(val, " ");
11191 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
11192 }
11193 if(!strncmp(key,"tx bitrate",10)) {
11194 val = strtok(val, " ");
11195 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
11196 }
11197 }
11198 free(line);
11199 pclose(f);
11200 return RETURN_OK;
11201}
11202
11203INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
11204{
developer7e4a2a62023-04-06 19:56:03 +080011205 char interface_name[IF_NAME_SIZE] = {0};
developerb149d9d2023-06-06 16:14:22 +080011206 char cmd[MAX_CMD_SIZE] = {0}, buf[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011207
developer7e4a2a62023-04-06 19:56:03 +080011208 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11209
developer72fb0bb2023-01-11 09:46:29 +080011210 if (NULL == output_string)
11211 return RETURN_ERR;
11212
11213 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11214 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080011215
11216 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
developer72fb0bb2023-01-11 09:46:29 +080011217 _syscmd(cmd, buf, sizeof(buf));
11218
11219 //size of SSID name restricted to value less than 32 bytes
11220 snprintf(output_string, 32, "%s", buf);
developer7e4a2a62023-04-06 19:56:03 +080011221 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011222
11223 return RETURN_OK;
11224}
11225
11226INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
11227{
developer2edaf012023-05-24 14:24:53 +080011228 char *mac_arry_buf = NULL;
11229 INT policy = -1;
11230 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080011231
developer2edaf012023-05-24 14:24:53 +080011232 mac_arry_buf = malloc(buf_size);
11233 if (!mac_arry_buf) {
11234 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080011235 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011236 }
11237 memset(mac_arry_buf, 0, buf_size);
11238 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
11239 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
11240 goto err;
11241 }
11242 /*
11243 mtk format to get policy:
11244 "policy=1
11245 00:11:22:33:44:55
11246 00:11:22:33:44:66
11247 "
11248 */
11249 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
11250 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
11251 goto err;
11252 }
11253 if (!(policy >=0 && policy <= 2)){
11254 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
11255 goto err;
11256 }
11257 *output_filterMode = policy;
11258 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
11259 free(mac_arry_buf);
11260 mac_arry_buf = NULL;
11261 return RETURN_OK;
11262err:
11263 free(mac_arry_buf);
11264 mac_arry_buf = NULL;
11265 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
11266 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011267}
11268
developer2edaf012023-05-24 14:24:53 +080011269
developer72fb0bb2023-01-11 09:46:29 +080011270INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
11271{
11272 FILE *fp = NULL;
11273 char str[MAX_BUF_SIZE] = {0};
11274 int wificlientindex = 0 ;
11275 int count = 0;
11276 int signalstrength = 0;
11277 int arr[MACADDRESS_SIZE] = {0};
11278 unsigned char mac[MACADDRESS_SIZE] = {0};
11279 UINT wifi_count = 0;
developer72fb0bb2023-01-11 09:46:29 +080011280 char pipeCmd[MAX_CMD_SIZE] = {0};
11281
11282 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11283 *output_array_size = 0;
11284 *associated_dev_array = NULL;
11285 char interface_name[50] = {0};
11286
11287 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11288 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11289 return RETURN_ERR;
11290 }
11291
11292 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
11293 fp = popen(pipeCmd, "r");
11294 if (fp == NULL)
11295 {
11296 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11297 return RETURN_ERR;
11298 }
11299
11300 /* Read the output a line at a time - output it. */
11301 fgets(str, sizeof(str)-1, fp);
11302 wifi_count = (unsigned int) atoi ( str );
11303 *output_array_size = wifi_count;
11304 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11305 pclose(fp);
11306
11307 if(wifi_count == 0)
11308 {
11309 return RETURN_OK;
11310 }
11311 else
11312 {
11313 wifi_associated_dev2_t* temp = NULL;
11314 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
11315 *associated_dev_array = temp;
11316 if(temp == NULL)
11317 {
11318 printf("Error Statement. Insufficient memory \n");
11319 return RETURN_ERR;
11320 }
11321
11322 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11323 system(pipeCmd);
11324
11325 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11326 if(fp == NULL)
11327 {
11328 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11329 return RETURN_ERR;
11330 }
11331 fclose(fp);
11332
11333 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11334 fp = popen(pipeCmd, "r");
11335 if(fp)
11336 {
11337 for(count =0 ; count < wifi_count; count++)
11338 {
11339 fgets(str, MAX_BUF_SIZE, fp);
11340 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11341 {
11342 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11343 {
11344 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
11345
11346 }
11347 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11348 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]);
11349 }
11350 temp[count].cli_AuthenticationState = 1; //TODO
11351 temp[count].cli_Active = 1; //TODO
11352 }
11353 pclose(fp);
11354 }
11355
11356 //Updating RSSI per client
11357 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11358 fp = popen(pipeCmd, "r");
11359 if(fp)
11360 {
11361 pclose(fp);
11362 }
11363 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11364 if(fp)
11365 {
11366 for(count =0 ; count < wifi_count ;count++)
11367 {
11368 fgets(str, MAX_BUF_SIZE, fp);
11369 signalstrength = atoi(str);
11370 temp[count].cli_RSSI = signalstrength;
11371 }
11372 pclose(fp);
11373 }
11374
11375
11376 //LastDataDownlinkRate
11377 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
11378 fp = popen(pipeCmd, "r");
11379 if (fp)
11380 {
11381 pclose(fp);
11382 }
11383 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
11384 if (fp)
11385 {
11386 for (count = 0; count < wifi_count; count++)
11387 {
11388 fgets(str, MAX_BUF_SIZE, fp);
11389 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
11390 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
11391 }
11392 pclose(fp);
11393 }
11394
11395 //LastDataUplinkRate
11396 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
11397 fp = popen(pipeCmd, "r");
11398 if (fp)
11399 {
11400 pclose(fp);
11401 }
11402 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
11403 if (fp)
11404 {
11405 for (count = 0; count < wifi_count; count++)
11406 {
11407 fgets(str, MAX_BUF_SIZE, fp);
11408 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
11409 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
11410 }
11411 pclose(fp);
11412 }
11413 }
11414 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11415 return RETURN_OK;
11416
11417}
11418
11419INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
11420{
11421#if 0
11422 /*char buf[1024] = {0};
11423 sprintf(cmd, "ifconfig %s ", interface_name);
11424 _syscmd(cmd, buf, sizeof(buf));*/
11425
11426 output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters.
11427 output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters.
11428 output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface.
11429 output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface.
11430
11431 output_struct->ssid_RetransCount = 0; //The total number of transmitted packets which were retransmissions. Two retransmissions of the same packet results in this counter incrementing by two.
11432 output_struct->ssid_FailedRetransCount = 0; //The number of packets that were not transmitted successfully due to the number of retransmission attempts exceeding an 802.11 retry limit. This parameter is based on dot11FailedCount from [802.11-2012].
11433 output_struct->ssid_RetryCount = 0; //The number of packets that were successfully transmitted after one or more retransmissions. This parameter is based on dot11RetryCount from [802.11-2012].
11434 output_struct->ssid_MultipleRetryCount = 0; //The number of packets that were successfully transmitted after more than one retransmission. This parameter is based on dot11MultipleRetryCount from [802.11-2012].
11435 output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012].
11436 output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac.
11437
11438 output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors.
11439 output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11440 output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11441 output_struct->ssid_UnicastPacketsReceived = 2; //The total number of received packets, delivered by this layer to a higher layer, which were not addressed to a multicast or broadcast address at this layer.
11442 output_struct->ssid_DiscardedPacketsSent = 1; //The total number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space.
11443 output_struct->ssid_DiscardedPacketsReceived = 1; //The total number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being delivered. One possible reason for discarding such a packet could be to free up buffer space.
11444 output_struct->ssid_MulticastPacketsSent = 10; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a multicast address at this layer, including those that were discarded or not sent.
11445 output_struct->ssid_MulticastPacketsReceived = 0; //The total number of received packets, delivered by this layer to a higher layer, which were addressed to a multicast address at this layer.
11446 output_struct->ssid_BroadcastPacketsSent = 0; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a broadcast address at this layer, including those that were discarded or not sent.
11447 output_struct->ssid_BroadcastPacketsRecevied = 1; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a broadcast address at this layer, including those that were discarded or not sent.
11448 output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol.
11449#endif
11450
11451 FILE *fp = NULL;
11452 char interface_name[50] = {0};
11453 char pipeCmd[128] = {0};
11454 char str[256] = {0};
11455 wifi_ssidTrafficStats2_t *out = output_struct;
11456
11457 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11458 if (!output_struct)
11459 return RETURN_ERR;
11460
11461 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
11462 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
11463 return RETURN_ERR;
11464 sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name);
11465
11466 fp = popen(pipeCmd, "r");
11467 if (fp == NULL) {
11468 fprintf(stderr, "%s: popen failed\n", __func__);
11469 return RETURN_ERR;
11470 }
11471 fgets(str, sizeof(str), fp);
11472 pclose(fp);
11473
11474 if (strlen(str) == 0) // interface not exist
11475 return RETURN_OK;
11476
developer5a333cf2023-06-06 18:18:50 +080011477 sscanf(str, "%*[^:]: %lu %lu %lu %lu %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
developer72fb0bb2023-01-11 09:46:29 +080011478 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
11479
11480 memset(str, 0, sizeof(str));
11481 sprintf(pipeCmd, "tail -n1 /proc/net/netstat");
11482 fp = popen(pipeCmd, "r");
11483 if (fp == NULL) {
11484 fprintf(stderr, "%s: popen failed\n", __func__);
11485 return RETURN_ERR;
11486 }
11487 fgets(str, sizeof(str), fp);
11488
developer5a333cf2023-06-06 18:18:50 +080011489 sscanf(str, "%*[^:]: %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
developer72fb0bb2023-01-11 09:46:29 +080011490 &out->ssid_BroadcastPacketsSent);
11491 pclose(fp);
11492
11493 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
11494 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
11495
11496 // Not supported
11497 output_struct->ssid_RetransCount = 0;
11498 output_struct->ssid_FailedRetransCount = 0;
11499 output_struct->ssid_RetryCount = 0;
11500 output_struct->ssid_MultipleRetryCount = 0;
11501 output_struct->ssid_ACKFailureCount = 0;
11502 output_struct->ssid_AggregatedPacketCount = 0;
11503
11504 return RETURN_OK;
11505}
11506
11507//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).
11508INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
11509{
11510 char output_val[16]={'\0'};
11511 char config_file[MAX_BUF_SIZE] = {0};
11512
11513 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11514 if (!output)
11515 return RETURN_ERR;
11516 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11517 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
11518
11519 if( strcmp(output_val,"1") == 0 )
11520 *output = TRUE;
11521 else
11522 *output = FALSE;
11523 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11524
11525 return RETURN_OK;
11526}
11527
11528INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
11529{
11530 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011531 char string[MAX_BUF_SIZE]={'\0'};
developer72fb0bb2023-01-11 09:46:29 +080011532 char config_file[MAX_BUF_SIZE] = {0};
11533 struct params params;
11534
11535 if(enable == TRUE)
11536 strcpy(string,"1");
11537 else
11538 strcpy(string,"0");
11539
11540 params.name = "ap_isolate";
11541 params.value = string;
11542
11543 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11544 wifi_hostapdWrite(config_file,&params,1);
11545 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11546
11547 return RETURN_OK;
11548}
11549
11550INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
11551{
developera1255e42023-05-13 17:45:02 +080011552 char mgmtpwr_file[32] = {0};
11553 char cmd[64] = {0};
11554 char buf[32]={0};
11555
developer72fb0bb2023-01-11 09:46:29 +080011556 if (NULL == output_dBm)
11557 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080011558 snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
11559 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
11560 _syscmd(cmd, buf, sizeof(buf));
11561 if (strlen(buf) > 0)
11562 *output_dBm = strtol(buf, NULL, 10);
11563 else
11564 *output_dBm = 23;
developer72fb0bb2023-01-11 09:46:29 +080011565 return RETURN_OK;
11566}
11567
11568INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
11569{
developera1255e42023-05-13 17:45:02 +080011570 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080011571 char mgmt_pwr_file[128]={0};
11572 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080011573 int if_idx, ret = 0;
11574 struct nl_msg *msg = NULL;
11575 struct nlattr * msg_data = NULL;
11576 struct mtk_nl80211_param param;
11577 struct unl unl_ins;
11578 char power[16] = {0};
developera1255e42023-05-13 17:45:02 +080011579
11580 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11581
11582 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
11583 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080011584
11585 if_idx = if_nametoindex(interface_name);
11586 /*init mtk nl80211 vendor cmd*/
11587 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
11588 param.if_type = NL80211_ATTR_IFINDEX;
11589 param.if_idx = if_idx;
11590
11591 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11592 if (ret) {
11593 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11594 return RETURN_ERR;
11595 }
11596
11597 /*add mtk vendor cmd data*/
11598 snprintf(power, sizeof(power), "%d", dBm);
11599 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
11600 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11601 nlmsg_free(msg);
11602 goto err;
11603 }
11604
11605 /*send mtk nl80211 vendor msg*/
11606 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11607 if (ret) {
11608 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
11609 goto err;
11610 }
11611
11612 /*deinit mtk nl80211 vendor msg*/
11613 mtk_nl80211_deint(&unl_ins);
11614 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
11615
developera1255e42023-05-13 17:45:02 +080011616 snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
11617 f = fopen(mgmt_pwr_file, "w");
11618 if (f == NULL) {
11619 fprintf(stderr, "%s: fopen failed\n", __func__);
11620 return RETURN_ERR;
11621 }
11622 fprintf(f, "%d", dBm);
11623 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080011624 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080011625err:
11626 mtk_nl80211_deint(&unl_ins);
11627 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11628 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011629}
11630INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
11631{
11632 return RETURN_OK;
11633}
11634INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
11635{
11636 return RETURN_OK;
11637}
11638INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
11639{
11640 return RETURN_OK;
11641}
11642INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
11643{
11644 return RETURN_OK;
11645}
11646INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
11647{
11648 char config_file[MAX_BUF_SIZE] = {0};
11649 struct params list;
11650
11651 list.name = "bss_transition";
11652 list.value = activate?"1":"0";
11653 snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
11654 wifi_hostapdWrite(config_file, &list, 1);
11655
11656 return RETURN_OK;
11657}
11658wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
11659
11660void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
11661{
11662 return;
11663}
11664
11665INT wifi_setApCsaDeauth(INT apIndex, INT mode)
11666{
11667 // TODO Implement me!
11668 return RETURN_OK;
11669}
11670
11671INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
11672{
11673 char file_name[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011674 FILE *f = NULL;
11675 int max_num_radios = 0;
11676
11677 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11678
11679 wifi_getMaxRadioNumber(&max_num_radios);
11680 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
11681 for (int index = 0; index < max_num_radios; index++) {
11682 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
11683 f = fopen(file_name, "w");
11684 if (f == NULL)
11685 return RETURN_ERR;
11686 // For mode == 0 is to disable filter, just don't write to the file.
11687 if (mode)
11688 fprintf(f, "%s", essid);
11689
11690 fclose(f);
11691 }
11692 } else { // special case, need to set AP's SSID as filter for each radio.
11693 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
11694 f = fopen(file_name, "w");
11695 if (f == NULL)
11696 return RETURN_ERR;
11697
11698 // For mode == 0 is to disable filter, just don't write to the file.
11699 if (mode)
11700 fprintf(f, "%s", essid);
11701
11702 fclose(f);
11703 }
11704
11705 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11706 return RETURN_OK;
11707}
11708
11709INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
11710{
11711 // TODO Implement me!
11712 //Apply wifi_pushRadioChannel() instantly
11713 return RETURN_ERR;
11714}
11715
11716INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
11717{
11718 // TODO Implement me!
11719 return RETURN_OK;
11720}
11721
11722#ifdef HAL_NETLINK_IMPL
11723static int tidStats_callback(struct nl_msg *msg, void *arg) {
11724 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11725 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11726 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
11727 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
11728 int rem , tid_index = 0;
11729
11730 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
11731 wifi_associated_dev_tid_entry_t *stats_entry;
11732
11733 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
11734 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
11735 };
11736 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
11737 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
11738 };
11739
11740 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11741 genlmsg_attrlen(gnlh, 0), NULL);
11742
11743
11744 if (!tb[NL80211_ATTR_STA_INFO]) {
11745 fprintf(stderr, "station stats missing!\n");
11746 return NL_SKIP;
11747 }
11748
11749 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
11750 tb[NL80211_ATTR_STA_INFO],
11751 stats_policy)) {
11752 fprintf(stderr, "failed to parse nested attributes!\n");
11753 return NL_SKIP;
11754 }
11755
developer386281b2023-05-20 15:43:13 +080011756 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
11757 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
11758 {
11759 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080011760
developer386281b2023-05-20 15:43:13 +080011761 stats_entry->tid = tid_index;
11762 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080011763
developer386281b2023-05-20 15:43:13 +080011764 if(sinfo[NL80211_STA_INFO_TID_STATS])
11765 {
11766 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
11767 printf("failed to parse nested stats attributes!");
11768 return NL_SKIP;
11769 }
developer72fb0bb2023-01-11 09:46:29 +080011770 }
developer386281b2023-05-20 15:43:13 +080011771 if(stats_info[NL80211_TID_STATS_TX_MSDU])
11772 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080011773
developer386281b2023-05-20 15:43:13 +080011774 if(tid_index < (PS_MAX_TID - 1))
11775 tid_index++;
11776 }
developer72fb0bb2023-01-11 09:46:29 +080011777 }
11778 //ToDo: sum_time_ms, ewma_time_ms
11779 return NL_SKIP;
11780}
11781#endif
11782
11783INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
11784{
11785#ifdef HAL_NETLINK_IMPL
11786 Netlink nl;
developerb149d9d2023-06-06 16:14:22 +080011787 char if_name[IF_NAME_SIZE];
11788 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011789
11790 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
11791 return RETURN_ERR;
11792
11793 snprintf(if_name, sizeof(if_name), "%s", interface_name);
11794
11795 nl.id = initSock80211(&nl);
11796
11797 if (nl.id < 0) {
11798 fprintf(stderr, "Error initializing netlink \n");
11799 return -1;
11800 }
11801
11802 struct nl_msg* msg = nlmsg_alloc();
11803
11804 if (!msg) {
11805 fprintf(stderr, "Failed to allocate netlink message.\n");
11806 nlfree(&nl);
11807 return -2;
11808 }
11809
11810 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080011811 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080011812 NL_AUTO_SEQ,
11813 nl.id,
11814 0,
11815 0,
11816 NL80211_CMD_GET_STATION,
11817 0);
11818
11819 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
11820 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
11821 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
developer8dd72532023-05-17 19:58:35 +080011822 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080011823 nl_recvmsgs(nl.socket, nl.cb);
11824 nlmsg_free(msg);
11825 nlfree(&nl);
11826 return RETURN_OK;
11827#else
11828//iw implementation
11829#define TID_STATS_FILE "/tmp/tid_stats_file.txt"
11830#define TOTAL_MAX_LINES 50
11831
11832 char buf[256] = {'\0'}; /* or other suitable maximum line size */
11833 char if_name[32] = {0};
11834 FILE *fp=NULL;
11835 char pipeCmd[1024]= {'\0'};
11836 int lines,tid_index=0;
11837 char mac_addr[20] = {'\0'};
11838
11839 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
11840 return RETURN_ERR;
11841
11842 wifi_associated_dev_tid_entry_t *stats_entry;
11843
11844 strcpy(mac_addr,clientMacAddress);
11845
11846 snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name);
11847 fp= popen(pipeCmd,"r");
11848 if(fp == NULL)
11849 {
11850 perror("popen for station dump failed\n");
11851 return RETURN_ERR;
11852 }
11853 pclose(fp);
11854
11855 snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1");
11856 fp=popen(pipeCmd,"r");
11857 if(fp == NULL)
11858 {
11859 perror("popen for grep station failed\n");
11860 return RETURN_ERR;
11861 }
11862 else if(fgets(buf,sizeof(buf),fp) != NULL)
11863 lines=atoi(buf);
11864 else
11865 {
11866 pclose(fp);
11867 fprintf(stderr,"No devices are connected \n");
11868 return RETURN_ERR;
11869 }
11870 pclose(fp);
11871
11872 if(lines == 1)
11873 lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output
11874
11875 for(tid_index=0; tid_index<PS_MAX_TID; tid_index++)
11876 {
11877 stats_entry = &tid_stats->tid_array[tid_index];
11878 stats_entry->tid = tid_index;
11879
11880 snprintf(pipeCmd, sizeof(pipeCmd),"cat "TID_STATS_FILE" | awk '/%s/ {for(i=0; i<=%d; i++) {getline; print}}' | grep -F -A%d 'MSDU' | awk '{print $3}' | tail -1",mac_addr,lines,tid_index+2);
11881
11882 fp=popen(pipeCmd,"r");
11883 if(fp ==NULL)
11884 {
11885 perror("Failed to read from tid file \n");
11886 return RETURN_ERR;
11887 }
11888 else if(fgets(buf,sizeof(buf),fp) != NULL)
11889 stats_entry->num_msdus = atol(buf);
11890
11891 pclose(fp);
11892 stats_entry->ac = _tid_ac_index_get[tid_index];
11893// TODO:
11894// ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus
11895// ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval
11896 }
11897 return RETURN_OK;
11898#endif
11899}
11900
11901
11902INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
11903{
11904 char interface_name[16] = {0};
11905 char cmd[128]={0};
11906 char buf[128]={0};
11907 int freq = 0;
11908
11909 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11910
11911 // full mode is used to scan all channels.
11912 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
11913 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
11914 ieee80211_channel_to_frequency(chan_list[0], &freq);
11915
11916 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11917 return RETURN_ERR;
11918
11919 if (freq)
11920 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
11921 else
11922 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
11923
11924 _syscmd(cmd, buf, sizeof(buf));
11925 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11926
11927 return RETURN_OK;
11928}
11929
11930
11931INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
11932{
11933 // TODO Implement me!
11934 return RETURN_ERR;
11935}
11936
11937INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
11938{
11939 // TODO Implement me!
11940 return RETURN_ERR;
11941}
11942
11943INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
11944{
11945 // TODO Implement me!
11946 return RETURN_ERR;
11947}
11948
11949INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
11950{
11951 // TODO Implement me!
11952 return RETURN_ERR;
11953}
11954
11955INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
11956{
11957 // TODO Implement me!
11958 return RETURN_ERR;
11959}
11960
11961INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
11962{
11963 // TODO Implement me!
11964 return RETURN_ERR;
11965}
11966
11967INT wifi_steering_eventUnregister(void)
11968{
11969 // TODO Implement me!
11970 return RETURN_ERR;
11971}
11972
11973INT wifi_delApAclDevices(INT apIndex)
11974{
developer7e4a2a62023-04-06 19:56:03 +080011975 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080011976 struct unl unl_ins;
11977 int if_idx = 0, ret = 0;
11978 struct nl_msg *msg = NULL;
11979 struct nlattr * msg_data = NULL;
11980 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080011981
developer7e4a2a62023-04-06 19:56:03 +080011982 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
11983 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011984 if_idx = if_nametoindex(inf_name);
11985 if (!if_idx) {
11986 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
11987 return RETURN_ERR;
11988 }
11989 /*init mtk nl80211 vendor cmd*/
11990 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
11991 param.if_type = NL80211_ATTR_IFINDEX;
11992 param.if_idx = if_idx;
11993 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11994 if (ret) {
11995 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11996 return RETURN_ERR;
11997 }
11998 /*add mtk vendor cmd data*/
11999 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
12000 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
12001 nlmsg_free(msg);
12002 goto err;
12003 }
12004 /*send mtk nl80211 vendor msg*/
12005 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
12006 if (ret) {
12007 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
12008 goto err;
12009 }
12010 /*deinit mtk nl80211 vendor msg*/
12011 mtk_nl80211_deint(&unl_ins);
12012 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
12013 return RETURN_OK;
12014err:
12015 mtk_nl80211_deint(&unl_ins);
12016 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12017 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012018
12019 return RETURN_OK;
12020}
12021
12022#ifdef HAL_NETLINK_IMPL
12023static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
12024 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12025 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12026 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12027 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12028 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12029 char mac_addr[20],dev[20];
12030
12031 nla_parse(tb,
12032 NL80211_ATTR_MAX,
12033 genlmsg_attrdata(gnlh, 0),
12034 genlmsg_attrlen(gnlh, 0),
12035 NULL);
12036
12037 if(!tb[NL80211_ATTR_STA_INFO]) {
12038 fprintf(stderr, "sta stats missing!\n");
12039 return NL_SKIP;
12040 }
12041
12042 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12043 fprintf(stderr, "failed to parse nested attributes!\n");
12044 return NL_SKIP;
12045 }
12046 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
12047
12048 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12049
developer386281b2023-05-20 15:43:13 +080012050 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12051 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
12052 fprintf(stderr, "failed to parse nested rate attributes!");
12053 return NL_SKIP;
12054 }
developer72fb0bb2023-01-11 09:46:29 +080012055 }
12056
12057 if(sinfo[NL80211_STA_INFO_TID_STATS])
12058 {
12059 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12060 printf("failed to parse nested stats attributes!");
12061 return NL_SKIP;
12062 }
12063 }
developer5a1194f2023-05-24 16:00:03 +080012064 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080012065
developereb1ea832023-05-24 14:46:27 +080012066 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
12067 {
12068 printf("Type is VHT\n");
12069 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12070 ((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 +080012071
developereb1ea832023-05-24 14:46:27 +080012072 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12073 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
12074 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12075 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12076 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12077 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12078 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12079 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12080 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
12081 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12082 }
12083 else
12084 {
12085 printf(" OFDM or CCK \n");
12086 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12087 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
12088 }
12089 }
developer72fb0bb2023-01-11 09:46:29 +080012090
developereff896f2023-05-29 14:52:55 +080012091 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12092 if(rinfo[NL80211_RATE_INFO_MCS])
12093 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12094 }
12095 if(sinfo[NL80211_STA_INFO_RX_BYTES64])
12096 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
12097 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
12098 ((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 +080012099
developereff896f2023-05-29 14:52:55 +080012100 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12101 if(stats_info[NL80211_TID_STATS_RX_MSDU])
12102 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
12103 }
developer72fb0bb2023-01-11 09:46:29 +080012104
developereff896f2023-05-29 14:52:55 +080012105 if (sinfo[NL80211_STA_INFO_SIGNAL])
12106 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
12107 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
12108 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
12109 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
12110 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
12111 //rssi_array need to be filled
12112 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080012113}
12114#endif
12115
12116INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12117{
12118#ifdef HAL_NETLINK_IMPL
12119 Netlink nl;
12120 char if_name[32];
12121 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12122 return RETURN_ERR;
12123
12124 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
12125
12126 if (*output_array_size <= 0)
12127 return RETURN_OK;
12128
12129 nl.id = initSock80211(&nl);
12130
12131 if (nl.id < 0) {
12132 fprintf(stderr, "Error initializing netlink \n");
12133 return 0;
12134 }
12135
12136 struct nl_msg* msg = nlmsg_alloc();
12137
12138 if (!msg) {
12139 fprintf(stderr, "Failed to allocate netlink message.\n");
12140 nlfree(&nl);
12141 return 0;
12142 }
12143
12144 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012145 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012146 NL_AUTO_SEQ,
12147 nl.id,
12148 0,
12149 0,
12150 NL80211_CMD_GET_STATION,
12151 0);
12152
12153 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
12154 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12155 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012156 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012157 nl_recvmsgs(nl.socket, nl.cb);
12158 nlmsg_free(msg);
12159 nlfree(&nl);
12160 return RETURN_OK;
12161#else
12162 //TODO Implement me
12163 return RETURN_OK;
12164#endif
12165}
12166
12167#ifdef HAL_NETLINK_IMPL
12168static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
12169 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12170 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12171 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12172 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12173 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12174 char mac_addr[20],dev[20];
12175
12176 nla_parse(tb,
12177 NL80211_ATTR_MAX,
12178 genlmsg_attrdata(gnlh, 0),
12179 genlmsg_attrlen(gnlh, 0),
12180 NULL);
12181
12182 if(!tb[NL80211_ATTR_STA_INFO]) {
12183 fprintf(stderr, "sta stats missing!\n");
12184 return NL_SKIP;
12185 }
12186
12187 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12188 fprintf(stderr, "failed to parse nested attributes!\n");
12189 return NL_SKIP;
12190 }
12191
12192 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
12193
12194 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12195
developer386281b2023-05-20 15:43:13 +080012196 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12197 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
12198 fprintf(stderr, "failed to parse nested rate attributes!");
12199 return NL_SKIP;
12200 }
developer72fb0bb2023-01-11 09:46:29 +080012201 }
12202
12203 if(sinfo[NL80211_STA_INFO_TID_STATS])
12204 {
12205 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12206 printf("failed to parse nested stats attributes!");
12207 return NL_SKIP;
12208 }
12209 }
developera6beea42023-05-24 16:44:05 +080012210 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developereb1ea832023-05-24 14:46:27 +080012211 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
12212 {
12213 printf("Type is VHT\n");
12214 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12215 ((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 +080012216
developereb1ea832023-05-24 14:46:27 +080012217 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12218 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
12219 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12220 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12221 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12222 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12223 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12224 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12225 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
12226 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
12227 }
12228 else
12229 {
12230 printf(" OFDM or CCK \n");
developer72fb0bb2023-01-11 09:46:29 +080012231 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
developereb1ea832023-05-24 14:46:27 +080012232 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
12233 }
developer72fb0bb2023-01-11 09:46:29 +080012234 }
12235
12236 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12237 if(rinfo[NL80211_RATE_INFO_MCS])
12238 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12239 }
12240
12241 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
12242 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
12243 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
12244 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
12245
12246 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
developereff896f2023-05-29 14:52:55 +080012247 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
12248 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080012249
developereff896f2023-05-29 14:52:55 +080012250 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12251 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12252 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
12253 }
developer72fb0bb2023-01-11 09:46:29 +080012254
12255 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
12256 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
12257
developereff896f2023-05-29 14:52:55 +080012258 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
12259 ((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 +080012260
12261 return NL_SKIP;
12262}
12263#endif
12264
12265INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12266{
12267#ifdef HAL_NETLINK_IMPL
12268 Netlink nl;
developerb149d9d2023-06-06 16:14:22 +080012269 char if_name[IF_NAME_SIZE];
12270 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080012271 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12272 return RETURN_ERR;
12273
12274 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
12275
12276 if (*output_array_size <= 0)
12277 return RETURN_OK;
12278
12279 snprintf(if_name, sizeof(if_name), "%s", interface_name);
12280
12281 nl.id = initSock80211(&nl);
12282
12283 if(nl.id < 0) {
12284 fprintf(stderr, "Error initializing netlink \n");
12285 return 0;
12286 }
12287
12288 struct nl_msg* msg = nlmsg_alloc();
12289
12290 if(!msg) {
12291 fprintf(stderr, "Failed to allocate netlink message.\n");
12292 nlfree(&nl);
12293 return 0;
12294 }
12295
12296 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012297 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012298 NL_AUTO_SEQ,
12299 nl.id,
12300 0,
12301 0,
12302 NL80211_CMD_GET_STATION,
12303 0);
12304
12305 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12306 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12307 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012308 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012309 nl_recvmsgs(nl.socket, nl.cb);
12310 nlmsg_free(msg);
12311 nlfree(&nl);
12312 return RETURN_OK;
12313#else
12314 //TODO Implement me
12315 return RETURN_OK;
12316#endif
12317}
12318
12319INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
12320{
12321 // TODO Implement me!
12322 char buf[MAX_BUF_SIZE] = {0};
12323 char config_file[MAX_BUF_SIZE] = {0};
12324
12325 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12326 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
12327 *activate = (strncmp("1",buf,1) == 0);
12328
12329 return RETURN_OK;
12330}
12331
12332INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
12333{
12334 char config_file[MAX_BUF_SIZE] = {0};
12335 struct params list;
12336
12337 list.name = "rrm_neighbor_report";
12338 list.value = activate?"1":"0";
12339 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12340 wifi_hostapdWrite(config_file, &list, 1);
12341
12342 return RETURN_OK;
12343}
12344
12345INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
12346{
12347 char buf[32] = {0};
12348 char config_file[MAX_BUF_SIZE] = {0};
12349
12350 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12351 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
12352 *activate = (strncmp("1",buf,1) == 0);
12353
12354 return RETURN_OK;
12355}
12356#undef HAL_NETLINK_IMPL
12357#ifdef HAL_NETLINK_IMPL
12358static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
12359 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12360 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12361 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
12362 char dev[20];
12363 int freq =0 ;
12364 static int i=0;
12365
12366 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
12367
12368 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
12369 };
12370
12371 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
12372
12373 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12374
12375 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
12376 fprintf(stderr, "survey data missing!\n");
12377 return NL_SKIP;
12378 }
12379
12380 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
12381 {
12382 fprintf(stderr, "failed to parse nested attributes!\n");
12383 return NL_SKIP;
12384 }
12385
12386
12387 if(out[0].array_size == 1 )
12388 {
12389 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
12390 {
12391 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12392 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12393 out[0].ch_number = ieee80211_frequency_to_channel(freq);
12394
12395 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12396 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12397 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12398 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12399 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12400 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12401 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12402 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12403 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12404 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12405 if (sinfo[NL80211_SURVEY_INFO_TIME])
12406 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12407 return NL_STOP;
12408 }
12409 }
12410 else
12411 {
12412 if ( i <= out[0].array_size )
12413 {
12414 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12415 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12416 out[i].ch_number = ieee80211_frequency_to_channel(freq);
12417
12418 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12419 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12420 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12421 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12422 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12423 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12424 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12425 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12426 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12427 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12428 if (sinfo[NL80211_SURVEY_INFO_TIME])
12429 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12430 }
12431 }
12432
12433 i++;
12434 return NL_SKIP;
12435}
12436#endif
12437
12438static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
12439{
12440 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
12441 FILE *fp;
12442
12443 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
12444 {
12445 printf("Creating Frequency-Channel Map\n");
12446 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
12447 }
12448 snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
12449 if((fp = popen(command, "r")))
12450 {
12451 fgets(output, sizeof(output), fp);
12452 *freqMHz = atoi(output);
12453 pclose(fp);
12454 }
12455
12456 return 0;
12457}
12458
developer2f79c922023-06-02 17:33:42 +080012459static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
developer72fb0bb2023-01-11 09:46:29 +080012460{
12461 int freqMHz = -1;
12462 char cmd[MAX_CMD_SIZE] = {'\0'};
12463 char interface_name[16] = {0};
12464
12465 ieee80211_channel_to_frequency(channel, &freqMHz);
12466 if (freqMHz == -1) {
12467 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
12468 return -1;
12469 }
12470
12471 wifi_GetInterfaceName(radioIndex, interface_name);
12472 if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) {
12473 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
12474 radioIndex, freqMHz);
12475 return -1;
12476 }
12477
12478 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
12479 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
12480 return -1;
12481 }
12482
12483 return 0;
12484}
12485
12486static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
12487{
12488 const char *ptr = buf;
12489 char *key = NULL;
12490 char *val = NULL;
12491 char line[256] = { '\0' };
12492
developerdaf24792023-06-06 11:40:04 +080012493 while ((ptr = get_line_from_str_buf(ptr, line))) {
developer72fb0bb2023-01-11 09:46:29 +080012494 if (strstr(line, "Frequency")) continue;
12495
12496 key = strtok(line, ":");
12497 val = strtok(NULL, " ");
12498 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
12499
12500 if (!strcmp(key, "noise")) {
12501 sscanf(val, "%d", &stats->ch_noise);
12502 if (stats->ch_noise == 0) {
12503 // Workaround for missing noise information.
12504 // Assume -95 for 2.4G and -103 for 5G
12505 if (radioIndex == 0) stats->ch_noise = -95;
12506 if (radioIndex == 1) stats->ch_noise = -103;
12507 }
12508 }
12509 else if (!strcmp(key, "channel active time")) {
12510 sscanf(val, "%llu", &stats->ch_utilization_total);
12511 }
12512 else if (!strcmp(key, "channel busy time")) {
12513 sscanf(val, "%llu", &stats->ch_utilization_busy);
12514 }
12515 else if (!strcmp(key, "channel receive time")) {
12516 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
12517 }
12518 else if (!strcmp(key, "channel transmit time")) {
12519 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
12520 }
12521 };
12522
12523 return 0;
12524}
12525
12526INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
12527{
12528 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12529#ifdef HAL_NETLINK_IMPL
12530 Netlink nl;
12531 wifi_channelStats_t_loc local[array_size];
12532 char if_name[32];
12533
12534 local[0].array_size = array_size;
12535
12536 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12537 return RETURN_ERR;
12538
12539 nl.id = initSock80211(&nl);
12540
12541 if (nl.id < 0) {
12542 fprintf(stderr, "Error initializing netlink \n");
12543 return -1;
12544 }
12545
12546 struct nl_msg* msg = nlmsg_alloc();
12547
12548 if (!msg) {
12549 fprintf(stderr, "Failed to allocate netlink message.\n");
12550 nlfree(&nl);
12551 return -2;
12552 }
12553
12554 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012555 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012556 NL_AUTO_SEQ,
12557 nl.id,
12558 0,
12559 NLM_F_DUMP,
12560 NL80211_CMD_GET_SURVEY,
12561 0);
12562
12563 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +080012564 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012565 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
12566 nl_recvmsgs(nl.socket, nl.cb);
12567 nlmsg_free(msg);
12568 nlfree(&nl);
12569 //Copying the Values
12570 for(int i=0;i<array_size;i++)
12571 {
12572 input_output_channelStats_array[i].ch_number = local[i].ch_number;
12573 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
12574 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
12575 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
12576 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
12577 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
12578 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
12579 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
12580 }
12581#else
12582 ULONG channel = 0;
12583 int i;
12584 int number_of_channels = array_size;
12585 char buf[512];
developer72fb0bb2023-01-11 09:46:29 +080012586
12587 if (number_of_channels == 0) {
12588 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
12589 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
12590 return RETURN_ERR;
12591 }
12592 number_of_channels = 1;
12593 input_output_channelStats_array[0].ch_number = channel;
12594 }
12595
12596 for (i = 0; i < number_of_channels; i++) {
12597
12598 input_output_channelStats_array[i].ch_noise = 0;
12599 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
12600 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
12601 input_output_channelStats_array[i].ch_utilization_busy = 0;
12602 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
12603 input_output_channelStats_array[i].ch_utilization_total = 0;
12604
12605 memset(buf, 0, sizeof(buf));
12606 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
12607 return RETURN_ERR;
12608 }
12609 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
12610 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
12611 return RETURN_ERR;
12612 }
12613
12614 // XXX: fake missing 'self' counter which is not available in iw survey output
12615 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
12616 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
12617
12618 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
12619 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
12620 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
12621 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
12622 input_output_channelStats_array[i].ch_utilization_total *= 1000;
12623
12624 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",
12625 __func__,
12626 input_output_channelStats_array[i].ch_number,
12627 input_output_channelStats_array[i].ch_noise,
12628 input_output_channelStats_array[i].ch_utilization_total,
12629 input_output_channelStats_array[i].ch_utilization_busy,
12630 input_output_channelStats_array[i].ch_utilization_busy_rx,
12631 input_output_channelStats_array[i].ch_utilization_busy_tx,
12632 input_output_channelStats_array[i].ch_utilization_busy_self,
12633 input_output_channelStats_array[i].ch_utilization_busy_ext);
12634 }
12635#endif
12636 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12637 return RETURN_OK;
12638}
12639#define HAL_NETLINK_IMPL
12640
12641/* Hostapd events */
12642
12643#ifndef container_of
12644#define offset_of(st, m) ((size_t)&(((st *)0)->m))
12645#define container_of(ptr, type, member) \
12646 ((type *)((char *)ptr - offset_of(type, member)))
12647#endif /* container_of */
12648
12649struct ctrl {
12650 char sockpath[128];
12651 char sockdir[128];
12652 char bss[IFNAMSIZ];
12653 char reply[4096];
12654 int ssid_index;
12655 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
12656 void (*overrun)(struct ctrl *ctrl);
12657 struct wpa_ctrl *wpa;
12658 unsigned int ovfl;
12659 size_t reply_len;
12660 int initialized;
12661 ev_timer retry;
12662 ev_timer watchdog;
12663 ev_stat stat;
12664 ev_io io;
12665};
12666static wifi_newApAssociatedDevice_callback clients_connect_cb;
12667static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
12668static struct ctrl wpa_ctrl[MAX_APS];
12669static int initialized;
12670
12671static unsigned int ctrl_get_drops(struct ctrl *ctrl)
12672{
12673 char cbuf[256] = {};
12674 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
12675 struct cmsghdr *cmsg;
12676 unsigned int ovfl = ctrl->ovfl;
12677 unsigned int drop;
12678
12679 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
12680 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
12681 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
12682 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
12683
12684 drop = ovfl - ctrl->ovfl;
12685 ctrl->ovfl = ovfl;
12686
12687 return drop;
12688}
12689
12690static void ctrl_close(struct ctrl *ctrl)
12691{
12692 if (ctrl->io.cb)
12693 ev_io_stop(EV_DEFAULT_ &ctrl->io);
12694 if (ctrl->retry.cb)
12695 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
12696 if (!ctrl->wpa)
12697 return;
12698
12699 wpa_ctrl_detach(ctrl->wpa);
12700 wpa_ctrl_close(ctrl->wpa);
12701 ctrl->wpa = NULL;
12702 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
12703}
12704
12705static void ctrl_process(struct ctrl *ctrl)
12706{
12707 const char *str;
12708 int drops;
12709 int level;
developer72fb0bb2023-01-11 09:46:29 +080012710
12711 /* Example events:
12712 *
12713 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
12714 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
12715 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
12716 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
12717 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
12718 */
12719 if (!(str = index(ctrl->reply, '>')))
12720 return;
12721 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
12722 return;
12723
12724 str++;
12725
12726 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
12727 if (!(str = index(ctrl->reply, ' ')))
12728 return;
12729 wifi_associated_dev_t sta;
12730 memset(&sta, 0, sizeof(sta));
12731
12732 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
12733 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
12734 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
12735
12736 sta.cli_Active=true;
12737
12738 (clients_connect_cb)(ctrl->ssid_index, &sta);
12739 goto handled;
12740 }
12741
12742 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
12743 if (!(str = index(ctrl->reply, ' ')))
12744 return;
12745
12746 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
12747 goto handled;
12748 }
12749
12750 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
12751 printf("CTRL_WPA: handle TERMINATING event\n");
12752 goto retry;
12753 }
12754
12755 if (strncmp("AP-DISABLED", str, 11) == 0) {
12756 printf("CTRL_WPA: handle AP-DISABLED\n");
12757 goto retry;
12758 }
12759
12760 printf("Event not supported!!\n");
12761
12762handled:
12763
12764 if ((drops = ctrl_get_drops(ctrl))) {
12765 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
12766 if (ctrl->overrun)
12767 ctrl->overrun(ctrl);
12768 }
12769
12770 return;
12771
12772retry:
12773 printf("WPA_CTRL: closing\n");
12774 ctrl_close(ctrl);
12775 printf("WPA_CTRL: retrying from ctrl prcoess\n");
12776 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
12777}
12778
12779static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
12780{
12781 struct ctrl *ctrl = container_of(io, struct ctrl, io);
12782 int err;
12783
12784 memset(ctrl->reply, 0, sizeof(ctrl->reply));
12785 ctrl->reply_len = sizeof(ctrl->reply) - 1;
12786 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
12787 ctrl->reply[ctrl->reply_len] = 0;
12788 if (err < 0) {
12789 if (errno == EAGAIN || errno == EWOULDBLOCK)
12790 return;
12791 ctrl_close(ctrl);
12792 ev_timer_again(EV_A_ &ctrl->retry);
12793 return;
12794 }
12795
12796 ctrl_process(ctrl);
12797}
12798
12799static int ctrl_open(struct ctrl *ctrl)
12800{
12801 int fd;
12802
12803 if (ctrl->wpa)
12804 return 0;
12805
12806 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
12807 if (!ctrl->wpa)
12808 goto err;
12809
12810 if (wpa_ctrl_attach(ctrl->wpa) < 0)
12811 goto err_close;
12812
12813 fd = wpa_ctrl_get_fd(ctrl->wpa);
12814 if (fd < 0)
12815 goto err_detach;
12816
12817 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
12818 goto err_detach;
12819
12820 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
12821 ev_io_start(EV_DEFAULT_ &ctrl->io);
12822
12823 return 0;
12824
12825err_detach:
12826 wpa_ctrl_detach(ctrl->wpa);
12827err_close:
12828 wpa_ctrl_close(ctrl->wpa);
12829err:
12830 ctrl->wpa = NULL;
12831 return -1;
12832}
12833
12834static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
12835{
12836 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
12837
12838 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
12839 ctrl_open(ctrl);
12840}
12841
12842static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
12843{
12844 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
12845
12846 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
12847 if (ctrl_open(ctrl) == 0) {
12848 printf("WPA_CTRL: retry successful\n");
12849 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
12850 }
12851}
12852
12853int ctrl_enable(struct ctrl *ctrl)
12854{
12855 if (ctrl->wpa)
12856 return 0;
12857
12858 if (!ctrl->stat.cb) {
12859 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
12860 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
12861 }
12862
12863 if (!ctrl->retry.cb) {
12864 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
12865 }
12866
12867 return ctrl_open(ctrl);
12868}
12869
12870static void
12871ctrl_msg_cb(char *buf, size_t len)
12872{
12873 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
12874
12875 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
12876 ctrl_process(ctrl);
12877}
12878
12879static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
12880{
12881 int err;
12882
12883 if (!ctrl->wpa)
12884 return -1;
12885 if (*reply_len < 2)
12886 return -1;
12887
12888 (*reply_len)--;
12889 ctrl->reply_len = sizeof(ctrl->reply);
12890 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
12891 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
12892 if (err < 0)
12893 return err;
12894
12895 if (ctrl->reply_len > *reply_len)
12896 ctrl->reply_len = *reply_len;
12897
12898 *reply_len = ctrl->reply_len;
12899 memcpy(reply, ctrl->reply, *reply_len);
12900 reply[*reply_len - 1] = 0;
12901 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
12902 return 0;
12903}
12904
12905static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
12906{
12907 const char *pong = "PONG";
12908 const char *ping = "PING";
12909 char reply[1024];
12910 size_t len = sizeof(reply);
12911 int err;
12912 ULONG s, snum;
12913 INT ret;
12914 BOOL status;
12915
12916 printf("WPA_CTRL: watchdog cb\n");
12917
12918 ret = wifi_getSSIDNumberOfEntries(&snum);
12919 if (ret != RETURN_OK) {
12920 printf("%s: failed to get SSID count", __func__);
12921 return;
12922 }
12923
12924 if (snum > MAX_APS) {
12925 printf("more ssid than supported! %lu\n", snum);
12926 return;
12927 }
12928
12929 for (s = 0; s < snum; s++) {
12930 if (wifi_getApEnable(s, &status) != RETURN_OK) {
12931 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
12932 continue;
12933 }
12934 if (status == false) continue;
12935
12936 memset(reply, 0, sizeof(reply));
12937 len = sizeof(reply);
12938 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
12939 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
12940 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
12941 continue;
12942
12943 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
12944 ctrl_close(&wpa_ctrl[s]);
12945 printf("WPA_CTRL: ev_timer_again %lu\n", s);
12946 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
12947 }
12948}
12949
12950static int init_wpa()
12951{
developer2f79c922023-06-02 17:33:42 +080012952 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +080012953 ULONG s, snum;
12954
12955 ret = wifi_getSSIDNumberOfEntries(&snum);
12956 if (ret != RETURN_OK) {
12957 printf("%s: failed to get SSID count", __func__);
12958 return RETURN_ERR;
12959 }
12960
12961 if (snum > MAX_APS) {
12962 printf("more ssid than supported! %lu\n", snum);
12963 return RETURN_ERR;
12964 }
12965
12966 for (s = 0; s < snum; s++) {
12967 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
12968 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
12969 wpa_ctrl[s].ssid_index = s;
12970 ctrl_enable(&wpa_ctrl[s]);
12971 }
12972
12973 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
12974 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
12975
12976 initialized = 1;
12977 printf("WPA_CTRL: initialized\n");
12978
12979 return RETURN_OK;
12980}
12981
12982void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
12983{
12984 clients_connect_cb = callback_proc;
12985 if (!initialized)
12986 init_wpa();
12987}
12988
12989void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
12990{
12991 clients_disconnect_cb = callback_proc;
12992 if (!initialized)
12993 init_wpa();
12994}
12995
12996INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
12997{
12998 // TODO Implement me!
12999 return RETURN_ERR;
13000}
13001
13002INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
13003{
13004 // TODO Implement me!
13005 return RETURN_ERR;
13006}
13007
13008INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
13009{
13010 int i;
developerd1824452023-05-18 12:30:04 +080013011 int phyId = -1;
13012 char cmd[256] = {0};
13013 char channel_numbers_buf[256] = {0};
13014 char dfs_state_buf[256] = {0};
13015 char line[256] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013016 const char *ptr;
developerd1824452023-05-18 12:30:04 +080013017 BOOL dfs_enable = false;
developer72fb0bb2023-01-11 09:46:29 +080013018
developerd1824452023-05-18 12:30:04 +080013019 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080013020
developerd1824452023-05-18 12:30:04 +080013021 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
13022 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013023
developerd1824452023-05-18 12:30:04 +080013024 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\\|");
developer72fb0bb2023-01-11 09:46:29 +080013025
developerd1824452023-05-18 12:30:04 +080013026 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
13027 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13028 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013029 }
13030
developerd1824452023-05-18 12:30:04 +080013031 ptr = channel_numbers_buf;
13032 i = 0;
developerdaf24792023-06-06 11:40:04 +080013033 while ((ptr = get_line_from_str_buf(ptr, line))) {
developerd1824452023-05-18 12:30:04 +080013034 if (i >= outputMapSize) {
13035 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
13036 return RETURN_ERR;
13037 }
13038 sscanf(line, "%d", &outputMap[i].ch_number);
13039
13040 memset(cmd, 0, sizeof(cmd));
13041 // Below command should fetch string for DFS state (usable, available or unavailable)
13042 // Example line: "DFS state: usable (for 78930 sec)"
13043 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) {
13044 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
developer72fb0bb2023-01-11 09:46:29 +080013045 return RETURN_ERR;
13046 }
13047
developerd1824452023-05-18 12:30:04 +080013048 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
13049 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
developer72fb0bb2023-01-11 09:46:29 +080013050 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13051 return RETURN_ERR;
13052 }
13053
developerd1824452023-05-18 12:30:04 +080013054 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080013055
developerd1824452023-05-18 12:30:04 +080013056 if (!strcmp(dfs_state_buf, "usable")) {
13057 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
13058 } else if (!strcmp(dfs_state_buf, "available")) {
13059 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
13060 } else if (!strcmp(dfs_state_buf, "unavailable")) {
13061 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
13062 } else {
13063 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
developer72fb0bb2023-01-11 09:46:29 +080013064 }
developerd1824452023-05-18 12:30:04 +080013065 i++;
developer59fda4f2023-05-16 15:47:38 +080013066 }
developer40ba1762023-05-13 11:03:49 +080013067
developerd1824452023-05-18 12:30:04 +080013068 return RETURN_OK;
13069
developer72fb0bb2023-01-11 09:46:29 +080013070 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
13071 return RETURN_ERR;
13072}
13073
13074INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
13075{
13076 // TODO Implement me!
13077 return RETURN_ERR;
13078}
13079
13080INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
13081{
13082 return RETURN_OK;
13083}
13084
13085INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
13086{
13087 // TODO Implement me!
13088 return RETURN_ERR;
13089}
13090
13091INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
13092{
13093 // TODO API refrence Implementaion is present on RPI hal
13094 return RETURN_ERR;
13095}
13096
13097INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
13098{
developera1255e42023-05-13 17:45:02 +080013099/*
developer72fb0bb2023-01-11 09:46:29 +080013100 char interface_name[16] = {0};
13101 char cmd[128]={'\0'};
13102 char buf[128]={'\0'};
13103 char *support;
13104 int maximum_tx = 0, current_tx = 0;
developera1255e42023-05-13 17:45:02 +080013105*/ ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080013106
13107 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13108 if(txpwr_pcntg == NULL)
developerdaf24792023-06-06 11:40:04 +080013109 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013110
developera1255e42023-05-13 17:45:02 +080013111 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
13112 *txpwr_pcntg = pwr_percentage;
13113/* if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +080013114 return RETURN_ERR;
13115
13116 // Get the maximum tx power of the device
13117 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
13118 _syscmd(cmd, buf, sizeof(buf));
13119 maximum_tx = strtol(buf, NULL, 10);
13120
13121 // Get the current tx power
13122 memset(cmd, 0, sizeof(cmd));
13123 memset(buf, 0, sizeof(buf));
13124 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
13125 _syscmd(cmd, buf, sizeof(buf));
13126 current_tx = strtol(buf, NULL, 10);
13127
13128 // Get the power supported list and find the current power percentage in supported list
13129 memset(buf, 0, sizeof(buf));
13130 wifi_getRadioTransmitPowerSupported(apIndex, buf);
13131 support = strtok(buf, ",");
13132 while(true)
13133 {
13134 if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal.
13135 *txpwr_pcntg = 100;
13136 wifi_dbg_printf("current power is not in supported list\n");
13137 return RETURN_OK;
13138 }
13139 int tmp = maximum_tx*strtol(support, NULL, 10)/100;
13140 if (tmp == current_tx) {
13141 *txpwr_pcntg = strtol(support, NULL, 10);
13142 break;
13143 }
13144 support = strtok(NULL, ",");
13145 }
developera1255e42023-05-13 17:45:02 +080013146*/
developer72fb0bb2023-01-11 09:46:29 +080013147 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13148 return RETURN_OK;
13149}
13150
13151INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
13152{
13153 // TODO precac feature.
developerd1824452023-05-18 12:30:04 +080013154 struct params params[2] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013155 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080013156 BOOL dfs_enable = false;
13157 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080013158
13159 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerd1824452023-05-18 12:30:04 +080013160 band = wifi_index_to_band(radioIndex);
13161 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080013162
developerd1824452023-05-18 12:30:04 +080013163 if (dfs_enable == false) {
13164 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
13165 return RETURN_ERR;
13166 }
13167 params[0].name = "DfsZeroWaitDefault";
13168 params[0].value = enable?"1":"0";
13169 params[1].name = "DfsDedicatedZeroWait";
13170 params[1].value = enable?"1":"0";
13171 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13172 wifi_datfileWrite(config_file, params, 2);
developerc0772e62023-05-18 15:10:48 +080013173 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013174 /* TODO precac feature */
13175
13176 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13177 return RETURN_OK;
13178}
13179
13180INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
13181{
13182 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080013183 char buf1[32] = {0};
13184 char buf2[32] = {0};
13185 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080013186
13187 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13188 if (NULL == enable || NULL == precac)
13189 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +080013190 band = wifi_index_to_band(radioIndex);
13191 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13192 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
13193 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
13194 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
developer72fb0bb2023-01-11 09:46:29 +080013195 *enable = true;
13196 else
13197 *enable = false;
13198
13199 /* TODO precac feature */
13200
13201 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13202 return RETURN_OK;
13203}
13204
13205INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
13206{
13207 *supported = TRUE;
13208 return RETURN_OK;
13209}
13210
13211INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
13212{
developer863a4a62023-06-06 16:55:59 +080013213 CHAR dat_file[64] = {0};
developera1255e42023-05-13 17:45:02 +080013214 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080013215 char ofdmabuf[32] = {'\0'};
13216 char mimobuf[32] = {'\0'};
13217 char new_ofdmabuf[32] = {'\0'};
13218 char new_mimobuf[32] = {'\0'};
13219 struct params params[2];
13220 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13221 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13222 UCHAR bss_cnt = 0;
13223 UCHAR val_cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013224
developera1255e42023-05-13 17:45:02 +080013225 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13226 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
13227 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
13228 printf("%s:mu_type input Error", __func__);
13229 return RETURN_ERR;
13230 }
13231 band = wifi_index_to_band(radio_index);
13232 if (band == band_invalid) {
13233 printf("%s:Band Error\n", __func__);
13234 return RETURN_ERR;
13235 }
13236 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13237 /*get current value in dat file*/
13238 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13239 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
13240 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13241 get_bssnum_byindex(radio_index, &bss_cnt);
13242 val_cnt = 2*bss_cnt - 1;
13243 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
13244 if ((val_cnt >= sizeof(new_ofdmabuf))
13245 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080013246 printf("%s:bss cnt Error", __func__);
developera1255e42023-05-13 17:45:02 +080013247 return RETURN_ERR;
13248 }
13249 /*translate set value*/
13250 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
13251 strncpy(new_ofdmabuf, str_zero, val_cnt);
13252 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013253 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080013254 strncpy(new_ofdmabuf, str_one, val_cnt);
13255 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013256 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080013257 strncpy(new_ofdmabuf, str_zero, val_cnt);
13258 strncpy(new_mimobuf, str_one, val_cnt);
13259 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
13260 strncpy(new_ofdmabuf, str_one, val_cnt);
13261 strncpy(new_mimobuf, str_one, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013262 }
developera1255e42023-05-13 17:45:02 +080013263 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13264 /*same value, not operation*/
13265 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13266 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13267 printf("%s:Reduntant value\n", __func__);
13268 return RETURN_OK;
13269 }
13270 /*modify dat file to new file*/
13271 params[0].name="MuOfdmaDlEnable";
13272 params[0].value=new_ofdmabuf;
13273 params[1].name="MuMimoDlEnable";
13274 params[1].value=new_mimobuf;
13275 wifi_datfileWrite(dat_file, params, 2);
13276 /*hostapd control restarp ap to take effect on these new value*/
13277 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013278 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13279 return RETURN_OK;
13280}
13281
13282INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
13283{
developer5a333cf2023-06-06 18:18:50 +080013284 CHAR dat_file[64] = {0};
developera1255e42023-05-13 17:45:02 +080013285 wifi_band band = band_invalid;
13286 char ofdmabuf[32] = {'\0'};
13287 char mimobuf[32] = {'\0'};
13288 char *token = NULL;
13289 UCHAR ofdma = 0;
13290 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013291
13292 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13293
13294 if (mu_type == NULL)
13295 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013296 band = wifi_index_to_band(radio_index);
13297 if (band == band_invalid) {
13298 printf("%s:Band Error\n", __func__);
13299 return RETURN_ERR;
13300 }
13301 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13302 /*get current value in dat file*/
13303 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13304 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013305
developera1255e42023-05-13 17:45:02 +080013306 token = strtok(ofdmabuf, ";");
13307 ofdma = strtol(token, NULL, 10);
13308 token = strtok(mimobuf, ";");
13309 mimo = strtol(token, NULL, 10);
13310 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
13311 if ((ofdma == 1) && (mimo == 1))
13312 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
13313 else if ((ofdma == 0) && (mimo == 1))
13314 *mu_type = WIFI_DL_MU_TYPE_MIMO;
13315 else if ((ofdma == 1) && (mimo == 0))
13316 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
13317 else
13318 *mu_type = WIFI_DL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013319 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13320 return RETURN_OK;
13321}
13322
13323INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
13324{
13325 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developer863a4a62023-06-06 16:55:59 +080013326 CHAR dat_file[64] = {0};
developera1255e42023-05-13 17:45:02 +080013327 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080013328 char ofdmabuf[32] = {'\0'};
13329 char mimobuf[32] = {'\0'};
13330 char new_ofdmabuf[32] = {'\0'};
13331 char new_mimobuf[32] = {'\0'};
13332 struct params params[2];
13333 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13334 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13335 UCHAR bss_cnt = 0;
13336 UCHAR val_cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013337
developera1255e42023-05-13 17:45:02 +080013338 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13339 band = wifi_index_to_band(radio_index);
13340 if (band == band_invalid) {
13341 printf("%s:Band Error\n", __func__);
13342 return RETURN_ERR;
13343 }
13344 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
13345 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
13346 printf("%s:mu_type input Error\n", __func__);
13347 return RETURN_ERR;
13348 }
13349 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13350 /*get current value in dat file*/
13351 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13352 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
13353 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13354 get_bssnum_byindex(radio_index, &bss_cnt);
13355 val_cnt = 2*bss_cnt - 1;
13356 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
13357 if ((val_cnt >= sizeof(new_ofdmabuf))
13358 || (val_cnt >= sizeof(new_mimobuf))) {
developer49c83812023-06-06 14:23:53 +080013359 printf("%s:bss cnt Error\n", __func__);
developera1255e42023-05-13 17:45:02 +080013360 return RETURN_ERR;
13361 }
13362 /*translate set value*/
13363 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
13364 strncpy(new_ofdmabuf, str_zero, val_cnt);
13365 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013366 }
developera1255e42023-05-13 17:45:02 +080013367 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
13368 strncpy(new_ofdmabuf, str_one, val_cnt);
13369 strncpy(new_mimobuf, str_zero, val_cnt);
13370 }
13371 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13372 /*same value, not operation*/
13373 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13374 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13375 printf("%s:Reduntant value\n", __func__);
13376 return RETURN_OK;
13377 }
13378 /*modify dat file to new file*/
13379 params[0].name="MuOfdmaUlEnable";
13380 params[0].value=new_ofdmabuf;
13381 params[1].name="MuMimoUlEnable";
13382 params[1].value=new_mimobuf;
13383 wifi_datfileWrite(dat_file, params, 2);
13384 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013385 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13386 return RETURN_OK;
13387}
13388
13389INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
13390{
developer863a4a62023-06-06 16:55:59 +080013391 CHAR dat_file[64] = {0};
developera1255e42023-05-13 17:45:02 +080013392 wifi_band band = band_invalid;
13393 char ofdmabuf[32] = {'\0'};
13394 char mimobuf[32] = {'\0'};
13395 char *token = NULL;
13396 UCHAR ofdma = 0;
13397 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013398
13399 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13400
13401 if (mu_type == NULL)
13402 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013403 band = wifi_index_to_band(radio_index);
13404 if (band == band_invalid) {
13405 printf("%s:Band Error", __func__);
13406 return RETURN_ERR;
13407 }
13408 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13409 /*get current value in dat file*/
13410 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13411 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013412
developera1255e42023-05-13 17:45:02 +080013413 token = strtok(ofdmabuf, ";");
13414 ofdma = strtol(token, NULL, 10);
13415 token = strtok(mimobuf, ";");
13416 mimo = strtol(token, NULL, 10);
13417 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
13418 if ((ofdma == 1) && (mimo == 0))
13419 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
13420 else
13421 *mu_type = WIFI_UL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013422 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13423 return RETURN_OK;
13424}
13425
13426
13427INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
13428{
13429 char cmd[128] = {0};
13430 char buf[256] = {0};
13431 char config_file[64] = {0};
13432 char GI[8] = {0};
developer863a4a62023-06-06 16:55:59 +080013433 UINT mode_map = 0;
developer72fb0bb2023-01-11 09:46:29 +080013434 FILE *f = NULL;
13435 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080013436 char dat_file[64] = {'\0'};
13437 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080013438
13439 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13440
13441 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
13442 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
13443 return RETURN_ERR;
13444 }
developera1255e42023-05-13 17:45:02 +080013445 /*sanity check*/
13446 if (((guard_interval == wifi_guard_interval_1600)
13447 || (guard_interval == wifi_guard_interval_3200))
developerdaf24792023-06-06 11:40:04 +080013448 && ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
developera1255e42023-05-13 17:45:02 +080013449 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
13450 return RETURN_ERR;
13451 }
developer72fb0bb2023-01-11 09:46:29 +080013452 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
13453 band = wifi_index_to_band(radio_index);
13454
13455 // Hostapd are not supported HE mode GI 1600, 3200 ns.
13456 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
13457 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
13458 _syscmd(cmd, buf, sizeof(buf));
13459 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
13460 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
13461 if (strstr(buf, "[SHORT-GI-") == NULL) {
13462 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
13463 _syscmd(cmd, buf, sizeof(buf));
13464 }
13465 if (band == band_5) {
13466 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
13467 if (strstr(buf, "[SHORT-GI-") == NULL) {
13468 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
13469 _syscmd(cmd, buf, sizeof(buf));
13470 }
13471 }
13472 }
developera1255e42023-05-13 17:45:02 +080013473 /*wifi_reloadAp(radio_index);
13474 caller "wifi_setRadioOperatingParameters" have done this step.
13475 */
13476 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13477 if (guard_interval == wifi_guard_interval_400) {
13478 params[0].name = "HT_GI";
13479 params[0].value = "1";
13480 params[1].name = "VHT_SGI";
13481 params[1].value = "1";
13482 wifi_datfileWrite(dat_file, params, 2);
developer72fb0bb2023-01-11 09:46:29 +080013483 strcpy(GI, "0.4");
developera1255e42023-05-13 17:45:02 +080013484 } else {
13485 params[0].name = "HT_GI";
13486 params[0].value = "0";
13487 params[1].name = "VHT_SGI";
13488 params[1].value = "0";
13489 /*should enable FIXED_HE_GI_SUPPORT in driver*/
13490 params[2].name = "FgiFltf";
13491 if (guard_interval == wifi_guard_interval_800) {
13492 params[2].value = "800";
13493 strcpy(GI, "0.8");
13494 } else if (guard_interval == wifi_guard_interval_1600) {
13495 params[2].value = "1600";
13496 strcpy(GI, "1.6");
13497 } else if (guard_interval == wifi_guard_interval_3200) {
13498 params[2].value = "3200";
13499 strcpy(GI, "3.2");
13500 } else if (guard_interval == wifi_guard_interval_auto) {
13501 params[2].value = "0";
13502 strcpy(GI, "auto");
13503 }
13504 wifi_datfileWrite(dat_file, params, 3);
13505 }
developer72fb0bb2023-01-11 09:46:29 +080013506 // Record GI for get GI function
13507 snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
13508 f = fopen(buf, "w");
13509 if (f == NULL)
13510 return RETURN_ERR;
13511 fprintf(f, "%s", GI);
13512 fclose(f);
13513 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13514 return RETURN_OK;
13515}
13516
13517INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
13518{
13519 char buf[32] = {0};
13520 char cmd[64] = {0};
13521
13522 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13523
13524 if (guard_interval == NULL)
13525 return RETURN_ERR;
13526
developera1255e42023-05-13 17:45:02 +080013527 snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013528 _syscmd(cmd, buf, sizeof(buf));
13529
13530 if (strncmp(buf, "0.4", 3) == 0)
13531 *guard_interval = wifi_guard_interval_400;
13532 else if (strncmp(buf, "0.8", 3) == 0)
13533 *guard_interval = wifi_guard_interval_800;
13534 else if (strncmp(buf, "1.6", 3) == 0)
13535 *guard_interval = wifi_guard_interval_1600;
13536 else if (strncmp(buf, "3.2", 3) == 0)
13537 *guard_interval = wifi_guard_interval_3200;
13538 else
13539 *guard_interval = wifi_guard_interval_auto;
13540
13541 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13542 return RETURN_OK;
13543}
13544
13545INT wifi_setBSSColor(INT radio_index, UCHAR color)
13546{
13547 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13548 struct params params = {0};
13549 char config_file[128] = {0};
13550 char bss_color[4] ={0};
13551
developera1255e42023-05-13 17:45:02 +080013552 if (color < 1 || color > 63) {
13553 wifi_dbg_printf("color value is err:%d.\n", color);
13554 return RETURN_ERR;
13555 }
developer72fb0bb2023-01-11 09:46:29 +080013556 params.name = "he_bss_color";
13557 snprintf(bss_color, sizeof(bss_color), "%hhu", color);
13558 params.value = bss_color;
13559 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13560 wifi_hostapdWrite(config_file, &params, 1);
developera1255e42023-05-13 17:45:02 +080013561 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
13562 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080013563
developer72fb0bb2023-01-11 09:46:29 +080013564 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13565 return RETURN_OK;
13566}
13567
13568INT wifi_getBSSColor(INT radio_index, UCHAR *color)
13569{
13570 char config_file[128] = {0};
13571 char buf[64] = {0};
13572 char temp_output[128] = {'\0'};
13573
13574 wifi_dbg_printf("\nFunc=%s\n", __func__);
13575 if (NULL == color)
13576 return RETURN_ERR;
13577
13578 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13579 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
13580
13581 if(strlen(buf) > 0) {
13582 snprintf(temp_output, sizeof(temp_output), "%s", buf);
13583 } else {
13584 snprintf(temp_output, sizeof(temp_output), "1"); // default value
13585 }
13586
13587 *color = (UCHAR)strtoul(temp_output, NULL, 10);
13588 wifi_dbg_printf("\noutput_string=%s\n", color);
13589
13590 return RETURN_OK;
13591}
13592
13593/* multi-psk support */
13594INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
13595{
13596 char cmd[256];
13597 char interface_name[16] = {0};
13598
13599 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13600 return RETURN_ERR;
13601
13602 sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
13603 interface_name,
13604 mac[0],
13605 mac[1],
13606 mac[2],
13607 mac[3],
13608 mac[4],
13609 mac[5]
13610 );
13611 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
13612 _syscmd(cmd, key->wifi_keyId, 64);
13613
13614
13615 return RETURN_OK;
13616}
13617
13618INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13619{
13620 char interface_name[16] = {0};
13621 FILE *fd = NULL;
13622 char fname[100];
13623 char cmd[128] = {0};
13624 char out[64] = {0};
13625 wifi_key_multi_psk_t * key = NULL;
13626 if(keysNumber < 0)
13627 return RETURN_ERR;
13628
13629 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13630 fd = fopen(fname, "w");
13631 if (!fd) {
13632 return RETURN_ERR;
13633 }
13634 key= (wifi_key_multi_psk_t *) keys;
13635 for(int i=0; i<keysNumber; ++i, key++) {
13636 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
13637 }
13638 fclose(fd);
13639
13640 //reload file
13641 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13642 return RETURN_ERR;
13643 sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
13644 _syscmd(cmd, out, 64);
13645 return RETURN_OK;
13646}
13647
13648INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13649{
13650 FILE *fd = NULL;
13651 char fname[100];
13652 char * line = NULL;
13653 char * pos = NULL;
13654 size_t len = 0;
13655 ssize_t read = 0;
13656 INT ret = RETURN_OK;
13657 wifi_key_multi_psk_t *keys_it = NULL;
13658
13659 if (keysNumber < 1) {
13660 return RETURN_ERR;
13661 }
13662
13663 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13664 fd = fopen(fname, "r");
13665 if (!fd) {
13666 return RETURN_ERR;
13667 }
13668
13669 if (keys == NULL) {
13670 ret = RETURN_ERR;
13671 goto close;
13672 }
13673
13674 keys_it = keys;
13675 while ((read = getline(&line, &len, fd)) != -1) {
13676 //Strip trailing new line if present
13677 if (read > 0 && line[read-1] == '\n') {
13678 line[read-1] = '\0';
13679 }
13680
13681 if(strcmp(line,"keyid=")) {
developerdaf24792023-06-06 11:40:04 +080013682 sscanf(line, "keyid=%s", keys_it->wifi_keyId);
developer72fb0bb2023-01-11 09:46:29 +080013683 if (!(pos = index(line, ' '))) {
13684 ret = RETURN_ERR;
13685 goto close;
13686 }
13687 pos++;
13688 //Here should be 00:00:00:00:00:00
13689 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
13690 printf("Not supported MAC: %s\n", pos);
13691 }
13692 if (!(pos = index(pos, ' '))) {
13693 ret = RETURN_ERR;
13694 goto close;
13695 }
13696 pos++;
13697
13698 //The rest is PSK
13699 snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
13700 keys_it++;
13701
13702 if(--keysNumber <= 0)
13703 break;
13704 }
13705 }
13706
13707close:
13708 free(line);
13709 fclose(fd);
13710 return ret;
13711}
13712/* end of multi-psk support */
13713
13714INT wifi_setNeighborReports(UINT apIndex,
13715 UINT numNeighborReports,
13716 wifi_NeighborReport_t *neighborReports)
13717{
13718 char cmd[256] = { 0 };
13719 char hex_bssid[13] = { 0 };
13720 char bssid[18] = { 0 };
developerb149d9d2023-06-06 16:14:22 +080013721 char nr[100] = { 0 };
13722 char ssid[32];
13723 char hex_ssid[32];
developer72fb0bb2023-01-11 09:46:29 +080013724 char interface_name[16] = {0};
13725 INT ret;
13726
13727 /*rmeove all neighbors*/
13728 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
13729 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13730 return RETURN_ERR;
13731 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);
13732 system(cmd);
13733
13734 for(unsigned int i = 0; i < numNeighborReports; i++)
13735 {
13736 memset(ssid, 0, sizeof(ssid));
13737 ret = wifi_getSSIDName(apIndex, ssid);
13738 if (ret != RETURN_OK)
13739 return RETURN_ERR;
13740
13741 memset(hex_ssid, 0, sizeof(hex_ssid));
13742 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
13743 sprintf(hex_ssid + k,"%02x", ssid[j]);
13744
13745 snprintf(hex_bssid, sizeof(hex_bssid),
13746 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
13747 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
13748 snprintf(bssid, sizeof(bssid),
13749 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
13750 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
13751
13752 snprintf(nr, sizeof(nr),
13753 "%s" // bssid
13754 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
13755 "%02hhx" // operclass
13756 "%02hhx" // channel
13757 "%02hhx", // phy_mode
13758 hex_bssid,
13759 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
13760 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
13761 neighborReports[i].opClass,
13762 neighborReports[i].channel,
13763 neighborReports[i].phyTable);
13764
13765 snprintf(cmd, sizeof(cmd),
13766 "hostapd_cli set_neighbor "
13767 "%s " // bssid
13768 "ssid=%s " // ssid
13769 "nr=%s " // nr
13770 "-i %s",
13771 bssid,hex_ssid,nr, interface_name);
13772
13773 if (WEXITSTATUS(system(cmd)) != 0)
13774 {
13775 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
13776 }
13777 }
13778
13779 return RETURN_OK;
13780}
13781
13782INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
13783{
13784 return RETURN_OK;
13785}
13786
13787#ifdef _WIFI_HAL_TEST_
13788int main(int argc,char **argv)
13789{
13790 int index;
13791 INT ret=0;
13792 char buf[1024]="";
13793
13794 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13795 if(argc<3)
13796 {
13797 if(argc==2)
13798 {
13799 if(!strcmp(argv[1], "init"))
13800 return wifi_init();
13801 if(!strcmp(argv[1], "reset"))
13802 return wifi_reset();
13803 if(!strcmp(argv[1], "wifi_getHalVersion"))
13804 {
13805 char buffer[64];
13806 if(wifi_getHalVersion(buffer)==RETURN_OK)
13807 printf("Version: %s\n", buffer);
13808 else
13809 printf("Error in wifi_getHalVersion\n");
13810 return RETURN_OK;
13811 }
13812 }
13813 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
13814 exit(-1);
13815 }
13816
13817 index = atoi(argv[2]);
13818 if(strstr(argv[1], "wifi_getApName")!=NULL)
13819 {
13820 wifi_getApName(index,buf);
13821 printf("Ap name is %s \n",buf);
13822 return 0;
13823 }
developerfead3972023-05-25 20:15:02 +080013824 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
13825 {
13826 UINT pureMode = atoi(argv[3]);
13827
13828 wifi_setRadioMode(index, NULL, pureMode);
13829 printf("Ap SET Radio mode 0x%x\n", pureMode);
13830 return 0;
13831 }
developere0ff7232023-06-08 16:33:14 +080013832 if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
13833 unsigned char enable = atoi(argv[3]);
13834 if (enable)
13835 wifi_setRadioAutoBlockAckEnable(index, TRUE);
13836 else
13837 wifi_setRadioAutoBlockAckEnable(index, FALSE);
13838 printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
13839 }
developerfead3972023-05-25 20:15:02 +080013840 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
13841 {
13842 ULONG TransmitPower = atoi(argv[3]);
13843
13844 wifi_setRadioTransmitPower(index, TransmitPower);
13845 printf("Ap SET TransmitPower %lu\n", TransmitPower);
13846 return 0;
13847 }
13848 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
13849 {
13850 INT TransmitPower = atoi(argv[3]);
13851
13852 wifi_setApManagementFramePowerControl(index, TransmitPower);
13853 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
13854 return 0;
13855 }
13856 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
13857 {
13858 CHAR *bandwith = argv[3];
13859
13860 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
13861 printf("Ap SET bw %s\n", bandwith);
13862 return 0;
13863 }
13864 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
13865 {
13866 wifi_factoryResetRadio(index);
13867 printf("wifi_factoryResetRadio ok!\n");
13868 return 0;
13869 }
13870 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
13871 {
13872 ULONG rst_cnt;
13873 wifi_getRadioResetCount(index, &rst_cnt);
13874 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
13875 return 0;
13876 }
developer2edaf012023-05-24 14:24:53 +080013877 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080013878 if(argc <= 3 )
13879 {
developer2edaf012023-05-24 14:24:53 +080013880 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
developer49b17232023-05-19 16:35:19 +080013881 exit(-1);
13882 }
13883 wifi_addApAclDevice(index, argv[3]);
13884 return 0;
13885 }
developer2edaf012023-05-24 14:24:53 +080013886 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
13887 wifi_getApAclDevices(index, buf, 1024);
13888 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080013889 return 0;
13890 }
developer2edaf012023-05-24 14:24:53 +080013891 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
13892 if(argc <= 3 )
13893 {
13894 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13895 exit(-1);
13896 }
13897 wifi_delApAclDevice(index, argv[3]);
13898 return 0;
13899 }
13900 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
13901 wifi_delApAclDevices(index);
13902 return 0;
13903 }
13904 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
developer863a4a62023-06-06 16:55:59 +080013905 UINT acl_num = 0;
developer2edaf012023-05-24 14:24:53 +080013906 wifi_getApAclDeviceNum(index, &acl_num);
13907 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
13908 return 0;
13909 }
13910 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
13911 wifi_getApDenyAclDevices(index, buf, 1024);
13912 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
13913 return 0;
13914 }
13915 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
13916 int filter_mode = 0;
13917 if(argc <= 3 )
13918 {
13919 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13920 exit(-1);
13921 }
13922 filter_mode = atoi(argv[3]);
13923 wifi_setApMacAddressControlMode(index,filter_mode);
13924 return 0;
13925 }
developer5cd4c862023-05-26 09:34:42 +080013926 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
13927 BOOL output_bool = 0;
13928 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
13929 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
13930 return 0;
13931 }
13932 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
13933 BOOL output_bool = 0;
13934 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
13935 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
13936 return 0;
13937 }
13938
13939 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
13940 int filter_mode = 0;
13941 wifi_getApMacAddressControlMode(index, &filter_mode);
13942 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
13943 return 0;
13944 }
13945 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
13946 int enable = 0;
13947 if(argc <= 3 )
13948 {
13949 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13950 exit(-1);
13951 }
13952 enable = (BOOL)atoi(argv[3]);
13953 wifi_setRadioIGMPSnoopingEnable(index, enable);
13954 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
13955 return 0;
13956 }
13957
13958 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
13959 BOOL out_status = 0;
13960 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
13961 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
13962 return 0;
13963 }
developer121a8e72023-05-22 09:19:39 +080013964
developer95c045d2023-05-24 19:26:28 +080013965 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
13966 int enable = 0;
13967 if(argc <= 3)
13968 {
13969 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
13970 exit(-1);
13971 }
13972 enable = atoi(argv[3]);
13973 wifi_setApWmmEnable(index,enable);
13974 return 0;
13975 }
developer56fbedb2023-05-30 16:47:05 +080013976 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
13977 wifi_down();
13978 return 0;
13979 }
developer95c045d2023-05-24 19:26:28 +080013980
developer56fbedb2023-05-30 16:47:05 +080013981 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
13982 BOOL enable = 0;
13983
13984 wifi_getRadioStatus(index, &enable);
13985 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
13986 return 0;
13987 }
developer333c1eb2023-05-31 14:59:39 +080013988
developer95c045d2023-05-24 19:26:28 +080013989 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
13990 BOOL enable = 0;
13991
13992 wifi_getApWMMCapability(index, &enable);
13993 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
13994 return 0;
13995 }
13996
13997 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
13998 BOOL enable = 0;
13999
14000 wifi_getApWmmEnable(index, &enable);
14001 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
14002 return 0;
14003 }
14004
developer2edaf012023-05-24 14:24:53 +080014005 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14006 int filter_mode = 0;
14007 wifi_getApMacAddressControlMode(index, &filter_mode);
14008 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14009 return 0;
14010 }
developer0f10c772023-05-16 21:43:39 +080014011 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
14012 {
developer863a4a62023-06-06 16:55:59 +080014013 UINT mode = 0;
developer0f10c772023-05-16 21:43:39 +080014014
14015 wifi_getRadioMode(index, buf, &mode);
14016 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
14017 return 0;
14018 }
developer72fb0bb2023-01-11 09:46:29 +080014019 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
14020 {
14021 BOOL b = FALSE;
14022 BOOL *output_bool = &b;
14023 wifi_getRadioAutoChannelEnable(index,output_bool);
14024 printf("Channel enabled = %d \n",b);
14025 return 0;
14026 }
14027 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
14028 {
14029 wifi_getApWpaEncryptionMode(index,buf);
14030 printf("encryption enabled = %s\n",buf);
14031 return 0;
14032 }
14033 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
14034 {
14035 BOOL b = FALSE;
14036 BOOL *output_bool = &b;
14037 wifi_getApSsidAdvertisementEnable(index,output_bool);
14038 printf("advertisment enabled = %d\n",b);
14039 return 0;
14040 }
14041 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
14042 {
14043 if(argc <= 3 )
14044 {
14045 printf("Insufficient arguments \n");
14046 exit(-1);
14047 }
14048
14049 char sta[20] = {'\0'};
14050 ULLONG handle= 0;
14051 strcpy(sta,argv[3]);
14052 mac_address_t st;
14053 mac_addr_aton(st,sta);
14054
14055 wifi_associated_dev_tid_stats_t tid_stats;
14056 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
14057 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
14058 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);
14059 }
14060
14061 if(strstr(argv[1], "getApEnable")!=NULL) {
14062 BOOL enable;
14063 ret=wifi_getApEnable(index, &enable);
14064 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14065 }
14066 else if(strstr(argv[1], "setApEnable")!=NULL) {
14067 BOOL enable = atoi(argv[3]);
14068 ret=wifi_setApEnable(index, enable);
14069 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14070 }
14071 else if(strstr(argv[1], "getApStatus")!=NULL) {
developer69b61b02023-03-07 17:17:44 +080014072 char status[64];
developer72fb0bb2023-01-11 09:46:29 +080014073 ret=wifi_getApStatus(index, status);
14074 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
14075 }
14076 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
14077 {
14078 wifi_getSSIDNameStatus(index,buf);
14079 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
14080 return 0;
developer2202b332023-05-24 16:23:22 +080014081 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
14082 wifi_resetApVlanCfg(index);
14083 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
14084 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014085 }
14086 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
14087 wifi_ssidTrafficStats2_t stats={0};
14088 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
14089 printf("%s %d: returns %d\n", argv[1], index, ret);
14090 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
14091 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
14092 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
14093 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
14094 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
14095 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
14096 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
14097 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
14098 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
14099 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
14100 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
14101 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
14102 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
14103 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
14104 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
14105 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
14106 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
14107 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
14108 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
14109 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
14110 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
14111 }
14112 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
14113 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
14114 UINT array_size=0;
14115 UINT i=0;
14116 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
14117 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080014118 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080014119 printf(" neighbor %d:\n", i);
14120 printf(" ap_SSID =%s\n", pt->ap_SSID);
14121 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
14122 printf(" ap_Mode =%s\n", pt->ap_Mode);
14123 printf(" ap_Channel =%d\n", pt->ap_Channel);
14124 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
14125 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14126 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
14127 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
14128 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
14129 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
14130 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14131 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
14132 printf(" ap_Noise =%d\n", pt->ap_Noise);
14133 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
14134 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
14135 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
developer69b61b02023-03-07 17:17:44 +080014136 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
developer72fb0bb2023-01-11 09:46:29 +080014137 }
14138 if(neighbor_ap_array)
14139 free(neighbor_ap_array); //make sure to free the list
14140 }
14141 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
14142 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
14143 UINT array_size=0;
14144 UINT i=0;
14145 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
14146 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080014147 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080014148 printf(" associated_dev %d:\n", i);
14149 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
14150 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
14151 printf(" cli_SNR =%d\n", pt->cli_SNR);
14152 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
14153 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
14154 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
14155 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
14156 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
14157 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
14158 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
14159 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
14160 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
14161 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
14162 }
14163 if(associated_dev_array)
14164 free(associated_dev_array); //make sure to free the list
14165 }
14166
14167 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
14168 {
14169#define MAX_ARRAY_SIZE 64
14170 int i, array_size;
14171 char *p, *ch_str;
14172 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
14173
14174 if(argc != 5)
14175 {
14176 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
14177 exit(-1);
14178 }
14179 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
14180
14181 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
14182 {
14183 strtok_r(ch_str, ",", &p);
14184 input_output_channelStats_array[i].ch_number = atoi(ch_str);
14185 }
14186 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
14187 if(!array_size)
14188 array_size=1;//Need to print current channel statistics
14189 for(i=0; i<array_size; i++)
14190 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
14191 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
14192 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
14193 input_output_channelStats_array[i].ch_number,\
14194 input_output_channelStats_array[i].ch_noise,\
14195 input_output_channelStats_array[i].ch_utilization_busy_rx,\
14196 input_output_channelStats_array[i].ch_utilization_busy_tx,\
14197 input_output_channelStats_array[i].ch_utilization_busy,\
14198 input_output_channelStats_array[i].ch_utilization_busy_ext,\
14199 input_output_channelStats_array[i].ch_utilization_total);
14200 }
14201
14202 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
14203 {
14204 if(argc <= 3 )
14205 {
14206 printf("Insufficient arguments \n");
14207 exit(-1);
14208 }
14209 char mac_addr[20] = {'\0'};
14210 wifi_device_t output_struct;
14211 int dev_index = atoi(argv[3]);
14212
14213 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
14214 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
14215 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);
14216 }
14217
14218 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
14219 {
14220 if (argc <= 3)
14221 {
14222 printf("Insufficient arguments\n");
14223 exit(-1);
14224 }
14225 char args[256];
14226 wifi_NeighborReport_t *neighborReports;
14227
14228 neighborReports = calloc(argc - 2, sizeof(neighborReports));
14229 if (!neighborReports)
14230 {
14231 printf("Failed to allocate memory");
14232 exit(-1);
14233 }
14234
14235 for (int i = 3; i < argc; ++i)
14236 {
14237 char *val;
14238 int j = 0;
14239 memset(args, 0, sizeof(args));
14240 strncpy(args, argv[i], sizeof(args));
14241 val = strtok(args, ";");
14242 while (val != NULL)
14243 {
14244 if (j == 0)
14245 {
14246 mac_addr_aton(neighborReports[i - 3].bssid, val);
14247 } else if (j == 1)
14248 {
14249 neighborReports[i - 3].info = strtol(val, NULL, 16);
14250 } else if (j == 2)
14251 {
14252 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
14253 } else if (j == 3)
14254 {
14255 neighborReports[i - 3].channel = strtol(val, NULL, 16);
14256 } else if (j == 4)
14257 {
14258 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
14259 } else {
14260 printf("Insufficient arguments]n\n");
14261 exit(-1);
14262 }
14263 val = strtok(NULL, ";");
14264 j++;
14265 }
14266 }
14267
14268 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
14269 if (ret != RETURN_OK)
14270 {
14271 printf("wifi_setNeighborReports ret = %d", ret);
14272 exit(-1);
14273 }
14274 }
14275 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
14276 {
14277 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
14278 printf("%s.\n", buf);
14279 else
14280 printf("Error returned\n");
14281 }
14282 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
14283 {
14284 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
14285 printf("%s.\n", buf);
14286 else
14287 printf("Error returned\n");
14288 }
14289 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
14290 {
14291 if (argc <= 2)
14292 {
14293 printf("Insufficient arguments\n");
14294 exit(-1);
14295 }
14296 char buf[64]= {'\0'};
14297 wifi_getRadioOperatingChannelBandwidth(index,buf);
14298 printf("Current bandwidth is %s \n",buf);
14299 return 0;
14300 }
14301 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
14302 {
14303 if (argc <= 5)
14304 {
14305 printf("Insufficient arguments\n");
14306 exit(-1);
14307 }
14308 UINT channel = atoi(argv[3]);
14309 UINT width = atoi(argv[4]);
14310 UINT beacon = atoi(argv[5]);
14311 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
14312 printf("Result = %d", ret);
14313 }
14314
14315 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14316 return 0;
14317}
14318
14319#endif
14320
14321#ifdef WIFI_HAL_VERSION_3
14322
14323INT BitMapToTransmitRates(UINT bitMap, char *BasicRate)
14324{
14325 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14326 if (bitMap & WIFI_BITRATE_1MBPS)
14327 strcat(BasicRate, "1,");
14328 if (bitMap & WIFI_BITRATE_2MBPS)
14329 strcat(BasicRate, "2,");
14330 if (bitMap & WIFI_BITRATE_5_5MBPS)
14331 strcat(BasicRate, "5.5,");
14332 if (bitMap & WIFI_BITRATE_6MBPS)
14333 strcat(BasicRate, "6,");
14334 if (bitMap & WIFI_BITRATE_9MBPS)
14335 strcat(BasicRate, "9,");
14336 if (bitMap & WIFI_BITRATE_11MBPS)
14337 strcat(BasicRate, "11,");
14338 if (bitMap & WIFI_BITRATE_12MBPS)
14339 strcat(BasicRate, "12,");
14340 if (bitMap & WIFI_BITRATE_18MBPS)
14341 strcat(BasicRate, "18,");
14342 if (bitMap & WIFI_BITRATE_24MBPS)
14343 strcat(BasicRate, "24,");
14344 if (bitMap & WIFI_BITRATE_36MBPS)
14345 strcat(BasicRate, "36,");
14346 if (bitMap & WIFI_BITRATE_48MBPS)
14347 strcat(BasicRate, "48,");
14348 if (bitMap & WIFI_BITRATE_54MBPS)
14349 strcat(BasicRate, "54,");
14350 if (strlen(BasicRate) != 0) // remove last comma
14351 BasicRate[strlen(BasicRate) - 1] = '\0';
14352 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14353 return RETURN_OK;
14354}
14355
14356INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
14357{
14358 UINT BitMap = 0;
14359 char *rate;
14360
14361 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14362 rate = strtok(BasicRatesList, ",");
14363 while(rate != NULL)
14364 {
14365 if (strcmp(rate, "1") == 0)
14366 BitMap |= WIFI_BITRATE_1MBPS;
14367 else if (strcmp(rate, "2") == 0)
14368 BitMap |= WIFI_BITRATE_2MBPS;
14369 else if (strcmp(rate, "5.5") == 0)
14370 BitMap |= WIFI_BITRATE_5_5MBPS;
14371 else if (strcmp(rate, "6") == 0)
14372 BitMap |= WIFI_BITRATE_6MBPS;
14373 else if (strcmp(rate, "9") == 0)
14374 BitMap |= WIFI_BITRATE_9MBPS;
14375 else if (strcmp(rate, "11") == 0)
14376 BitMap |= WIFI_BITRATE_11MBPS;
14377 else if (strcmp(rate, "12") == 0)
14378 BitMap |= WIFI_BITRATE_12MBPS;
14379 else if (strcmp(rate, "18") == 0)
14380 BitMap |= WIFI_BITRATE_18MBPS;
14381 else if (strcmp(rate, "24") == 0)
14382 BitMap |= WIFI_BITRATE_24MBPS;
14383 else if (strcmp(rate, "36") == 0)
14384 BitMap |= WIFI_BITRATE_36MBPS;
14385 else if (strcmp(rate, "48") == 0)
14386 BitMap |= WIFI_BITRATE_48MBPS;
14387 else if (strcmp(rate, "54") == 0)
14388 BitMap |= WIFI_BITRATE_54MBPS;
14389 rate = strtok(NULL, ",");
14390 }
14391 *basicRateBitMap = BitMap;
14392 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14393 return RETURN_OK;
14394}
14395
14396// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
14397INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14398{
14399 char buf[128] = {0};
developerdaf24792023-06-06 11:40:04 +080014400 int bandwidth = 20;
developer72fb0bb2023-01-11 09:46:29 +080014401 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080014402 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developer72fb0bb2023-01-11 09:46:29 +080014403 wifi_radio_operationParam_t current_param;
14404
14405 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14406
14407 multiple_set = TRUE;
14408 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
14409 fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__);
14410 return RETURN_ERR;
14411 }
14412 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
14413 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
14414 fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__);
14415 return RETURN_ERR;
14416 }
developer333c1eb2023-05-31 14:59:39 +080014417 drv_dat_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014418 }
developer333c1eb2023-05-31 14:59:39 +080014419 if (current_param.channelWidth != operationParam->channelWidth ||
14420 current_param.channel != operationParam->channel ||
14421 current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
14422 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
14423 bandwidth = 20;
14424 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
14425 bandwidth = 40;
14426 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
14427 bandwidth = 80;
14428 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
14429 bandwidth = 160;
developer72fb0bb2023-01-11 09:46:29 +080014430
developer333c1eb2023-05-31 14:59:39 +080014431 if (operationParam->autoChannelEnabled) {
14432 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14433 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14434 return RETURN_ERR;
14435 }
14436 } else {
14437 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14438 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14439 return RETURN_ERR;
14440 }
developer72fb0bb2023-01-11 09:46:29 +080014441 }
developer333c1eb2023-05-31 14:59:39 +080014442 drv_dat_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014443 }
developer72fb0bb2023-01-11 09:46:29 +080014444 if (current_param.variant != operationParam->variant) {
14445 // Two different definition bit map, so need to check every bit.
14446 if (operationParam->variant & WIFI_80211_VARIANT_A)
14447 set_mode |= WIFI_MODE_A;
14448 if (operationParam->variant & WIFI_80211_VARIANT_B)
14449 set_mode |= WIFI_MODE_B;
14450 if (operationParam->variant & WIFI_80211_VARIANT_G)
14451 set_mode |= WIFI_MODE_G;
14452 if (operationParam->variant & WIFI_80211_VARIANT_N)
14453 set_mode |= WIFI_MODE_N;
14454 if (operationParam->variant & WIFI_80211_VARIANT_AC)
14455 set_mode |= WIFI_MODE_AC;
14456 if (operationParam->variant & WIFI_80211_VARIANT_AX)
14457 set_mode |= WIFI_MODE_AX;
14458 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
14459 memset(buf, 0, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +080014460 drv_dat_change = TRUE;
developer0f10c772023-05-16 21:43:39 +080014461 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014462 fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__);
14463 return RETURN_ERR;
14464 }
14465 }
14466 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer56fbedb2023-05-30 16:47:05 +080014467 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014468 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
14469 fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__);
14470 return RETURN_ERR;
14471 }
14472 }
14473 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer56fbedb2023-05-30 16:47:05 +080014474 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014475 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
14476 fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__);
14477 return RETURN_ERR;
14478 }
14479 }
14480 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer56fbedb2023-05-30 16:47:05 +080014481 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014482 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf);
14483 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14484 fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__);
14485 return RETURN_ERR;
14486 }
14487 }
14488 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer56fbedb2023-05-30 16:47:05 +080014489 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014490 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
14491 fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__);
14492 return RETURN_ERR;
14493 }
14494 }
14495 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080014496 hapd_conf_change = TRUE;
14497 drv_dat_change = TRUE;
14498 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014499 fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__);
14500 return RETURN_ERR;
14501 }
14502 }
14503 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080014504 drv_dat_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014505 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
14506 fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__);
14507 return RETURN_ERR;
14508 }
14509 }
14510 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
developer56fbedb2023-05-30 16:47:05 +080014511 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014512 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
14513 fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__);
14514 return RETURN_ERR;
14515 }
14516 }
14517 if (current_param.obssCoex != operationParam->obssCoex) {
developer56fbedb2023-05-30 16:47:05 +080014518 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014519 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
14520 fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__);
14521 return RETURN_ERR;
14522 }
14523 }
14524 if (current_param.stbcEnable != operationParam->stbcEnable) {
developer56fbedb2023-05-30 16:47:05 +080014525 hapd_conf_change = TRUE;
14526 drv_dat_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014527 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
14528 fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__);
14529 return RETURN_ERR;
14530 }
14531 }
14532 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
14533 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
14534 fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__);
14535 return RETURN_ERR;
14536 }
14537 }
14538
developer56fbedb2023-05-30 16:47:05 +080014539 /* only down/up interface when dat file has been changed,
14540 * if enable is true, then restart the radio.
14541 */
14542 if (drv_dat_change == TRUE) {
14543 wifi_setRadioEnable(index, FALSE);
14544 if (operationParam->enable == TRUE)
14545 wifi_setRadioEnable(index, TRUE);
14546 } else if (hapd_conf_change == TRUE) {
14547 hostapd_raw_remove_bss(index);
14548 if (operationParam->enable == TRUE)
14549 hostapd_raw_add_bss(index);
14550 }
14551
developer72fb0bb2023-01-11 09:46:29 +080014552 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14553
14554 return RETURN_OK;
14555}
14556
14557INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14558{
14559 char band[64] = {0};
14560 char buf[256] = {0};
14561 char config_file[64] = {0};
14562 char cmd[128] = {0};
developer863a4a62023-06-06 16:55:59 +080014563 UINT mode = 0;
developer72fb0bb2023-01-11 09:46:29 +080014564 BOOL enabled = FALSE;
developer863a4a62023-06-06 16:55:59 +080014565 int dtimPeriod;
developer2f79c922023-06-02 17:33:42 +080014566 UINT beaconInterval;
14567 UINT basicDataTransmitRates;
14568 UINT operationalDataTransmitRates;
14569 wifi_guard_interval_t guardInterval;
14570 UINT transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080014571
14572 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14573 printf("Entering %s index = %d\n", __func__, (int)index);
14574
14575 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
14576 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
14577 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
14578 {
14579 fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__);
14580 return RETURN_ERR;
14581 }
14582 operationParam->enable = enabled;
14583
14584 memset(band, 0, sizeof(band));
14585 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
14586 {
14587 fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__);
14588 return RETURN_ERR;
14589 }
14590
14591 if (!strcmp(band, "2.4GHz"))
14592 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
14593 else if (!strcmp(band, "5GHz"))
14594 operationParam->band = WIFI_FREQUENCY_5_BAND;
14595 else if (!strcmp(band, "6GHz"))
14596 operationParam->band = WIFI_FREQUENCY_6_BAND;
14597 else
14598 {
14599 fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
14600 band);
14601 }
14602
14603 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
14604 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
14605 operationParam->channel = 0;
14606 operationParam->autoChannelEnabled = TRUE;
14607 } else {
14608 operationParam->channel = strtol(buf, NULL, 10);
14609 operationParam->autoChannelEnabled = FALSE;
14610 }
14611
14612 memset(buf, 0, sizeof(buf));
14613 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
14614 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__);
14615 return RETURN_ERR;
14616 }
14617 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
14618 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
14619 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
14620 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
14621 else
14622 {
14623 fprintf(stderr, "Unknown channel bandwidth: %s\n", buf);
14624 return false;
14625 }
14626
14627 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
14628 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
14629 return RETURN_ERR;
14630 }
14631 // Two different definition bit map, so need to check every bit.
14632 if (mode & WIFI_MODE_A)
14633 operationParam->variant |= WIFI_80211_VARIANT_A;
14634 if (mode & WIFI_MODE_B)
14635 operationParam->variant |= WIFI_80211_VARIANT_B;
14636 if (mode & WIFI_MODE_G)
14637 operationParam->variant |= WIFI_80211_VARIANT_G;
14638 if (mode & WIFI_MODE_N)
14639 operationParam->variant |= WIFI_80211_VARIANT_N;
14640 if (mode & WIFI_MODE_AC)
14641 operationParam->variant |= WIFI_80211_VARIANT_AC;
14642 if (mode & WIFI_MODE_AX)
14643 operationParam->variant |= WIFI_80211_VARIANT_AX;
14644 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
14645 fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__);
14646 return RETURN_ERR;
14647 }
developer2f79c922023-06-02 17:33:42 +080014648 if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014649 fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__);
14650 return RETURN_ERR;
14651 }
developer2f79c922023-06-02 17:33:42 +080014652 operationParam->dtimPeriod = dtimPeriod;
14653 if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014654 fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__);
14655 return RETURN_ERR;
14656 }
developer2f79c922023-06-02 17:33:42 +080014657 operationParam->beaconInterval = beaconInterval;
developer72fb0bb2023-01-11 09:46:29 +080014658
14659 memset(buf, 0, sizeof(buf));
14660 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
14661 fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__);
14662 return RETURN_ERR;
14663 }
developer2f79c922023-06-02 17:33:42 +080014664 TransmitRatesToBitMap(buf, &basicDataTransmitRates);
14665 operationParam->basicDataTransmitRates = basicDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080014666
14667 memset(buf, 0, sizeof(buf));
14668 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14669 fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__);
14670 return RETURN_ERR;
14671 }
developer2f79c922023-06-02 17:33:42 +080014672 TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
14673 operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
developer72fb0bb2023-01-11 09:46:29 +080014674
14675 memset(buf, 0, sizeof(buf));
14676 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
14677 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
14678
developer2f79c922023-06-02 17:33:42 +080014679 if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014680 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
14681 return RETURN_ERR;
14682 }
developer2f79c922023-06-02 17:33:42 +080014683 operationParam->guardInterval = guardInterval;
14684
14685 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014686 fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__);
14687 return RETURN_ERR;
14688 }
developer2f79c922023-06-02 17:33:42 +080014689 operationParam->transmitPower = transmitPower;
developer72fb0bb2023-01-11 09:46:29 +080014690
14691 memset(buf, 0, sizeof(buf));
14692 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
14693 if (strcmp(buf, "-1") == 0) {
14694 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
14695 operationParam->ctsProtection = FALSE;
14696 } else {
14697 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
14698 operationParam->ctsProtection = TRUE;
14699 }
14700
14701 memset(buf, 0, sizeof(buf));
14702 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
14703 if (strcmp(buf, "0") == 0)
14704 operationParam->obssCoex = FALSE;
14705 else
14706 operationParam->obssCoex = TRUE;
14707
14708 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
14709 _syscmd(cmd, buf, sizeof(buf));
14710 if (strlen(buf) != 0)
14711 operationParam->stbcEnable = TRUE;
14712 else
14713 operationParam->stbcEnable = FALSE;
14714
14715 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
14716 fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__);
14717 return RETURN_ERR;
14718 }
14719
14720 // Below value is hardcoded
14721
14722 operationParam->numSecondaryChannels = 0;
14723 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
14724 operationParam->channelSecondary[i] = 0;
14725 }
14726 operationParam->csa_beacon_count = 15;
14727 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
14728
14729 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14730 return RETURN_OK;
14731}
14732
14733static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
14734{
14735 int max_radio_num = 0;
14736
14737 wifi_getMaxRadioNumber(&max_radio_num);
14738 if (radioIndex >= max_radio_num) {
14739 fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex);
14740 return RETURN_ERR;
14741 }
14742
14743 return (arrayIndex * max_radio_num) + radioIndex;
14744}
14745
developer96b38512023-02-22 11:17:45 +080014746static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
14747{
14748 int max_radio_num = 0;
14749
14750 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
14751 return -1;
14752
14753 wifi_getMaxRadioNumber(&max_radio_num);
14754
14755 (*radioIndex) = vapIndex % max_radio_num;
14756 (*arrayIndex) = vapIndex / max_radio_num;
14757
14758 return 0;
14759}
14760
14761
developer72fb0bb2023-01-11 09:46:29 +080014762wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
14763 if (strncmp(beaconRate, "1Mbps", 5) == 0)
14764 return WIFI_BITRATE_1MBPS;
14765 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
14766 return WIFI_BITRATE_2MBPS;
14767 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
14768 return WIFI_BITRATE_5_5MBPS;
14769 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
14770 return WIFI_BITRATE_6MBPS;
14771 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
14772 return WIFI_BITRATE_9MBPS;
14773 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
14774 return WIFI_BITRATE_11MBPS;
14775 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
14776 return WIFI_BITRATE_12MBPS;
14777 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
14778 return WIFI_BITRATE_18MBPS;
14779 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
14780 return WIFI_BITRATE_24MBPS;
14781 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
14782 return WIFI_BITRATE_36MBPS;
14783 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
14784 return WIFI_BITRATE_48MBPS;
14785 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
14786 return WIFI_BITRATE_54MBPS;
14787 return WIFI_BITRATE_DEFAULT;
14788}
14789
14790INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str)
14791{
14792 if (beacon == WIFI_BITRATE_1MBPS)
14793 strcpy(beacon_str, "1Mbps");
14794 else if (beacon == WIFI_BITRATE_2MBPS)
14795 strcpy(beacon_str, "2Mbps");
14796 else if (beacon == WIFI_BITRATE_5_5MBPS)
14797 strcpy(beacon_str, "5.5Mbps");
14798 else if (beacon == WIFI_BITRATE_6MBPS)
14799 strcpy(beacon_str, "6Mbps");
14800 else if (beacon == WIFI_BITRATE_9MBPS)
14801 strcpy(beacon_str, "9Mbps");
14802 else if (beacon == WIFI_BITRATE_11MBPS)
14803 strcpy(beacon_str, "11Mbps");
14804 else if (beacon == WIFI_BITRATE_12MBPS)
14805 strcpy(beacon_str, "12Mbps");
14806 else if (beacon == WIFI_BITRATE_18MBPS)
14807 strcpy(beacon_str, "18Mbps");
14808 else if (beacon == WIFI_BITRATE_24MBPS)
14809 strcpy(beacon_str, "24Mbps");
14810 else if (beacon == WIFI_BITRATE_36MBPS)
14811 strcpy(beacon_str, "36Mbps");
14812 else if (beacon == WIFI_BITRATE_48MBPS)
14813 strcpy(beacon_str, "48Mbps");
14814 else if (beacon == WIFI_BITRATE_54MBPS)
14815 strcpy(beacon_str, "54Mbps");
14816 return RETURN_OK;
14817}
14818
14819INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
14820{
14821 INT mode = 0;
14822 INT ret = -1;
developer863a4a62023-06-06 16:55:59 +080014823 UINT output = 0;
developer72fb0bb2023-01-11 09:46:29 +080014824 int i = 0;
14825 int vap_index = 0;
14826 BOOL enabled = FALSE;
developerb149d9d2023-06-06 16:14:22 +080014827 char buf[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +080014828 wifi_vap_security_t security = {0};
developer72fb0bb2023-01-11 09:46:29 +080014829
14830 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14831 printf("Entering %s index = %d\n", __func__, (int)index);
14832
developerfde01262023-05-22 15:15:24 +080014833 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
14834 if (ret != 0) {
14835 fprintf(stderr, "%s: wifi_BandProfileRead BssidNum failed\n", __func__);
14836 return RETURN_ERR;
14837 }
14838
14839 map->num_vaps = atoi(buf);
14840 if (map->num_vaps <= 0) {
14841 fprintf(stderr, "%s: invalid BssidNum %s\n", __func__, buf);
14842 return RETURN_ERR;
14843 }
14844
14845 for (i = 0; i < map->num_vaps; i++)
developer72fb0bb2023-01-11 09:46:29 +080014846 {
14847 map->vap_array[i].radio_index = index;
14848
14849 vap_index = array_index_to_vap_index(index, i);
14850 if (vap_index < 0)
14851 return RETURN_ERR;
14852
14853 strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME);
14854
14855 map->vap_array[i].vap_index = vap_index;
14856
14857 memset(buf, 0, sizeof(buf));
14858 ret = wifi_getApName(vap_index, buf);
14859 if (ret != RETURN_OK) {
14860 printf("%s: wifi_getApName return error\n", __func__);
14861 return RETURN_ERR;
14862 }
14863 snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
14864
14865 memset(buf, 0, sizeof(buf));
14866 ret = wifi_getSSIDName(vap_index, buf);
14867 if (ret != RETURN_OK) {
14868 printf("%s: wifi_getSSIDName return error\n", __func__);
14869 return RETURN_ERR;
14870 }
14871 snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
14872
developere740c2a2023-05-23 18:34:32 +080014873#if 0
developer72fb0bb2023-01-11 09:46:29 +080014874 ret = wifi_getSSIDEnable(vap_index, &enabled);
14875 if (ret != RETURN_OK) {
14876 printf("%s: wifi_getSSIDEnable return error\n", __func__);
14877 return RETURN_ERR;
14878 }
developere740c2a2023-05-23 18:34:32 +080014879#endif
14880 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080014881
14882 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
14883 if (ret != RETURN_OK) {
14884 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
14885 return RETURN_ERR;
14886 }
14887 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080014888
developer72fb0bb2023-01-11 09:46:29 +080014889 ret = wifi_getApIsolationEnable(vap_index, &enabled);
14890 if (ret != RETURN_OK) {
14891 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
14892 return RETURN_ERR;
14893 }
14894 map->vap_array[i].u.bss_info.isolation = enabled;
14895
14896 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
14897 if (ret != RETURN_OK) {
14898 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
14899 return RETURN_ERR;
14900 }
14901 map->vap_array[i].u.bss_info.bssMaxSta = output;
14902
14903 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
14904 if (ret != RETURN_OK) {
14905 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
14906 return RETURN_ERR;
14907 }
14908 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
14909
14910 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
14911 if (ret != RETURN_OK) {
14912 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
14913 return RETURN_ERR;
14914 }
14915 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
14916
14917 ret = wifi_getApSecurity(vap_index, &security);
14918 if (ret != RETURN_OK) {
14919 printf("%s: wifi_getApSecurity return error\n", __func__);
14920 return RETURN_ERR;
14921 }
14922 map->vap_array[i].u.bss_info.security = security;
14923
14924 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
14925 if (ret != RETURN_OK) {
14926 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
14927 return RETURN_ERR;
14928 }
developer69b61b02023-03-07 17:17:44 +080014929 if (mode == 0)
developer72fb0bb2023-01-11 09:46:29 +080014930 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
developer69b61b02023-03-07 17:17:44 +080014931 else
developer72fb0bb2023-01-11 09:46:29 +080014932 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
developer69b61b02023-03-07 17:17:44 +080014933 if (mode == 1)
developer72fb0bb2023-01-11 09:46:29 +080014934 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
developer69b61b02023-03-07 17:17:44 +080014935 else if (mode == 2)
developer72fb0bb2023-01-11 09:46:29 +080014936 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
14937
14938 ret = wifi_getApWmmEnable(vap_index, &enabled);
14939 if (ret != RETURN_OK) {
14940 printf("%s: wifi_getApWmmEnable return error\n", __func__);
14941 return RETURN_ERR;
14942 }
14943 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
14944
14945 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
14946 if (ret != RETURN_OK) {
14947 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
14948 return RETURN_ERR;
14949 }
14950 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
14951
14952 memset(buf, 0, sizeof(buf));
14953 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
14954 if (ret != RETURN_OK) {
14955 printf("%s: wifi_getApBeaconRate return error\n", __func__);
14956 return RETURN_ERR;
14957 }
14958 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
14959
14960 memset(buf, 0, sizeof(buf));
14961 ret = wifi_getBaseBSSID(vap_index, buf);
14962 if (ret != RETURN_OK) {
14963 printf("%s: wifi_getBaseBSSID return error\n", __func__);
14964 return RETURN_ERR;
14965 }
developer5b2f10c2023-05-25 17:02:21 +080014966 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
14967 printf("%s: hwaddr_aton2 fail\n", __func__);
14968 return RETURN_ERR;
14969 }
developer72fb0bb2023-01-11 09:46:29 +080014970
14971 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
14972 if (ret != RETURN_OK) {
14973 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
14974 return RETURN_ERR;
14975 }
14976 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
14977
14978 // TODO: wps, noack
14979 }
14980 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14981 return RETURN_OK;
14982}
14983
developer47cc27a2023-05-17 23:09:58 +080014984void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080014985{
14986 char if_name[16] = {0};
14987 char cmd[128] = {0};
14988 char buf[128] = {0};
14989
14990 *enable = FALSE;
14991 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
14992 return;
14993
14994 snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
14995 _syscmd(cmd, buf, sizeof(buf));
14996 if (strlen(buf) > 0)
14997 *enable = TRUE;
14998 return;
14999}
15000
developer56fbedb2023-05-30 16:47:05 +080015001int hostapd_manage_bss(INT apIndex, BOOL enable)
15002{
15003 char interface_name[16] = {0};
developerb149d9d2023-06-06 16:14:22 +080015004 char config_file[MAX_SUB_CMD_SIZE] = {0};
developer56fbedb2023-05-30 16:47:05 +080015005 char cmd[MAX_CMD_SIZE] = {0};
15006 char buf[MAX_BUF_SIZE] = {0};
15007 BOOL status = FALSE;
15008 int max_radio_num = 0;
15009 int phyId = 0;
15010
15011 wifi_getApEnable(apIndex, &status);
15012
15013 wifi_getMaxRadioNumber(&max_radio_num);
15014 if (enable == status)
15015 return RETURN_OK;
15016
15017 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
15018 return RETURN_ERR;
15019
15020 if (enable == TRUE) {
15021 int radioIndex = apIndex % max_radio_num;
15022 phyId = radio_index_to_phy(radioIndex);
15023 fprintf(stderr, "%s %d\n", __func__, __LINE__);
15024 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
15025 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
15026 _syscmd(cmd, buf, sizeof(buf));
15027 } else {
15028 fprintf(stderr, "%s %d\n", __func__, __LINE__);
15029 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
15030 _syscmd(cmd, buf, sizeof(buf));
15031 }
15032 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
15033 interface_name, interface_name, enable, VAP_STATUS_FILE);
15034 _syscmd(cmd, buf, sizeof(buf));
15035 //Wait for wifi up/down to apply
15036 return RETURN_OK;
15037}
15038
15039int hostapd_raw_add_bss(int apIndex)
15040{
15041 return hostapd_manage_bss(apIndex, TRUE);
15042}
15043
15044int hostapd_raw_remove_bss(int apIndex)
15045{
15046 return hostapd_manage_bss(apIndex, FALSE);
15047}
15048
15049int hostapd_raw_restart_bss(int apIndex)
developer333c1eb2023-05-31 14:59:39 +080015050{
developerdaf24792023-06-06 11:40:04 +080015051 int ret = 0;
15052
15053 ret = hostapd_raw_remove_bss(apIndex);
15054 if(ret != RETURN_OK)
15055 return RETURN_ERR;
15056
15057 ret = hostapd_raw_add_bss(apIndex);
15058 if(ret != RETURN_OK)
15059 return RETURN_ERR;
15060
15061 return RETURN_OK;
developer56fbedb2023-05-30 16:47:05 +080015062}
15063
developer72fb0bb2023-01-11 09:46:29 +080015064INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15065{
developer72fb0bb2023-01-11 09:46:29 +080015066 unsigned int i;
15067 wifi_vap_info_t *vap_info = NULL;
15068 int acl_mode;
15069 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +080015070 char buf[256] = {0};
15071 char cmd[128] = {0};
15072 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015073 char psk_file[64] = {0};
developer47cc27a2023-05-17 23:09:58 +080015074 BOOL enable = FALSE;
developere740c2a2023-05-23 18:34:32 +080015075 int band_idx;
15076
developer72fb0bb2023-01-11 09:46:29 +080015077
15078 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15079 printf("Entering %s index = %d\n", __func__, (int)index);
15080 for (i = 0; i < map->num_vaps; i++)
15081 {
15082 multiple_set = TRUE;
15083 vap_info = &map->vap_array[i];
15084
15085 // Check vap status file to enable multiple ap if the system boot.
15086 checkVapStatus(vap_info->vap_index, &enable);
15087 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
15088 continue;
15089
15090 fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
15091
developere740c2a2023-05-23 18:34:32 +080015092 band_idx = radio_index_to_band(index);
15093 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
15094 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
15095 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015096
developer56fbedb2023-05-30 16:47:05 +080015097 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080015098 params[0].name = "interface";
15099 params[0].value = vap_info->vap_name;
developer72fb0bb2023-01-11 09:46:29 +080015100 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
developer56fbedb2023-05-30 16:47:05 +080015101 params[1].name = "wpa_psk_file";
15102 params[1].value = psk_file;
15103 params[2].name = "ssid";
15104 params[2].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080015105
15106 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
developer56fbedb2023-05-30 16:47:05 +080015107 wifi_hostapdWrite(config_file, params, 3);
developer72fb0bb2023-01-11 09:46:29 +080015108
15109 snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
15110 _syscmd(cmd, buf, sizeof(buf));
15111
15112 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
15113 if (ret != RETURN_OK) {
15114 fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__);
15115 return RETURN_ERR;
15116 }
15117
15118 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
15119 if (ret != RETURN_OK) {
15120 fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__);
15121 return RETURN_ERR;
15122 }
15123
15124 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
15125 if (ret != RETURN_OK) {
15126 fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__);
15127 return RETURN_ERR;
15128 }
15129
15130 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
15131 if (ret != RETURN_OK) {
15132 fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__);
15133 return RETURN_ERR;
15134 }
15135
15136 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
15137 if (ret != RETURN_OK) {
15138 fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__);
15139 return RETURN_ERR;
15140 }
15141
15142 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
15143 if (ret != RETURN_OK) {
15144 fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__);
15145 return RETURN_ERR;
15146 }
15147
15148 if (vap_info->u.bss_info.mac_filter_enable == false){
15149 acl_mode = 0;
15150 }else {
15151 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
15152 acl_mode = 2;
15153 snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
15154 _syscmd(cmd, buf, sizeof(buf));
15155 }else{
15156 acl_mode = 1;
15157 }
15158 }
15159
15160 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
15161 if (ret != RETURN_OK) {
15162 fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__);
15163 return RETURN_ERR;
15164 }
15165
15166 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
15167 if (ret != RETURN_OK) {
15168 fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__);
15169 return RETURN_ERR;
15170 }
15171
developer0f10c772023-05-16 21:43:39 +080015172 memset(buf, 0, sizeof(buf));
15173 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf);
15174 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
15175 if (ret != RETURN_OK) {
15176 fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__);
15177 return RETURN_ERR;
15178 }
developer72fb0bb2023-01-11 09:46:29 +080015179
15180 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
15181 if (ret != RETURN_OK) {
15182 fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__);
15183 return RETURN_ERR;
15184 }
15185
developer72fb0bb2023-01-11 09:46:29 +080015186 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
15187 if (ret != RETURN_OK) {
15188 fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__);
15189 return RETURN_ERR;
15190 }
developer333c1eb2023-05-31 14:59:39 +080015191
developer56fbedb2023-05-30 16:47:05 +080015192 hostapd_raw_restart_bss(vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080015193
developer23e71282023-01-18 10:25:19 +080015194 multiple_set = FALSE;
15195
15196 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
developer72fb0bb2023-01-11 09:46:29 +080015197 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
15198 if (ret != RETURN_OK) {
15199 fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__);
15200 return RETURN_ERR;
15201 }
15202
15203 // TODO mgmtPowerControl, interworking, wps
15204 }
15205 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15206 return RETURN_OK;
15207}
15208
15209int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
15210{
15211 char *token, *next;
15212 const char s[2] = ",";
15213 int count =0;
15214
15215 /* get the first token */
15216 token = strtok_r(pchannels, s, &next);
15217
15218 /* walk through other tokens */
15219 while( token != NULL && count < MAX_CHANNELS) {
15220 chlistptr->channels_list[count++] = atoi(token);
15221 token = strtok_r(NULL, s, &next);
15222 }
15223
15224 return count;
15225}
15226
15227static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
15228{
15229 INT status;
15230 wifi_channels_list_t *chlistp;
15231 CHAR output_string[64];
15232 CHAR pchannels[128];
15233 CHAR interface_name[16] = {0};
15234 wifi_band band;
15235
15236 if(rcap == NULL)
15237 {
15238 return RETURN_ERR;
15239 }
15240
15241 rcap->numSupportedFreqBand = 1;
15242 band = wifi_index_to_band(radioIndex);
15243
15244 if (band == band_2_4)
15245 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
15246 else if (band == band_5)
15247 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
15248 else if (band == band_6)
15249 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
15250
15251 chlistp = &(rcap->channel_list[0]);
15252 memset(pchannels, 0, sizeof(pchannels));
15253
15254 /* possible number of radio channels */
15255 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
15256 {
15257 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
15258 }
15259 /* Number of channels and list*/
15260 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
15261
15262 /* autoChannelSupported */
15263 /* always ON with wifi_getRadioAutoChannelSupported */
15264 rcap->autoChannelSupported = TRUE;
15265
15266 /* DCSSupported */
15267 /* always ON with wifi_getRadioDCSSupported */
15268 rcap->DCSSupported = TRUE;
15269
15270 /* zeroDFSSupported - TBD */
15271 rcap->zeroDFSSupported = FALSE;
15272
15273 /* Supported Country List*/
15274 memset(output_string, 0, sizeof(output_string));
15275 status = wifi_getRadioCountryCode(radioIndex, output_string);
15276 if( status != 0 ) {
15277 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
15278 return RETURN_ERR;
15279 } else {
15280 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
15281 }
15282 if(!strcmp(output_string,"US")){
15283 rcap->countrySupported[0] = wifi_countrycode_US;
15284 rcap->countrySupported[1] = wifi_countrycode_CA;
15285 } else if (!strcmp(output_string,"CA")) {
15286 rcap->countrySupported[0] = wifi_countrycode_CA;
15287 rcap->countrySupported[1] = wifi_countrycode_US;
15288 } else {
15289 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
15290 }
15291
15292 rcap->numcountrySupported = 2;
15293
15294 /* csi */
15295 rcap->csi.maxDevices = 8;
15296 rcap->csi.soudingFrameSupported = TRUE;
15297
15298 wifi_GetInterfaceName(radioIndex, interface_name);
15299 snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
15300
15301 /* channelWidth - all supported bandwidths */
15302 int i=0;
15303 rcap->channelWidth[i] = 0;
15304 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
15305 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
15306 WIFI_CHANNELBANDWIDTH_40MHZ);
15307
15308 }
15309 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
15310 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
15311 WIFI_CHANNELBANDWIDTH_40MHZ |
15312 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
15313 }
15314
15315
15316 /* mode - all supported variants */
15317 // rcap->mode[i] = WIFI_80211_VARIANT_H;
15318 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
15319 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
15320 }
15321 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
15322 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
15323 }
15324 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
15325 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
15326 }
15327 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
15328 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
15329
15330 /* supportedBitRate - all supported bitrates */
15331 rcap->supportedBitRate[i] = 0;
15332 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
15333 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
15334 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
15335 }
developerdaf24792023-06-06 11:40:04 +080015336 else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
developer72fb0bb2023-01-11 09:46:29 +080015337 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
15338 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
15339 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
15340 }
15341
15342
15343 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
15344 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
15345 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
15346 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
15347 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
15348 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
15349 rcap->cipherSupported = 0;
15350 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
15351 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
15352
15353 return RETURN_OK;
15354}
15355
15356INT wifi_getHalCapability(wifi_hal_capability_t *cap)
15357{
15358 INT status = 0, radioIndex = 0;
developer2f79c922023-06-02 17:33:42 +080015359 char output[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015360 int iter = 0;
15361 unsigned int j = 0;
15362 int max_num_radios;
15363 wifi_interface_name_idex_map_t *iface_info = NULL;
15364
15365 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15366
15367 memset(cap, 0, sizeof(wifi_hal_capability_t));
15368
15369 /* version */
15370 cap->version.major = WIFI_HAL_MAJOR_VERSION;
15371 cap->version.minor = WIFI_HAL_MINOR_VERSION;
15372
15373 /* number of radios platform property */
15374 wifi_getMaxRadioNumber(&max_num_radios);
15375 cap->wifi_prop.numRadios = max_num_radios;
15376
15377 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
15378 {
15379 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
15380 if (status != 0) {
15381 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
15382 return RETURN_ERR;
15383 }
15384
15385 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
15386 {
15387 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
15388 {
15389 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
15390 return RETURN_ERR;
15391 }
15392 iface_info = &cap->wifi_prop.interface_map[iter];
15393 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
15394 iface_info->rdk_radio_index = radioIndex;
15395 memset(output, 0, sizeof(output));
15396 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
15397 {
15398 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
15399 }
15400 // TODO: bridge name
15401 // TODO: vlan id
15402 // TODO: primary
15403 iface_info->index = array_index_to_vap_index(radioIndex, j);
15404 memset(output, 0, sizeof(output));
15405 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
15406 {
15407 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
15408 }
15409 iter++;
15410 }
15411 }
15412
15413 cap->BandSteeringSupported = FALSE;
15414 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15415 return RETURN_OK;
15416}
15417
15418INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
15419{
15420 struct params h_config={0};
15421 char config_file[64] = {0};
15422
15423 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15424
15425 h_config.name = "okc";
15426 h_config.value = okc_enable?"1":"0";
15427
15428 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15429 wifi_hostapdWrite(config_file, &h_config, 1);
15430 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15431
15432 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15433 return RETURN_OK;
15434}
15435
15436INT wifi_setSAEMFP(int ap_index, BOOL enable)
15437{
15438 struct params h_config={0};
15439 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015440
15441 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15442
15443 h_config.name = "sae_require_mfp";
15444 h_config.value = enable?"1":"0";
15445
15446 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15447 wifi_hostapdWrite(config_file, &h_config, 1);
15448 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15449
15450 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15451 return RETURN_OK;
15452}
15453
15454INT wifi_setSAEpwe(int ap_index, int sae_pwe)
15455{
15456 struct params h_config={0};
15457 char config_file[64] = {0};
15458 char buf[128] = {0};
15459
15460 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15461
15462 h_config.name = "sae_pwe";
15463 snprintf(buf, sizeof(buf), "%d", sae_pwe);
15464 h_config.value = buf;
15465
15466 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15467 wifi_hostapdWrite(config_file, &h_config, 1);
15468 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15469
15470 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15471 return RETURN_OK;
15472}
15473
15474INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
15475{
15476 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
15477 struct params h_config={0};
15478 char config_file[64] = {0};
15479
15480 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15481
15482 h_config.name = "wpa_disable_eapol_key_retries";
15483 h_config.value = disable_EAPOL_retries?"1":"0";
15484
15485 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15486 wifi_hostapdWrite(config_file, &h_config, 1);
15487 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15488
15489 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15490 return RETURN_OK;
15491}
15492
15493INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
15494{
15495 char buf[128] = {0};
15496 char config_file[128] = {0};
developerb149d9d2023-06-06 16:14:22 +080015497 char cmd[MAX_CMD_SIZE] = {0};
developer863a4a62023-06-06 16:55:59 +080015498 char password[65] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015499 char mfp[32] = {0};
15500 char wpa_mode[32] = {0};
15501 BOOL okc_enable = FALSE;
15502 BOOL sae_MFP = FALSE;
15503 BOOL disable_EAPOL_retries = TRUE;
15504 int sae_pwe = 0;
15505 struct params params = {0};
15506 wifi_band band = band_invalid;
15507
15508 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15509
15510 multiple_set = TRUE;
15511 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15512 if (security->mode == wifi_security_mode_none) {
15513 strcpy(wpa_mode, "None");
15514 } else if (security->mode == wifi_security_mode_wpa_personal)
15515 strcpy(wpa_mode, "WPA-Personal");
15516 else if (security->mode == wifi_security_mode_wpa2_personal)
15517 strcpy(wpa_mode, "WPA2-Personal");
15518 else if (security->mode == wifi_security_mode_wpa_wpa2_personal)
15519 strcpy(wpa_mode, "WPA-WPA2-Personal");
15520 else if (security->mode == wifi_security_mode_wpa_enterprise)
15521 strcpy(wpa_mode, "WPA-Enterprise");
15522 else if (security->mode == wifi_security_mode_wpa2_enterprise)
15523 strcpy(wpa_mode, "WPA2-Enterprise");
15524 else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise)
15525 strcpy(wpa_mode, "WPA-WPA2-Enterprise");
15526 else if (security->mode == wifi_security_mode_wpa3_personal) {
15527 strcpy(wpa_mode, "WPA3-Personal");
15528 okc_enable = TRUE;
15529 sae_MFP = TRUE;
15530 sae_pwe = 2;
15531 disable_EAPOL_retries = FALSE;
15532 } else if (security->mode == wifi_security_mode_wpa3_transition) {
15533 strcpy(wpa_mode, "WPA3-Personal-Transition");
15534 okc_enable = TRUE;
15535 sae_MFP = TRUE;
15536 sae_pwe = 2;
15537 disable_EAPOL_retries = FALSE;
15538 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
15539 strcpy(wpa_mode, "WPA3-Enterprise");
15540 sae_MFP = TRUE;
15541 sae_pwe = 2;
15542 disable_EAPOL_retries = FALSE;
developerd01e3e82023-04-26 19:10:38 +080015543 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer3086e2f2023-01-17 09:40:01 +080015544 strcpy(wpa_mode, "OWE");
15545 sae_MFP = TRUE;
15546 sae_pwe = 2;
15547 disable_EAPOL_retries = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015548 }
15549
15550 band = wifi_index_to_band(ap_index);
15551 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
15552 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
15553 return RETURN_ERR;
15554 }
15555
15556 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
15557 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
15558 wifi_setSAEMFP(ap_index, sae_MFP);
15559 wifi_setSAEpwe(ap_index, sae_pwe);
15560 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
15561
developerd01e3e82023-04-26 19:10:38 +080015562 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
developere5750452023-05-15 16:46:42 +080015563 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) {
15564 int key_len = strlen(security->u.key.key);
15565 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
15566 if (key_len == 64) { // set wpa_psk
15567 strncpy(password, security->u.key.key, 64); // 64 characters
15568 password[64] = '\0';
15569 wifi_setApSecurityPreSharedKey(ap_index, password);
15570 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
15571 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
15572 strncpy(password, security->u.key.key, 63);
15573 password[63] = '\0';
15574 wifi_setApSecurityKeyPassphrase(ap_index, password);
15575 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
15576 } else
15577 return RETURN_ERR;
15578 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015579 }
15580 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
15581 params.name = "sae_password";
15582 params.value = security->u.key.key;
15583 wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +080015584 } else { // remove sae_password
15585 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
15586 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015587 }
15588 }
15589
15590 if (security->mode != wifi_security_mode_none) {
15591 memset(&params, 0, sizeof(params));
15592 params.name = "wpa_pairwise";
15593 if (security->encr == wifi_encryption_tkip)
15594 params.value = "TKIP";
15595 else if (security->encr == wifi_encryption_aes)
15596 params.value = "CCMP";
15597 else if (security->encr == wifi_encryption_aes_tkip)
15598 params.value = "TKIP CCMP";
15599 wifi_hostapdWrite(config_file, &params, 1);
15600 }
15601
15602 if (security->mfp == wifi_mfp_cfg_disabled)
15603 strcpy(mfp, "Disabled");
15604 else if (security->mfp == wifi_mfp_cfg_optional)
15605 strcpy(mfp, "Optional");
15606 else if (security->mfp == wifi_mfp_cfg_required)
15607 strcpy(mfp, "Required");
15608 wifi_setApSecurityMFPConfig(ap_index, mfp);
15609
15610 memset(&params, 0, sizeof(params));
15611 params.name = "transition_disable";
15612 if (security->wpa3_transition_disable == TRUE)
15613 params.value = "0x01";
15614 else
15615 params.value = "0x00";
15616 wifi_hostapdWrite(config_file, &params, 1);
15617
15618 memset(&params, 0, sizeof(params));
15619 params.name = "wpa_group_rekey";
15620 snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
15621 params.value = buf;
15622 wifi_hostapdWrite(config_file, &params, 1);
15623
15624 memset(&params, 0, sizeof(params));
15625 params.name = "wpa_strict_rekey";
15626 params.value = security->strict_rekey?"1":"0";
15627 wifi_hostapdWrite(config_file, &params, 1);
15628
15629 memset(&params, 0, sizeof(params));
15630 params.name = "wpa_pairwise_update_count";
developere5750452023-05-15 16:46:42 +080015631 if (security->eapol_key_retries == 0)
15632 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developer72fb0bb2023-01-11 09:46:29 +080015633 snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
15634 params.value = buf;
15635 wifi_hostapdWrite(config_file, &params, 1);
15636
15637 memset(&params, 0, sizeof(params));
15638 params.name = "disable_pmksa_caching";
15639 params.value = security->disable_pmksa_caching?"1":"0";
15640 wifi_hostapdWrite(config_file, &params, 1);
15641
developer23e71282023-01-18 10:25:19 +080015642 if (multiple_set == FALSE) {
15643 wifi_setApEnable(ap_index, FALSE);
15644 wifi_setApEnable(ap_index, TRUE);
15645 }
developer72fb0bb2023-01-11 09:46:29 +080015646
15647 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15648
15649 return RETURN_OK;
15650}
15651
15652INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
15653{
15654 char buf[256] = {0};
15655 char config_file[128] = {0};
15656 int disable = 0;
developere5750452023-05-15 16:46:42 +080015657 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015658
15659 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15660 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15661 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
15662 security->mode = wifi_security_mode_none;
15663 if (strlen(buf) != 0) {
15664 if (!strcmp(buf, "WPA-Personal"))
15665 security->mode = wifi_security_mode_wpa_personal;
15666 else if (!strcmp(buf, "WPA2-Personal"))
15667 security->mode = wifi_security_mode_wpa2_personal;
15668 else if (!strcmp(buf, "WPA-WPA2-Personal"))
15669 security->mode = wifi_security_mode_wpa_wpa2_personal;
15670 else if (!strcmp(buf, "WPA-Enterprise"))
15671 security->mode = wifi_security_mode_wpa_enterprise;
15672 else if (!strcmp(buf, "WPA2-Enterprise"))
15673 security->mode = wifi_security_mode_wpa2_enterprise;
15674 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
15675 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
15676 else if (!strcmp(buf, "WPA3-Personal"))
15677 security->mode = wifi_security_mode_wpa3_personal;
15678 else if (!strcmp(buf, "WPA3-Personal-Transition"))
15679 security->mode = wifi_security_mode_wpa3_transition;
15680 else if (!strcmp(buf, "WPA3-Enterprise"))
15681 security->mode = wifi_security_mode_wpa3_enterprise;
developer3086e2f2023-01-17 09:40:01 +080015682 else if (!strcmp(buf, "OWE"))
developerd01e3e82023-04-26 19:10:38 +080015683 security->mode = wifi_security_mode_enhanced_open;
developer72fb0bb2023-01-11 09:46:29 +080015684 }
15685
15686 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
15687 if (security->mode == wifi_security_mode_none)
15688 security->encr = wifi_encryption_none;
15689 else {
15690 if (strcmp(buf, "TKIP") == 0)
15691 security->encr = wifi_encryption_tkip;
15692 else if (strcmp(buf, "CCMP") == 0)
15693 security->encr = wifi_encryption_aes;
15694 else
15695 security->encr = wifi_encryption_aes_tkip;
15696 }
15697
developerdaf24792023-06-06 11:40:04 +080015698 if (security->mode != wifi_security_mode_none) {
developer72fb0bb2023-01-11 09:46:29 +080015699 memset(buf, 0, sizeof(buf));
15700 // wpa3 can use one or both configs as password, so we check sae_password first.
15701 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
developere5750452023-05-15 16:46:42 +080015702 if (strlen(buf) != 0) {
15703 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
15704 security->u.key.type = wifi_security_key_type_sae;
15705 set_sae = TRUE;
15706 strncpy(security->u.key.key, buf, sizeof(buf));
15707 }
15708 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
15709 if (strlen(buf) != 0){
15710 if (set_sae == TRUE)
15711 security->u.key.type = wifi_security_key_type_psk_sae;
15712 else if (strlen(buf) == 64)
15713 security->u.key.type = wifi_security_key_type_psk;
15714 else
15715 security->u.key.type = wifi_security_key_type_pass;
15716 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
developer72fb0bb2023-01-11 09:46:29 +080015717 }
developer72fb0bb2023-01-11 09:46:29 +080015718 security->u.key.key[255] = '\0';
15719 }
15720
15721 memset(buf, 0, sizeof(buf));
15722 wifi_getApSecurityMFPConfig(ap_index, buf);
15723 if (strcmp(buf, "Disabled") == 0)
15724 security->mfp = wifi_mfp_cfg_disabled;
15725 else if (strcmp(buf, "Optional") == 0)
15726 security->mfp = wifi_mfp_cfg_optional;
15727 else if (strcmp(buf, "Required") == 0)
15728 security->mfp = wifi_mfp_cfg_required;
15729
15730 memset(buf, 0, sizeof(buf));
15731 security->wpa3_transition_disable = FALSE;
15732 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
15733 disable = strtol(buf, NULL, 16);
15734 if (disable != 0)
15735 security->wpa3_transition_disable = TRUE;
15736
15737 memset(buf, 0, sizeof(buf));
15738 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
15739 if (strlen(buf) == 0)
15740 security->rekey_interval = 86400;
15741 else
15742 security->rekey_interval = strtol(buf, NULL, 10);
15743
15744 memset(buf, 0, sizeof(buf));
15745 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
15746 if (strlen(buf) == 0)
15747 security->strict_rekey = 1;
15748 else
15749 security->strict_rekey = strtol(buf, NULL, 10);
15750
15751 memset(buf, 0, sizeof(buf));
15752 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
15753 if (strlen(buf) == 0)
15754 security->eapol_key_retries = 4;
15755 else
15756 security->eapol_key_retries = strtol(buf, NULL, 10);
15757
15758 memset(buf, 0, sizeof(buf));
15759 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
15760 if (strlen(buf) == 0)
15761 security->disable_pmksa_caching = FALSE;
15762 else
15763 security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE;
15764
15765 /* TODO
15766 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
15767 */
15768 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
15769 security->eap_identity_req_timeout = 0;
15770 security->eap_identity_req_retries = 0;
15771 security->eap_req_timeout = 0;
15772 security->eap_req_retries = 0;
15773 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15774 return RETURN_OK;
15775}
15776
15777#endif /* WIFI_HAL_VERSION_3 */
15778
15779#ifdef WIFI_HAL_VERSION_3_PHASE2
15780INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
15781{
15782 char interface_name[16] = {0};
15783 char cmd[128] = {0};
15784 char buf[128] = {0};
15785 char *mac_addr = NULL;
15786 BOOL status = FALSE;
15787 size_t len = 0;
15788
15789 if(ap_index > MAX_APS)
15790 return RETURN_ERR;
15791
15792 *output_numDevices = 0;
15793 wifi_getApEnable(ap_index, &status);
15794 if (status == FALSE)
15795 return RETURN_OK;
15796
15797 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
15798 return RETURN_ERR;
15799 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
15800 _syscmd(cmd, buf, sizeof(buf));
15801
15802 mac_addr = strtok(buf, "\n");
15803 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
15804 *output_numDevices = i + 1;
15805 fprintf(stderr, "mac_addr: %s\n", mac_addr);
15806 addr_ptr = output_deviceMacAddressArray[i];
15807 mac_addr_aton(addr_ptr, mac_addr);
15808 mac_addr = strtok(NULL, "\n");
15809 }
15810
15811 return RETURN_OK;
15812}
15813#else
15814INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
15815{
15816 char interface_name[16] = {0};
15817 char cmd[128];
15818 BOOL status = false;
15819
15820 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
15821 return RETURN_ERR;
15822
15823 output_buf[0] = '\0';
15824
15825 wifi_getApEnable(ap_index,&status);
15826 if (!status)
15827 return RETURN_OK;
15828
15829 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
15830 return RETURN_ERR;
15831 sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
15832 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080015833
developer72fb0bb2023-01-11 09:46:29 +080015834 return RETURN_OK;
15835}
15836#endif
15837
15838INT wifi_getProxyArp(INT apIndex, BOOL *enable)
15839{
15840 char output[16]={'\0'};
15841 char config_file[MAX_BUF_SIZE] = {0};
15842
15843 if (!enable)
15844 return RETURN_ERR;
15845
15846 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
15847 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
15848
15849 if (strlen(output) == 0)
15850 *enable = FALSE;
15851 else if (strncmp(output, "1", 1) == 0)
15852 *enable = TRUE;
15853 else
15854 *enable = FALSE;
15855
15856 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
15857 return RETURN_OK;
15858}
15859
15860INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
15861{
15862 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
15863 return RETURN_ERR;
15864 *output_enable=TRUE;
15865 return RETURN_OK;
15866}
15867
15868INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
15869{
15870 char cmd[128] = {0};
15871 char buf[128] = {0};
15872 char line[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015873 FILE *f = NULL;
15874 int index = 0;
15875 int exp = 0;
15876 int mantissa = 0;
15877 int duration = 0;
15878 int radio_index = 0;
15879 int max_radio_num = 0;
15880 uint twt_wake_interval = 0;
15881 int phyId = 0;
15882 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15883
15884 wifi_getMaxRadioNumber(&max_radio_num);
15885
15886 radio_index = ap_index % max_radio_num;
15887
15888 phyId = radio_index_to_phy(radio_index);
15889 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
15890 _syscmd(cmd, buf, sizeof(buf));
15891 *numSessionReturned = strtol(buf, NULL, 10) - 1;
15892 if (*numSessionReturned > maxNumberSessions)
15893 *numSessionReturned = maxNumberSessions;
15894 else if (*numSessionReturned < 1) {
15895 *numSessionReturned = 0;
15896 return RETURN_OK;
15897 }
15898
15899 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
15900 if ((f = popen(cmd, "r")) == NULL) {
15901 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
15902 return RETURN_ERR;
15903 }
15904
15905 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
15906 while((fgets(line, sizeof(line), f)) != NULL) {
15907 char *tmp = NULL;
15908 strcpy(buf, line);
15909 tmp = strtok(buf, " ");
15910 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
15911 tmp = strtok(NULL, " ");
15912 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
15913 tmp = strtok(NULL, " ");
15914 if (strstr(tmp, "t")) {
15915 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
15916 }
15917 if (strstr(tmp, "a")) {
15918 twtSessions[index].twtParameters.operation.announced = TRUE;
15919 }
15920 tmp = strtok(NULL, " ");
15921 exp = strtol(tmp, NULL, 10);
15922 tmp = strtok(NULL, " ");
15923 mantissa = strtol(tmp, NULL, 10);
15924 tmp = strtok(NULL, " ");
15925 duration = strtol(tmp, NULL, 10);
15926
15927 // only implicit supported
15928 twtSessions[index].twtParameters.operation.implicit = TRUE;
15929 // only individual agreement supported
15930 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
15931
15932 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
15933 twt_wake_interval = mantissa * (1 << exp);
15934 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
15935 // Overflow handling
15936 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
15937 } else {
15938 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
15939 }
15940 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
15941 index++;
15942 }
15943
15944 pclose(f);
15945 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15946 return RETURN_OK;
15947}